You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2011/05/16 23:30:33 UTC
svn commit: r1103907 [6/8] - in /felix/trunk/framework/src/main/java/org:
apache/felix/framework/ osgi/framework/ osgi/framework/startlevel/
osgi/framework/wiring/
Modified: felix/trunk/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/FrameworkUtil.java?rev=1103907&r1=1103906&r2=1103907&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/FrameworkUtil.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/FrameworkUtil.java Mon May 16 21:30:32 2011
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,15 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import javax.security.auth.x500.X500Principal;
@@ -39,7 +42,7 @@ import javax.security.auth.x500.X500Prin
*
* @since 1.3
* @ThreadSafe
- * @version $Revision: 7761 $
+ * @version $Id: a902bc156ea997ed244831c7fab0f290a08ac0c1 $
*/
public class FrameworkUtil {
/**
@@ -50,9 +53,9 @@ public class FrameworkUtil {
}
/**
- * Creates a <code>Filter</code> object. This <code>Filter</code> object may
- * be used to match a <code>ServiceReference</code> object or a
- * <code>Dictionary</code> object.
+ * Creates a {@code Filter} object. This {@code Filter} object may
+ * be used to match a {@code ServiceReference} object or a
+ * {@code Dictionary} object.
*
* <p>
* If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
@@ -64,16 +67,16 @@ public class FrameworkUtil {
* by {@link BundleContext#createFilter(String)}.
*
* @param filter The filter string.
- * @return A <code>Filter</code> object encapsulating the filter string.
- * @throws InvalidSyntaxException If <code>filter</code> contains an invalid
+ * @return A {@code Filter} object encapsulating the filter string.
+ * @throws InvalidSyntaxException If {@code filter} contains an invalid
* filter string that cannot be parsed.
- * @throws NullPointerException If <code>filter</code> is null.
+ * @throws NullPointerException If {@code filter} is null.
*
* @see Filter
*/
public static Filter createFilter(String filter)
throws InvalidSyntaxException {
- return new org.apache.felix.framework.FilterImpl(filter);
+ return FilterImpl.newInstance(filter);
}
/**
@@ -102,8 +105,8 @@ public class FrameworkUtil {
* wildcard can also replace the first list of RDNs of a DN. The first RDNs
* are the least significant. Such lists of matched RDNs can be empty.
* <p>
- * For example, a match pattern with a wildcard that matches all all DNs
- * that end with RDNs of o=ACME and c=US would look like this:
+ * For example, a match pattern with a wildcard that matches all DNs that
+ * end with RDNs of o=ACME and c=US would look like this:
*
* <pre>
* *, o=ACME, c=US
@@ -176,34 +179,36 @@ public class FrameworkUtil {
*
* @param matchPattern The pattern against which to match the DN chain.
* @param dnChain The DN chain to match against the specified pattern. Each
- * element of the chain must be of type <code>String</code> and use
- * the format defined in RFC 2253.
- * @return <code>true</code> If the pattern matches the DN chain; otherwise
- * <code>false</code> is returned.
+ * element of the chain must be of type {@code String} and use the
+ * format defined in <a
+ * href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
+ * @return {@code true} If the pattern matches the DN chain; otherwise
+ * {@code false} is returned.
* @throws IllegalArgumentException If the specified match pattern or DN
* chain is invalid.
* @since 1.5
*/
public static boolean matchDistinguishedNameChain(String matchPattern,
- List /* <String> */dnChain) {
+ List<String> dnChain) {
return DNChainMatching.match(matchPattern, dnChain);
}
/**
- * Return a <code>Bundle</code> for the specified bundle class. The returned
- * <code>Bundle</code> is the bundle associated with the bundle class loader
+ * Return a {@code Bundle} for the specified bundle class. The returned
+ * {@code Bundle} is the bundle associated with the bundle class loader
* which defined the specified class.
*
* @param classFromBundle A class defined by a bundle class loader.
- * @return A <code>Bundle</code> for the specified bundle class or
- * <code>null</code> if the specified class was not defined by a
+ * @return A {@code Bundle} for the specified bundle class or
+ * {@code null} if the specified class was not defined by a
* bundle class loader.
* @since 1.5
*/
- public static Bundle getBundle(final Class classFromBundle) {
+ public static Bundle getBundle(final Class< ? > classFromBundle) {
// We use doPriv since the caller may not have permission
// to call getClassLoader.
- Object cl = AccessController.doPrivileged(new PrivilegedAction() {
+ Object cl = AccessController
+ .doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return classFromBundle.getClassLoader();
}
@@ -216,6 +221,1518 @@ 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.
+ */
+ 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.
+ */
+ 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
+ */
+ 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
+ */
+ 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.
+ */
+ 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 StringBuffer normalize() {
+ StringBuffer sb = new StringBuffer();
+ 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.
+ */
+ 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}.
+ */
+ 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);
+ }
+
+ 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< ? >) {
+ 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 final Class< ? >[] constructorType = new Class[] {String.class};
+
+ private boolean compare_Comparable(int operation,
+ Comparable<Object> value1, Object value2) {
+ if (operation == SUBSTRING) {
+ return false;
+ }
+ Constructor< ? > constructor;
+ try {
+ constructor = value1.getClass().getConstructor(constructorType);
+ }
+ catch (NoSuchMethodException e) {
+ return false;
+ }
+ try {
+ if (!constructor.isAccessible())
+ AccessController.doPrivileged(new SetAccessibleAction(
+ constructor));
+ value2 = constructor
+ .newInstance(new Object[] {((String) value2).trim()});
+ }
+ catch (IllegalAccessException e) {
+ return false;
+ }
+ catch (InvocationTargetException e) {
+ return false;
+ }
+ catch (InstantiationException e) {
+ 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_Unknown(int operation, Object value1,
+ Object value2) {
+ if (operation == SUBSTRING) {
+ return false;
+ }
+ Constructor< ? > constructor;
+ try {
+ constructor = value1.getClass().getConstructor(constructorType);
+ }
+ catch (NoSuchMethodException e) {
+ return false;
+ }
+ try {
+ if (!constructor.isAccessible())
+ AccessController.doPrivileged(new SetAccessibleAction(
+ constructor));
+ value2 = constructor
+ .newInstance(new Object[] {((String) value2).trim()});
+ }
+ catch (IllegalAccessException e) {
+ return false;
+ }
+ catch (InvocationTargetException e) {
+ return false;
+ }
+ catch (InstantiationException e) {
+ 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[operands.size()]));
+ }
+
+ 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[operands.size()]));
+ }
+
+ 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 {
+ StringBuffer sb = new StringBuffer(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 {
+ StringBuffer sb = new StringBuffer(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[size]);
+ }
+
+ 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[keyList.size()]);
+ }
+
+ public Object get(Object o) {
+ String k = (String) o;
+ for (String key : keys) {
+ if (key.equalsIgnoreCase(k)) {
+ return dictionary.get(key);
+ }
+ }
+ return null;
+ }
+
+ 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;
+ }
+
+ public Object get(Object key) {
+ if (reference == null) {
+ return null;
+ }
+ return reference.getProperty((String) key);
+ }
+
+ public Set<java.util.Map.Entry<String, Object>> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static private final class SetAccessibleAction implements
+ PrivilegedAction<Object> {
+ private final AccessibleObject accessible;
+
+ SetAccessibleAction(AccessibleObject accessible) {
+ this.accessible = accessible;
+ }
+
+ public Object run() {
+ accessible.setAccessible(true);
+ return null;
+ }
+ }
+
+ /**
* This class contains a method to match a distinguished name (DN) chain
* against and DN chain pattern.
* <p>
@@ -229,12 +1746,12 @@ public class FrameworkUtil {
* cn=ben+ou=research,o=ACME,c=us;ou=Super CA,c=CA
* </pre>
*
- * is made up of two DNs: "<code>cn=ben+ou=research,o=ACME,c=us</code>
- * " and " <code>ou=Super CA,c=CA</code>
+ * is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us}
+ * " and " {@code ou=Super CA,c=CA}
* ". The first DN is made of of three RDNs: "
- * <code>cn=ben+ou=research</code>" and "<code>o=ACME</code>" and "
- * <code>c=us</code>". The first RDN has two name value pairs: "
- * <code>cn=ben</code>" and "<code>ou=research</code>".
+ * {@code cn=ben+ou=research}" and "{@code o=ACME}" and "
+ * {@code c=us}". The first RDN has two name value pairs: "
+ * {@code cn=ben}" and "{@code ou=research}".
* <p>
* A chain pattern makes use of wildcards ('*' or '-') to match against DNs,
* and wildcards ('*') to match againts DN prefixes, and value. If a DN in a
@@ -246,7 +1763,7 @@ public class FrameworkUtil {
* removed). If a value of a name/value pair is a wildcard ("*"), the value
* will match any value for that name.
*/
- private static class DNChainMatching {
+ static private final class DNChainMatching {
private static final String MINUS_WILDCARD = "-";
private static final String STAR_WILDCARD = "*";
@@ -257,7 +1774,7 @@ public class FrameworkUtil {
* @param rdnPattern List of name value pattern pairs.
* @return true if the list of name value pairs match the pattern.
*/
- private static boolean rdnmatch(List rdn, List rdnPattern) {
+ private static boolean rdnmatch(List< ? > rdn, List< ? > rdnPattern) {
if (rdn.size() != rdnPattern.size()) {
return false;
}
@@ -281,7 +1798,7 @@ public class FrameworkUtil {
return true;
}
- private static boolean dnmatch(List dn, List dnPattern) {
+ private static boolean dnmatch(List< ? > dn, List< ? > dnPattern) {
int dnStart = 0;
int patStart = 0;
int patLen = dnPattern.size();
@@ -308,7 +1825,8 @@ public class FrameworkUtil {
}
}
for (int i = 0; i < patLen; i++) {
- if (!rdnmatch((List) dn.get(i + dnStart), (List) dnPattern
+ if (!rdnmatch((List< ? >) dn.get(i + dnStart),
+ (List< ? >) dnPattern
.get(i + patStart))) {
return false;
}
@@ -329,12 +1847,12 @@ public class FrameworkUtil {
* @return a list of DNs.
* @throws IllegalArgumentException
*/
- private static List parseDNchainPattern(String dnChain) {
+ private static List<Object> parseDNchainPattern(String dnChain) {
if (dnChain == null) {
throw new IllegalArgumentException(
"The DN chain must not be null.");
}
- List parsed = new ArrayList();
+ List<Object> parsed = new ArrayList<Object>();
int startIndex = 0;
startIndex = skipSpaces(dnChain, startIndex);
while (startIndex < dnChain.length()) {
@@ -362,22 +1880,15 @@ public class FrameworkUtil {
startIndex = endIndex + 1;
startIndex = skipSpaces(dnChain, startIndex);
}
- return parseDNchain(parsed);
- }
- private static List parseDNchain(List chain) {
- if (chain == null) {
- throw new IllegalArgumentException("DN chain must not be null.");
- }
- chain = new ArrayList(chain);
// Now we parse is a list of strings, lets make List of rdn out
// of them
- for (int i = 0; i < chain.size(); i++) {
- String dn = (String) chain.get(i);
+ for (int i = 0; i < parsed.size(); i++) {
+ String dn = (String) parsed.get(i);
if (dn.equals(STAR_WILDCARD) || dn.equals(MINUS_WILDCARD)) {
continue;
}
- List rdns = new ArrayList();
+ List<Object> rdns = new ArrayList<Object>();
if (dn.charAt(0) == '*') {
if (dn.charAt(1) != ',') {
throw new IllegalArgumentException(
@@ -392,12 +1903,32 @@ public class FrameworkUtil {
}
// Now dn is a nice CANONICAL DN
parseDN(dn, rdns);
- chain.set(i, rdns);
+ parsed.set(i, rdns);
+ }
+ if (parsed.size() == 0) {
+ throw new IllegalArgumentException("empty DN chain");
+ }
+ return parsed;
+ }
+
+ private static List<Object> parseDNchain(List<String> chain) {
+ if (chain == null) {
+ throw new IllegalArgumentException("DN chain must not be null.");
+ }
+ List<Object> result = new ArrayList<Object>(chain.size());
+ // Now we parse is a list of strings, lets make List of rdn out
+ // of them
+ for (String dn : chain) {
+ dn = new X500Principal(dn).getName(X500Principal.CANONICAL);
+ // Now dn is a nice CANONICAL DN
+ List<Object> rdns = new ArrayList<Object>();
+ parseDN(dn, rdns);
+ result.add(rdns);
}
- if (chain.size() == 0) {
+ if (result.size() == 0) {
throw new IllegalArgumentException("empty DN chain");
}
- return chain;
+ return result;
}
/**
@@ -420,10 +1951,10 @@ public class FrameworkUtil {
* @param rdn the list to fill in with RDNs extracted from the dn
* @throws IllegalArgumentException if a formatting error is found.
*/
- private static void parseDN(String dn, List rdn) {
+ private static void parseDN(String dn, List<Object> rdn) {
int startIndex = 0;
char c = '\0';
- List nameValues = new ArrayList();
+ List<String> nameValues = new ArrayList<String>();
while (startIndex < dn.length()) {
int endIndex;
for (endIndex = startIndex; endIndex < dn.length(); endIndex++) {
@@ -443,7 +1974,7 @@ public class FrameworkUtil {
if (c != '+') {
rdn.add(nameValues);
if (endIndex != dn.length()) {
- nameValues = new ArrayList();
+ nameValues = new ArrayList<String>();
}
else {
nameValues = null;
@@ -461,7 +1992,7 @@ public class FrameworkUtil {
* This method will return an 'index' which points to a non-wildcard DN
* or the end-of-list.
*/
- private static int skipWildCards(List dnChainPattern,
+ private static int skipWildCards(List<Object> dnChainPattern,
int dnChainPatternIndex) {
int i;
for (i = dnChainPatternIndex; i < dnChainPattern.size(); i++) {
@@ -475,7 +2006,7 @@ public class FrameworkUtil {
// otherwise continue skipping over wild cards
}
else {
- if (dnPattern instanceof List) {
+ if (dnPattern instanceof List< ? >) {
// if its a list then we have our 'non-wildcard' DN
break;
}
@@ -496,8 +2027,9 @@ public class FrameworkUtil {
* where DNChain is of the format: "DN;DN;DN;" and DNChainPattern is of
* the format: "DNPattern;*;DNPattern" (or combinations of this)
*/
- private static boolean dnChainMatch(List dnChain, int dnChainIndex,
- List dnChainPattern, int dnChainPatternIndex)
+ private static boolean dnChainMatch(List<Object> dnChain,
+ int dnChainIndex, List<Object> dnChainPattern,
+ int dnChainPatternIndex)
throws IllegalArgumentException {
if (dnChainIndex >= dnChain.size()) {
return false;
@@ -551,12 +2083,12 @@ public class FrameworkUtil {
// failure
}
else {
- if (dnPattern instanceof List) {
+ if (dnPattern instanceof List< ? >) {
// here we have to do a deeper check for each DN in the
// pattern until we hit a wild card
do {
- if (!dnmatch((List) dnChain.get(dnChainIndex),
- (List) dnPattern)) {
+ if (!dnmatch((List< ? >) dnChain.get(dnChainIndex),
+ (List< ? >) dnPattern)) {
return false;
}
// go to the next set of DN's in both chains
@@ -598,7 +2130,7 @@ public class FrameworkUtil {
dnChainPattern, dnChainPatternIndex);
}
else {
- if (!(dnPattern instanceof List)) {
+ if (!(dnPattern instanceof List< ? >)) {
throw new IllegalArgumentException(
"expected String or List in DN Pattern");
}
@@ -651,9 +2183,9 @@ public class FrameworkUtil {
* @return true if dnChain matches the pattern.
* @throws IllegalArgumentException
*/
- static boolean match(String pattern, List/* <String> */dnChain) {
- List parsedDNChain;
- List parsedDNPattern;
+ static boolean match(String pattern, List<String> dnChain) {
+ List<Object> parsedDNChain;
+ List<Object> parsedDNPattern;
try {
parsedDNChain = parseDNchain(dnChain);
}
@@ -675,12 +2207,12 @@ public class FrameworkUtil {
return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 0);
}
- private static String toString(List dnChain) {
+ private static String toString(List< ? > dnChain) {
if (dnChain == null) {
return null;
}
StringBuffer sb = new StringBuffer();
- for (Iterator iChain = dnChain.iterator(); iChain.hasNext();) {
+ for (Iterator< ? > iChain = dnChain.iterator(); iChain.hasNext();) {
sb.append(iChain.next());
if (iChain.hasNext()) {
sb.append("; ");
Modified: felix/trunk/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java?rev=1103907&r1=1103906&r2=1103907&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java Mon May 16 21:30:32 2011
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,14 +21,14 @@ package org.osgi.framework;
* syntax.
*
* <p>
- * An <code>InvalidSyntaxException</code> object indicates that a filter
+ * An {@code InvalidSyntaxException} object indicates that a filter
* string parameter has an invalid syntax and cannot be parsed. See
* {@link Filter} for a description of the filter string syntax.
*
* <p>
* This exception conforms to the general purpose exception chaining mechanism.
*
- * @version $Revision: 6083 $
+ * @version $Id: adb84e3bc0b82b842e4da84542057fdf53e2ca6a $
*/
public class InvalidSyntaxException extends Exception {
@@ -39,10 +39,10 @@ public class InvalidSyntaxException exte
private final String filter;
/**
- * Creates an exception of type <code>InvalidSyntaxException</code>.
+ * Creates an exception of type {@code InvalidSyntaxException}.
*
* <p>
- * This method creates an <code>InvalidSyntaxException</code> object with
+ * This method creates an {@code InvalidSyntaxException} object with
* the specified message and the filter string which generated the
* exception.
*
@@ -55,10 +55,10 @@ public class InvalidSyntaxException exte
}
/**
- * Creates an exception of type <code>InvalidSyntaxException</code>.
+ * Creates an exception of type {@code InvalidSyntaxException}.
*
* <p>
- * This method creates an <code>InvalidSyntaxException</code> object with
+ * This method creates an {@code InvalidSyntaxException} object with
* the specified message and the filter string which generated the
* exception.
*
@@ -74,7 +74,7 @@ public class InvalidSyntaxException exte
/**
* Returns the filter string that generated the
- * <code>InvalidSyntaxException</code> object.
+ * {@code InvalidSyntaxException} object.
*
* @return The invalid filter string.
* @see BundleContext#getServiceReferences
@@ -85,10 +85,10 @@ public class InvalidSyntaxException exte
}
/**
- * Returns the cause of this exception or <code>null</code> if no cause was
+ * Returns the cause of this exception or {@code null} if no cause was
* set.
*
- * @return The cause of this exception or <code>null</code> if no cause was
+ * @return The cause of this exception or {@code null} if no cause was
* set.
* @since 1.3
*/
Modified: felix/trunk/framework/src/main/java/org/osgi/framework/PackagePermission.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/PackagePermission.java?rev=1103907&r1=1103906&r2=1103907&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/PackagePermission.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/PackagePermission.java Mon May 16 21:30:32 2011
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,11 +29,9 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -51,35 +49,35 @@ import java.util.Map;
* </pre>
*
* <p>
- * <code>PackagePermission</code> has three actions: <code>exportonly</code>,
- * <code>import</code> and <code>export</code>. The <code>export</code> action,
- * which is deprecated, implies the <code>import</code> action.
+ * {@code PackagePermission} has three actions: {@code exportonly},
+ * {@code import} and {@code export}. The {@code export} action,
+ * which is deprecated, implies the {@code import} action.
*
* @ThreadSafe
- * @version $Revision: 7189 $
+ * @version $Id: a286af94405e583f8bedc2ff5d7c818198f8caaf $
*/
public final class PackagePermission extends BasicPermission {
static final long serialVersionUID = -5107705877071099135L;
/**
- * The action string <code>export</code>. The <code>export</code> action
- * implies the <code>import</code> action.
+ * The action string {@code export}. The {@code export} action
+ * implies the {@code import} action.
*
- * @deprecated Since 1.5. Use <code>exportonly</code> instead.
+ * @deprecated Since 1.5. Use {@code exportonly} instead.
*/
public final static String EXPORT = "export";
/**
- * The action string <code>exportonly</code>. The <code>exportonly</code>
- * action does not imply the <code>import</code> action.
+ * The action string {@code exportonly}. The {@code exportonly}
+ * action does not imply the {@code import} action.
*
* @since 1.5
*/
public final static String EXPORTONLY = "exportonly";
/**
- * The action string <code>import</code>.
+ * The action string {@code import}.
*/
public final static String IMPORT = "import";
@@ -113,14 +111,14 @@ public final class PackagePermission ext
transient Filter filter;
/**
- * This dictionary holds the properties of the permission, used to match a
- * filter in implies. This is not initialized until necessary, and then
- * cached in this object.
+ * This map holds the properties of the permission, used to match a filter
+ * in implies. This is not initialized until necessary, and then cached in
+ * this object.
*/
- private transient volatile Dictionary properties;
+ private transient volatile Map<String, Object> properties;
/**
- * Creates a new <code>PackagePermission</code> object.
+ * Creates a new {@code PackagePermission} object.
*
* <p>
* The name is specified as a normal Java package name: a dot-separated
@@ -138,7 +136,7 @@ public final class PackagePermission ext
* *
* </pre>
*
- * For the <code>import</code> action, the name can also be a filter
+ * For the {@code import} action, the name can also be a filter
* expression. The filter gives access to the following attributes:
* <ul>
* <li>signer - A Distinguished Name chain used to sign the exporting
@@ -155,19 +153,19 @@ public final class PackagePermission ext
* Package Permissions are granted over all possible versions of a package.
*
* A bundle that needs to export a package must have the appropriate
- * <code>PackagePermission</code> for that package; similarly, a bundle that
+ * {@code PackagePermission} for that package; similarly, a bundle that
* needs to import a package must have the appropriate
- * <code>PackagePermssion</code> for that package.
+ * {@code PackagePermssion} for that package.
* <p>
* Permission is granted for both classes and resources.
*
* @param name Package name or filter expression. A filter expression can
- * only be specified if the specified action is <code>import</code>.
- * @param actions <code>exportonly</code>,<code>import</code> (canonical
+ * only be specified if the specified action is {@code import}.
+ * @param actions {@code exportonly},{@code import} (canonical
* order).
* @throws IllegalArgumentException If the specified name is a filter
* expression and either the specified action is not
- * <code>import</code> or the filter has an invalid syntax.
+ * {@code import} or the filter has an invalid syntax.
*/
public PackagePermission(String name, String actions) {
this(name, parseActions(actions));
@@ -179,17 +177,17 @@ public final class PackagePermission ext
}
/**
- * Creates a new requested <code>PackagePermission</code> object to be used
- * by code that must perform <code>checkPermission</code> for the
- * <code>import</code> action. <code>PackagePermission</code> objects
+ * Creates a new requested {@code PackagePermission} object to be used
+ * by code that must perform {@code checkPermission} for the
+ * {@code import} action. {@code PackagePermission} objects
* created with this constructor cannot be added to a
- * <code>PackagePermission</code> permission collection.
+ * {@code PackagePermission} permission collection.
*
* @param name The name of the requested package to import.
* @param exportingBundle The bundle exporting the requested package.
- * @param actions The action <code>import</code>.
+ * @param actions The action {@code import}.
* @throws IllegalArgumentException If the specified action is not
- * <code>import</code> or the name is a filter expression.
+ * {@code import} or the name is a filter expression.
* @since 1.5
*/
public PackagePermission(String name, Bundle exportingBundle, String actions) {
@@ -345,7 +343,7 @@ public final class PackagePermission ext
*
* @param filterString The filter string to parse.
* @return a Filter for this bundle. If the specified filterString is not a
- * filter expression, then <code>null</code> is returned.
+ * filter expression, then {@code null} is returned.
* @throws IllegalArgumentException If the filter syntax is invalid.
*/
private static Filter parseFilter(String filterString) {
@@ -370,9 +368,9 @@ public final class PackagePermission ext
*
* <p>
* This method checks that the package name of the target is implied by the
- * package name of this object. The list of <code>PackagePermission</code>
+ * package name of this object. The list of {@code PackagePermission}
* actions must either match or allow for the list of the target object to
- * imply the target <code>PackagePermission</code> action.
+ * imply the target {@code PackagePermission} action.
* <p>
* The permission to export a package implies the permission to import the
* named package.
@@ -385,8 +383,8 @@ public final class PackagePermission ext
* </pre>
*
* @param p The requested permission.
- * @return <code>true</code> if the specified permission is implied by this
- * object; <code>false</code> otherwise.
+ * @return {@code true} if the specified permission is implied by this
+ * object; {@code false} otherwise.
*/
public boolean implies(Permission p) {
if (!(p instanceof PackagePermission)) {
@@ -411,8 +409,8 @@ public final class PackagePermission ext
* validated as a proper argument. The requested PackagePermission
* must not have a filter expression.
* @param effective The effective actions with which to start.
- * @return <code>true</code> if the specified permission is implied by this
- * object; <code>false</code> otherwise.
+ * @return {@code true} if the specified permission is implied by this
+ * object; {@code false} otherwise.
*/
boolean implies0(PackagePermission requested, int effective) {
/* check actions first - much faster */
@@ -426,19 +424,19 @@ public final class PackagePermission ext
if (f == null) {
return super.implies(requested);
}
- return f.matchCase(requested.getProperties());
+ return f.matches(requested.getProperties());
}
/**
* Returns the canonical string representation of the
- * <code>PackagePermission</code> actions.
+ * {@code PackagePermission} actions.
*
* <p>
- * Always returns present <code>PackagePermission</code> actions in the
- * following order: <code>EXPORTONLY</code>,<code>IMPORT</code>.
+ * Always returns present {@code PackagePermission} actions in the
+ * following order: {@code EXPORTONLY},{@code IMPORT}.
*
* @return Canonical string representation of the
- * <code>PackagePermission</code> actions.
+ * {@code PackagePermission} actions.
*/
public String getActions() {
String result = actions;
@@ -464,28 +462,28 @@ public final class PackagePermission ext
}
/**
- * Returns a new <code>PermissionCollection</code> object suitable for
- * storing <code>PackagePermission</code> objects.
+ * Returns a new {@code PermissionCollection} object suitable for
+ * storing {@code PackagePermission} objects.
*
- * @return A new <code>PermissionCollection</code> object.
+ * @return A new {@code PermissionCollection} object.
*/
public PermissionCollection newPermissionCollection() {
return new PackagePermissionCollection();
}
/**
- * Determines the equality of two <code>PackagePermission</code> objects.
+ * Determines the equality of two {@code PackagePermission} objects.
*
* This method checks that specified package has the same package name and
- * <code>PackagePermission</code> actions as this
- * <code>PackagePermission</code> object.
+ * {@code PackagePermission} actions as this
+ * {@code PackagePermission} object.
*
* @param obj The object to test for equality with this
- * <code>PackagePermission</code> object.
- * @return <code>true</code> if <code>obj</code> is a
- * <code>PackagePermission</code>, and has the same package name and
- * actions as this <code>PackagePermission</code> object;
- * <code>false</code> otherwise.
+ * {@code PackagePermission} object.
+ * @return {@code true} if {@code obj} is a
+ * {@code PackagePermission}, and has the same package name and
+ * actions as this {@code PackagePermission} object;
+ * {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
@@ -547,42 +545,42 @@ public final class PackagePermission ext
}
/**
- * Called by <code><@link PackagePermission#implies(Permission)></code>.
+ * Called by {@code <@link PackagePermission#implies(Permission)>}. This
+ * method is only called on a requested permission which cannot have a
+ * filter set.
*
- * @return a dictionary of properties for this permission.
+ * @return a map of properties for this permission.
*/
- private Dictionary getProperties() {
- Dictionary result = properties;
+ private Map<String, Object> getProperties() {
+ Map<String, Object> result = properties;
if (result != null) {
return result;
}
- final Dictionary dict = new Hashtable(5);
- if (filter == null) {
- dict.put("package.name", getName());
- }
+ final Map<String, Object> map = new HashMap<String, Object>(5);
+ map.put("package.name", getName());
if (bundle != null) {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
- dict.put("id", new Long(bundle.getBundleId()));
- dict.put("location", bundle.getLocation());
+ map.put("id", new Long(bundle.getBundleId()));
+ map.put("location", bundle.getLocation());
String name = bundle.getSymbolicName();
if (name != null) {
- dict.put("name", name);
+ map.put("name", name);
}
SignerProperty signer = new SignerProperty(bundle);
if (signer.isBundleSigned()) {
- dict.put("signer", signer);
+ map.put("signer", signer);
}
return null;
}
});
}
- return properties = dict;
+ return properties = map;
}
}
/**
- * Stores a set of <code>PackagePermission</code> permissions.
+ * Stores a set of {@code PackagePermission} permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
@@ -596,7 +594,7 @@ final class PackagePermissionCollection
*
* @GuardedBy this
*/
- private transient Map permissions;
+ private transient Map<String, PackagePermission> permissions;
/**
* Boolean saying if "*" is in the collection.
@@ -612,25 +610,25 @@ final class PackagePermissionCollection
* @serial
* @GuardedBy this
*/
- private Map filterPermissions;
+ private Map<String, PackagePermission> filterPermissions;
/**
* Create an empty PackagePermissions object.
*/
public PackagePermissionCollection() {
- permissions = new HashMap();
+ permissions = new HashMap<String, PackagePermission>();
all_allowed = false;
}
/**
* Adds a permission to this permission collection.
*
- * @param permission The <code>PackagePermission</code> object to add.
+ * @param permission The {@code PackagePermission} object to add.
* @throws IllegalArgumentException If the specified permission is not a
- * <code>PackagePermission</code> instance or was constructed with a
+ * {@code PackagePermission} instance or was constructed with a
* Bundle object.
* @throws SecurityException If this
- * <code>PackagePermissionCollection</code> object has been marked
+ * {@code PackagePermissionCollection} object has been marked
* read-only.
*/
public void add(final Permission permission) {
@@ -653,18 +651,18 @@ final class PackagePermissionCollection
final Filter f = pp.filter;
synchronized (this) {
/* select the bucket for the permission */
- Map pc;
+ Map<String, PackagePermission> pc;
if (f != null) {
pc = filterPermissions;
if (pc == null) {
- filterPermissions = pc = new HashMap();
+ filterPermissions = pc = new HashMap<String, PackagePermission>();
}
}
else {
pc = permissions;
}
- final PackagePermission existing = (PackagePermission) pc.get(name);
+ final PackagePermission existing = pc.get(name);
if (existing != null) {
final int oldMask = existing.action_mask;
final int newMask = pp.action_mask;
@@ -689,12 +687,12 @@ final class PackagePermissionCollection
/**
* Determines if the specified permissions implies the permissions expressed
- * in <code>permission</code>.
+ * in {@code permission}.
*
* @param permission The Permission object to compare with this
- * <code>PackagePermission</code> object.
- * @return <code>true</code> if <code>permission</code> is a proper subset
- * of a permission in the set; <code>false</code> otherwise.
+ * {@code PackagePermission} object.
+ * @return {@code true} if {@code permission} is a proper subset
+ * of a permission in the set; {@code false} otherwise.
*/
public boolean implies(final Permission permission) {
if (!(permission instanceof PackagePermission)) {
@@ -709,13 +707,13 @@ final class PackagePermissionCollection
final int desired = requested.action_mask;
int effective = PackagePermission.ACTION_NONE;
- Collection perms;
+ Collection<PackagePermission> perms;
synchronized (this) {
- Map pc = permissions;
+ Map<String, PackagePermission> pc = permissions;
PackagePermission pp;
/* short circuit if the "*" Permission was added */
if (all_allowed) {
- pp = (PackagePermission) pc.get("*");
+ pp = pc.get("*");
if (pp != null) {
effective |= pp.action_mask;
if ((effective & desired) == desired) {
@@ -727,7 +725,7 @@ final class PackagePermissionCollection
* strategy: Check for full match first. Then work our way up the
* name looking for matches on a.b.*
*/
- pp = (PackagePermission) pc.get(requestedName);
+ pp = pc.get(requestedName);
if (pp != null) {
/* we have a direct hit! */
effective |= pp.action_mask;
@@ -740,7 +738,7 @@ final class PackagePermissionCollection
int offset = requestedName.length() - 1;
while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
requestedName = requestedName.substring(0, last + 1) + "*";
- pp = (PackagePermission) pc.get(requestedName);
+ pp = pc.get(requestedName);
if (pp != null) {
effective |= pp.action_mask;
if ((effective & desired) == desired) {
@@ -760,9 +758,8 @@ final class PackagePermissionCollection
perms = pc.values();
}
/* iterate one by one over filteredPermissions */
- for (Iterator iter = perms.iterator(); iter.hasNext();) {
- if (((PackagePermission) iter.next())
- .implies0(requested, effective)) {
+ for (PackagePermission perm : perms) {
+ if (perm.implies0(requested, effective)) {
return true;
}
}
@@ -770,14 +767,14 @@ final class PackagePermissionCollection
}
/**
- * Returns an enumeration of all <code>PackagePermission</code> objects in
+ * Returns an enumeration of all {@code PackagePermission} objects in
* the container.
*
- * @return Enumeration of all <code>PackagePermission</code> objects.
+ * @return Enumeration of all {@code PackagePermission} objects.
*/
- public synchronized Enumeration elements() {
- List all = new ArrayList(permissions.values());
- Map pc = filterPermissions;
+ public synchronized Enumeration<Permission> elements() {
+ List<Permission> all = new ArrayList<Permission>(permissions.values());
+ Map<String, PackagePermission> pc = filterPermissions;
if (pc != null) {
all.addAll(pc.values());
}
@@ -792,7 +789,8 @@ final class PackagePermissionCollection
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
- Hashtable hashtable = new Hashtable(permissions);
+ Hashtable<String, PackagePermission> hashtable = new Hashtable<String, PackagePermission>(
+ permissions);
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", hashtable);
pfields.put("all_allowed", all_allowed);
@@ -803,9 +801,12 @@ final class PackagePermissionCollection
private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
- Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
- permissions = new HashMap(hashtable);
+ Hashtable<String, PackagePermission> hashtable = (Hashtable<String, PackagePermission>) gfields
+ .get("permissions", null);
+ permissions = new HashMap<String, PackagePermission>(hashtable);
all_allowed = gfields.get("all_allowed", false);
- filterPermissions = (HashMap) gfields.get("filterPermissions", null);
+ HashMap<String, PackagePermission> fp = (HashMap<String, PackagePermission>) gfields
+ .get("filterPermissions", null);
+ filterPermissions = fp;
}
}
Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java?rev=1103907&r1=1103906&r2=1103907&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java Mon May 16 21:30:32 2011
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@ import java.util.EventObject;
/**
* An event from the Framework describing a service lifecycle change.
* <p>
- * <code>ServiceEvent</code> objects are delivered to
- * <code>ServiceListener</code>s and <code>AllServiceListener</code>s when a
+ * {@code ServiceEvent} objects are delivered to
+ * {@code ServiceListener}s and {@code AllServiceListener}s when a
* change occurs in this service's lifecycle. A type code is used to identify
* the event type for future extendability.
*
@@ -33,7 +33,7 @@ import java.util.EventObject;
* @Immutable
* @see ServiceListener
* @see AllServiceListener
- * @version $Revision: 6542 $
+ * @version $Id: 2b9458d90004411b6ca0cb4b361bc282b04c85eb $
*/
public class ServiceEvent extends EventObject {
@@ -41,7 +41,7 @@ public class ServiceEvent extends EventO
/**
* Reference to the service that had a change occur in its lifecycle.
*/
- private final ServiceReference reference;
+ private final ServiceReference< ? > reference;
/**
* Type of service lifecycle change.
@@ -75,7 +75,7 @@ public class ServiceEvent extends EventO
* has completed unregistering.
*
* <p>
- * If a bundle is using a service that is <code>UNREGISTERING</code>, the
+ * If a bundle is using a service that is {@code UNREGISTERING}, the
* bundle should release its use of the service when it receives this event.
* If the bundle does not release its use of the service when it receives
* this event, the Framework will automatically release the bundle's use of
@@ -92,7 +92,7 @@ public class ServiceEvent extends EventO
* <p>
* This event is synchronously delivered <strong>after</strong> the service
* properties have been modified. This event is only delivered to listeners
- * which were added with a non-<code>null</code> filter where the filter
+ * which were added with a non-{@code null} filter where the filter
* matched the service properties prior to the modification but the filter
* does not match the modified service properties.
*
@@ -105,10 +105,10 @@ public class ServiceEvent extends EventO
* Creates a new service event object.
*
* @param type The event type.
- * @param reference A <code>ServiceReference</code> object to the service
+ * @param reference A {@code ServiceReference} object to the service
* that had a lifecycle change.
*/
- public ServiceEvent(int type, ServiceReference reference) {
+ public ServiceEvent(int type, ServiceReference< ? > reference) {
super(reference);
this.reference = reference;
this.type = type;
@@ -122,7 +122,7 @@ public class ServiceEvent extends EventO
*
* @return Reference to the service that had a lifecycle change.
*/
- public ServiceReference getServiceReference() {
+ public ServiceReference< ? > getServiceReference() {
return reference;
}
Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java?rev=1103907&r1=1103906&r2=1103907&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java Mon May 16 21:30:32 2011
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2007, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,18 +20,18 @@ package org.osgi.framework;
* A service exception used to indicate that a service problem occurred.
*
* <p>
- * A <code>ServiceException</code> object is created by the Framework or
+ * A {@code ServiceException} object is created by the Framework or
* service implementation to denote an exception condition in the service. A
* type code is used to identify the exception type for future extendability.
* Service implementations may also create subclasses of
- * <code>ServiceException</code>. When subclassing, the subclass should set
+ * {@code ServiceException}. When subclassing, the subclass should set
* the type to {@link #SUBCLASSED} to indicate that
- * <code>ServiceException</code> has been subclassed.
+ * {@code ServiceException} has been subclassed.
*
* <p>
* This exception conforms to the general purpose exception chaining mechanism.
*
- * @version $Revision: 6518 $
+ * @version $Id: 453b6021eed4543f754e20696b9f8b33a7e121ee $
* @since 1.5
*/
@@ -68,9 +68,16 @@ public class ServiceException extends Ru
* An error occurred invoking a remote service.
*/
public static final int REMOTE = 5;
+ /**
+ * The service factory resulted in a recursive call to itself for the
+ * requesting bundle.
+ *
+ * @since 1.6
+ */
+ public static final int FACTORY_RECURSION = 6;
/**
- * Creates a <code>ServiceException</code> with the specified message and
+ * Creates a {@code ServiceException} with the specified message and
* exception cause.
*
* @param msg The associated message.
@@ -81,7 +88,7 @@ public class ServiceException extends Ru
}
/**
- * Creates a <code>ServiceException</code> with the specified message.
+ * Creates a {@code ServiceException} with the specified message.
*
* @param msg The message.
*/
@@ -90,7 +97,7 @@ public class ServiceException extends Ru
}
/**
- * Creates a <code>ServiceException</code> with the specified message,
+ * Creates a {@code ServiceException} with the specified message,
* type and exception cause.
*
* @param msg The associated message.
@@ -103,7 +110,7 @@ public class ServiceException extends Ru
}
/**
- * Creates a <code>ServiceException</code> with the specified message and
+ * Creates a {@code ServiceException} with the specified message and
* type.
*
* @param msg The message.
@@ -115,7 +122,7 @@ public class ServiceException extends Ru
}
/**
- * Returns the type for this exception or <code>UNSPECIFIED</code> if the
+ * Returns the type for this exception or {@code UNSPECIFIED} if the
* type was unspecified or unknown.
*
* @return The type of this exception.