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 2006/10/19 00:01:24 UTC

svn commit: r465392 [7/10] - in /incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi: framework/ service/condpermadmin/ service/packageadmin/ service/permissionadmin/ service/startlevel/ service/url/

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java Wed Oct 18 15:01:22 2006
@@ -1,508 +1,508 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServicePermission.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2000, 2005). 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework;
-
-import java.io.IOException;
-import java.security.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-/**
- * Indicates a bundle's authority to register or get a service.
- * <ul>
- * <li>The <code>ServicePermission.REGISTER</code> action allows a bundle to
- * register a service on the specified names.
- * <li>The <code>ServicePermission.GET</code> action allows a bundle to
- * detect a service and get it.
- * </ul>
- * Permission to get a service is required in order to detect events regarding
- * the service. Untrusted bundles should not be able to detect the presence of
- * certain services unless they have the appropriate
- * <code>ServicePermission</code> to get the specific service.
- * 
- * @version $Revision: 1.13 $
- */
-
-final public class ServicePermission extends BasicPermission {
-	static final long			serialVersionUID	= -7662148639076511574L;
-	/**
-	 * The action string <code>get</code> (Value is "get").
-	 */
-	public final static String	GET					= "get";
-	/**
-	 * The action string <code>register</code> (Value is "register").
-	 */
-	public final static String	REGISTER			= "register";
-
-	private final static int	ACTION_GET			= 0x00000001;
-	private final static int	ACTION_REGISTER		= 0x00000002;
-	private final static int	ACTION_ALL			= ACTION_GET
-															| ACTION_REGISTER;
-	private final static int	ACTION_NONE			= 0;
-	/**
-	 * The actions mask.
-	 */
-	private transient int		action_mask			= ACTION_NONE;
-
-	/**
-	 * The actions in canonical form.
-	 * 
-	 * @serial
-	 */
-	private String				actions				= null;
-
-	/**
-	 * Create a new ServicePermission.
-	 * 
-	 * <p>
-	 * The name of the service is specified as a fully qualified class name.
-	 * 
-	 * <pre>
-	 * ClassName ::= &lt;class name&gt; | &lt;class name ending in &quot;.*&quot;&gt;
-	 * </pre>
-	 * 
-	 * Examples:
-	 * 
-	 * <pre>
-	 * org.osgi.service.http.HttpService
-	 * org.osgi.service.http.*
-	 * org.osgi.service.snmp.*
-	 * </pre>
-	 * 
-	 * <p>
-	 * There are two possible actions: <code>get</code> and
-	 * <code>register</code>. The <code>get</code> permission allows the
-	 * owner of this permission to obtain a service with this name. The
-	 * <code>register</code> permission allows the bundle to register a
-	 * service under that name.
-	 * 
-	 * @param name class name
-	 * @param actions <code>get</code>,<code>register</code> (canonical
-	 *        order)
-	 */
-
-	public ServicePermission(String name, String actions) {
-		this(name, getMask(actions));
-	}
-
-	/**
-	 * Package private constructor used by ServicePermissionCollection.
-	 * 
-	 * @param name class name
-	 * @param mask action mask
-	 */
-	ServicePermission(String name, int mask) {
-		super(name);
-
-		init(mask);
-	}
-
-	/**
-	 * Called by constructors and when deserialized.
-	 * 
-	 * @param mask action mask
-	 */
-	private void init(int mask) {
-		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
-			throw new IllegalArgumentException("invalid action string");
-		}
-
-		action_mask = mask;
-	}
-
-	/**
-	 * Parse action string into action mask.
-	 * 
-	 * @param actions Action string.
-	 * @return action mask.
-	 */
-	private static int getMask(String actions) {
-		boolean seencomma = false;
-
-		int mask = ACTION_NONE;
-
-		if (actions == null) {
-			return mask;
-		}
-
-		char[] a = actions.toCharArray();
-
-		int i = a.length - 1;
-		if (i < 0)
-			return mask;
-
-		while (i != -1) {
-			char c;
-
-			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
-				i--;
-
-			// check for the known strings
-			int matchlen;
-
-			if (i >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
-					&& (a[i - 1] == 'e' || a[i - 1] == 'E')
-					&& (a[i] == 't' || a[i] == 'T')) {
-				matchlen = 3;
-				mask |= ACTION_GET;
-
-			}
-			else
-				if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
-						&& (a[i - 6] == 'e' || a[i - 6] == 'E')
-						&& (a[i - 5] == 'g' || a[i - 5] == 'G')
-						&& (a[i - 4] == 'i' || a[i - 4] == 'I')
-						&& (a[i - 3] == 's' || a[i - 3] == 'S')
-						&& (a[i - 2] == 't' || a[i - 2] == 'T')
-						&& (a[i - 1] == 'e' || a[i - 1] == 'E')
-						&& (a[i] == 'r' || a[i] == 'R')) {
-					matchlen = 8;
-					mask |= ACTION_REGISTER;
-
-				}
-				else {
-					// parse error
-					throw new IllegalArgumentException("invalid permission: "
-							+ actions);
-				}
-
-			// make sure we didn't just match the tail of a word
-			// like "ackbarfregister". Also, skip to the comma.
-			seencomma = false;
-			while (i >= matchlen && !seencomma) {
-				switch (a[i - matchlen]) {
-					case ',' :
-						seencomma = true;
-					/* FALLTHROUGH */
-					case ' ' :
-					case '\r' :
-					case '\n' :
-					case '\f' :
-					case '\t' :
-						break;
-					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
-				}
-				i--;
-			}
-
-			// point i at the location of the comma minus one (or -1).
-			i -= matchlen;
-		}
-
-		if (seencomma) {
-			throw new IllegalArgumentException("invalid permission: " + actions);
-		}
-
-		return mask;
-	}
-
-	/**
-	 * Determines if a <code>ServicePermission</code> object "implies" the
-	 * specified permission.
-	 * 
-	 * @param p The target permission to check.
-	 * @return <code>true</code> if the specified permission is implied by
-	 *         this object; <code>false</code> otherwise.
-	 */
-
-	public boolean implies(Permission p) {
-		if (p instanceof ServicePermission) {
-			ServicePermission target = (ServicePermission) p;
-
-			return (((action_mask & target.action_mask) == target.action_mask) && super
-					.implies(p));
-		}
-
-		return (false);
-	}
-
-	/**
-	 * Returns the canonical string representation of the actions. Always
-	 * returns present actions in the following order: <code>get</code>,
-	 * <code>register</code>.
-	 * 
-	 * @return The canonical string representation of the actions.
-	 */
-	public String getActions() {
-		if (actions == null) {
-			StringBuffer sb = new StringBuffer();
-			boolean comma = false;
-
-			if ((action_mask & ACTION_GET) == ACTION_GET) {
-				sb.append(GET);
-				comma = true;
-			}
-
-			if ((action_mask & ACTION_REGISTER) == ACTION_REGISTER) {
-				if (comma)
-					sb.append(',');
-				sb.append(REGISTER);
-			}
-
-			actions = sb.toString();
-		}
-
-		return (actions);
-	}
-
-	/**
-	 * Returns a new <code>PermissionCollection</code> object for storing
-	 * <code>ServicePermission<code> objects.
-	 *
-	 * @return A new <code>PermissionCollection</code> object suitable for storing
-	 * <code>ServicePermission</code> objects.
-	 */
-	public PermissionCollection newPermissionCollection() {
-		return (new ServicePermissionCollection());
-	}
-
-	/**
-	 * Determines the equalty of two ServicePermission objects.
-	 * 
-	 * Checks that specified object has the same class name and action as this
-	 * <code>ServicePermission</code>.
-	 * 
-	 * @param obj The object to test for equality.
-	 * @return true if obj is a <code>ServicePermission</code>, and has the
-	 *         same class name and actions as this
-	 *         <code>ServicePermission</code> object; <code>false</code>
-	 *         otherwise.
-	 */
-	public boolean equals(Object obj) {
-		if (obj == this) {
-			return (true);
-		}
-
-		if (!(obj instanceof ServicePermission)) {
-			return (false);
-		}
-
-		ServicePermission p = (ServicePermission) obj;
-
-		return ((action_mask == p.action_mask) && getName().equals(p.getName()));
-	}
-
-	/**
-	 * Returns the hash code value for this object.
-	 * 
-	 * @return Hash code value for this object.
-	 */
-
-	public int hashCode() {
-		return (getName().hashCode() ^ getActions().hashCode());
-	}
-
-	/**
-	 * Returns the current action mask. Used by the ServicePermissionCollection
-	 * object.
-	 * 
-	 * @return The actions mask.
-	 */
-	int getMask() {
-		return (action_mask);
-	}
-
-	/**
-	 * WriteObject is called to save the state of this permission to a stream.
-	 * The actions are serialized, and the superclass takes care of the name.
-	 */
-
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
-		// Write out the actions. The superclass takes care of the name
-		// call getActions to make sure actions field is initialized
-		if (actions == null)
-			getActions();
-		s.defaultWriteObject();
-	}
-
-	/**
-	 * readObject is called to restore the state of this permission from a
-	 * stream.
-	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
-		// Read in the action, then initialize the rest
-		s.defaultReadObject();
-		init(getMask(actions));
-	}
-}
-
-/**
- * Stores a set of ServicePermission permissions.
- * 
- * @see java.security.Permission
- * @see java.security.Permissions
- * @see java.security.PermissionCollection
- */
-
-final class ServicePermissionCollection extends PermissionCollection {
-	static final long	serialVersionUID	= 662615640374640621L;
-	/**
-	 * Table of permissions.
-	 * 
-	 * @serial
-	 */
-	private Hashtable	permissions;
-
-	/**
-	 * Boolean saying if "*" is in the collection.
-	 * 
-	 * @serial
-	 */
-	private boolean		all_allowed;
-
-	/**
-	 * Creates an empty ServicePermissions object.
-	 */
-
-	public ServicePermissionCollection() {
-		permissions = new Hashtable();
-		all_allowed = false;
-	}
-
-	/**
-	 * Adds a permission to the <code>ServicePermission</code> objects using
-	 * the key for the hash as the name.
-	 * 
-	 * @param permission The Permission object to add.
-	 * 
-	 * @throws IllegalArgumentException If the permission is not a
-	 *         ServicePermission object.
-	 * @throws SecurityException If this
-	 *         <code>ServicePermissionCollection</code> object has been marked
-	 *         read-only.
-	 */
-
-	public void add(Permission permission) {
-		if (!(permission instanceof ServicePermission))
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
-		if (isReadOnly())
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
-
-		ServicePermission sp = (ServicePermission) permission;
-		String name = sp.getName();
-
-		ServicePermission existing = (ServicePermission) permissions.get(name);
-
-		if (existing != null) {
-			int oldMask = existing.getMask();
-			int newMask = sp.getMask();
-			if (oldMask != newMask) {
-				permissions.put(name, new ServicePermission(name, oldMask
-						| newMask));
-			}
-		}
-		else {
-			permissions.put(name, permission);
-		}
-
-		if (!all_allowed) {
-			if (name.equals("*"))
-				all_allowed = true;
-		}
-	}
-
-	/**
-	 * Determines if a set of permissions implies the permissions expressed in
-	 * <code>permission</code>.
-	 * 
-	 * @param permission The Permission object to compare.
-	 * 
-	 * @return <code>true</code> if <code>permission</code> is a proper
-	 *         subset of a permission in the set; <code>false</code>
-	 *         otherwise.
-	 */
-
-	public boolean implies(Permission permission) {
-		if (!(permission instanceof ServicePermission))
-			return (false);
-
-		ServicePermission sp = (ServicePermission) permission;
-		ServicePermission x;
-
-		int desired = sp.getMask();
-		int effective = 0;
-
-		// short circuit if the "*" Permission was added
-		if (all_allowed) {
-			x = (ServicePermission) permissions.get("*");
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
-					return (true);
-			}
-		}
-
-		// strategy:
-		// Check for full match first. Then work our way up the
-		// name looking for matches on a.b.*
-
-		String name = sp.getName();
-
-		x = (ServicePermission) permissions.get(name);
-
-		if (x != null) {
-			// we have a direct hit!
-			effective |= x.getMask();
-			if ((effective & desired) == desired)
-				return (true);
-		}
-
-		// work our way up the tree...
-		int last, offset;
-
-		offset = name.length() - 1;
-
-		while ((last = name.lastIndexOf(".", offset)) != -1) {
-
-			name = name.substring(0, last + 1) + "*";
-			x = (ServicePermission) permissions.get(name);
-
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
-					return (true);
-			}
-			offset = last - 1;
-		}
-
-		// we don't have to check for "*" as it was already checked
-		// at the top (all_allowed), so we just return false
-		return (false);
-	}
-
-	/**
-	 * Returns an enumeration of all the <code>ServicePermission</code>
-	 * objects in the container.
-	 * 
-	 * @return Enumeration of all the ServicePermission objects.
-	 */
-
-	public Enumeration elements() {
-		return (permissions.elements());
-	}
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServicePermission.java,v 1.14 2006/06/16 16:31:18 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2006). 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.security.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * Indicates a bundle's authority to register or get a service.
+ * <ul>
+ * <li>The <code>ServicePermission.REGISTER</code> action allows a bundle to
+ * register a service on the specified names.
+ * <li>The <code>ServicePermission.GET</code> action allows a bundle to
+ * detect a service and get it.
+ * </ul>
+ * Permission to get a service is required in order to detect events regarding
+ * the service. Untrusted bundles should not be able to detect the presence of
+ * certain services unless they have the appropriate
+ * <code>ServicePermission</code> to get the specific service.
+ * 
+ * @version $Revision: 1.14 $
+ */
+
+final public class ServicePermission extends BasicPermission {
+	static final long			serialVersionUID	= -7662148639076511574L;
+	/**
+	 * The action string <code>get</code> (Value is "get").
+	 */
+	public final static String	GET					= "get";
+	/**
+	 * The action string <code>register</code> (Value is "register").
+	 */
+	public final static String	REGISTER			= "register";
+
+	private final static int	ACTION_GET			= 0x00000001;
+	private final static int	ACTION_REGISTER		= 0x00000002;
+	private final static int	ACTION_ALL			= ACTION_GET
+															| ACTION_REGISTER;
+	private final static int	ACTION_NONE			= 0;
+	/**
+	 * The actions mask.
+	 */
+	private transient int		action_mask			= ACTION_NONE;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private String				actions				= null;
+
+	/**
+	 * Create a new ServicePermission.
+	 * 
+	 * <p>
+	 * The name of the service is specified as a fully qualified class name.
+	 * 
+	 * <pre>
+	 * ClassName ::= &lt;class name&gt; | &lt;class name ending in &quot;.*&quot;&gt;
+	 * </pre>
+	 * 
+	 * Examples:
+	 * 
+	 * <pre>
+	 * org.osgi.service.http.HttpService
+	 * org.osgi.service.http.*
+	 * org.osgi.service.snmp.*
+	 * </pre>
+	 * 
+	 * <p>
+	 * There are two possible actions: <code>get</code> and
+	 * <code>register</code>. The <code>get</code> permission allows the
+	 * owner of this permission to obtain a service with this name. The
+	 * <code>register</code> permission allows the bundle to register a
+	 * service under that name.
+	 * 
+	 * @param name class name
+	 * @param actions <code>get</code>,<code>register</code> (canonical
+	 *        order)
+	 */
+
+	public ServicePermission(String name, String actions) {
+		this(name, getMask(actions));
+	}
+
+	/**
+	 * Package private constructor used by ServicePermissionCollection.
+	 * 
+	 * @param name class name
+	 * @param mask action mask
+	 */
+	ServicePermission(String name, int mask) {
+		super(name);
+
+		init(mask);
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask action mask
+	 */
+	private void init(int mask) {
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+
+		action_mask = mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int getMask(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1)
+					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+							|| c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
+					&& (a[i - 1] == 'e' || a[i - 1] == 'E')
+					&& (a[i] == 't' || a[i] == 'T')) {
+				matchlen = 3;
+				mask |= ACTION_GET;
+
+			}
+			else
+				if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
+						&& (a[i - 6] == 'e' || a[i - 6] == 'E')
+						&& (a[i - 5] == 'g' || a[i - 5] == 'G')
+						&& (a[i - 4] == 'i' || a[i - 4] == 'I')
+						&& (a[i - 3] == 's' || a[i - 3] == 'S')
+						&& (a[i - 2] == 't' || a[i - 2] == 'T')
+						&& (a[i - 1] == 'e' || a[i - 1] == 'E')
+						&& (a[i] == 'r' || a[i] == 'R')) {
+					matchlen = 8;
+					mask |= ACTION_REGISTER;
+
+				}
+				else {
+					// parse error
+					throw new IllegalArgumentException("invalid permission: "
+							+ actions);
+				}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfregister". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+					/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException(
+								"invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Determines if a <code>ServicePermission</code> object "implies" the
+	 * specified permission.
+	 * 
+	 * @param p The target permission to check.
+	 * @return <code>true</code> if the specified permission is implied by
+	 *         this object; <code>false</code> otherwise.
+	 */
+
+	public boolean implies(Permission p) {
+		if (p instanceof ServicePermission) {
+			ServicePermission target = (ServicePermission) p;
+
+			return (((action_mask & target.action_mask) == target.action_mask) && super
+					.implies(p));
+		}
+
+		return (false);
+	}
+
+	/**
+	 * Returns the canonical string representation of the actions. Always
+	 * returns present actions in the following order: <code>get</code>,
+	 * <code>register</code>.
+	 * 
+	 * @return The canonical string representation of the actions.
+	 */
+	public String getActions() {
+		if (actions == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+
+			if ((action_mask & ACTION_GET) == ACTION_GET) {
+				sb.append(GET);
+				comma = true;
+			}
+
+			if ((action_mask & ACTION_REGISTER) == ACTION_REGISTER) {
+				if (comma)
+					sb.append(',');
+				sb.append(REGISTER);
+			}
+
+			actions = sb.toString();
+		}
+
+		return (actions);
+	}
+
+	/**
+	 * Returns a new <code>PermissionCollection</code> object for storing
+	 * <code>ServicePermission<code> objects.
+	 *
+	 * @return A new <code>PermissionCollection</code> object suitable for storing
+	 * <code>ServicePermission</code> objects.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return (new ServicePermissionCollection());
+	}
+
+	/**
+	 * Determines the equalty of two ServicePermission objects.
+	 * 
+	 * Checks that specified object has the same class name and action as this
+	 * <code>ServicePermission</code>.
+	 * 
+	 * @param obj The object to test for equality.
+	 * @return true if obj is a <code>ServicePermission</code>, and has the
+	 *         same class name and actions as this
+	 *         <code>ServicePermission</code> object; <code>false</code>
+	 *         otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return (true);
+		}
+
+		if (!(obj instanceof ServicePermission)) {
+			return (false);
+		}
+
+		ServicePermission p = (ServicePermission) obj;
+
+		return ((action_mask == p.action_mask) && getName().equals(p.getName()));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+
+	public int hashCode() {
+		return (getName().hashCode() ^ getActions().hashCode());
+	}
+
+	/**
+	 * Returns the current action mask. Used by the ServicePermissionCollection
+	 * object.
+	 * 
+	 * @return The actions mask.
+	 */
+	int getMask() {
+		return (action_mask);
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission to a stream.
+	 * The actions are serialized, and the superclass takes care of the name.
+	 */
+
+	private synchronized void writeObject(java.io.ObjectOutputStream s)
+			throws IOException {
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s)
+			throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		init(getMask(actions));
+	}
+}
+
+/**
+ * Stores a set of ServicePermission permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class ServicePermissionCollection extends PermissionCollection {
+	static final long	serialVersionUID	= 662615640374640621L;
+	/**
+	 * Table of permissions.
+	 * 
+	 * @serial
+	 */
+	private Hashtable	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 */
+	private boolean		all_allowed;
+
+	/**
+	 * Creates an empty ServicePermissions object.
+	 */
+
+	public ServicePermissionCollection() {
+		permissions = new Hashtable();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to the <code>ServicePermission</code> objects using
+	 * the key for the hash as the name.
+	 * 
+	 * @param permission The Permission object to add.
+	 * 
+	 * @throws IllegalArgumentException If the permission is not a
+	 *         ServicePermission object.
+	 * @throws SecurityException If this
+	 *         <code>ServicePermissionCollection</code> object has been marked
+	 *         read-only.
+	 */
+
+	public void add(Permission permission) {
+		if (!(permission instanceof ServicePermission))
+			throw new IllegalArgumentException("invalid permission: "
+					+ permission);
+		if (isReadOnly())
+			throw new SecurityException("attempt to add a Permission to a "
+					+ "readonly PermissionCollection");
+
+		ServicePermission sp = (ServicePermission) permission;
+		String name = sp.getName();
+
+		ServicePermission existing = (ServicePermission) permissions.get(name);
+
+		if (existing != null) {
+			int oldMask = existing.getMask();
+			int newMask = sp.getMask();
+			if (oldMask != newMask) {
+				permissions.put(name, new ServicePermission(name, oldMask
+						| newMask));
+			}
+		}
+		else {
+			permissions.put(name, permission);
+		}
+
+		if (!all_allowed) {
+			if (name.equals("*"))
+				all_allowed = true;
+		}
+	}
+
+	/**
+	 * Determines if a set of permissions implies the permissions expressed in
+	 * <code>permission</code>.
+	 * 
+	 * @param permission The Permission object to compare.
+	 * 
+	 * @return <code>true</code> if <code>permission</code> is a proper
+	 *         subset of a permission in the set; <code>false</code>
+	 *         otherwise.
+	 */
+
+	public boolean implies(Permission permission) {
+		if (!(permission instanceof ServicePermission))
+			return (false);
+
+		ServicePermission sp = (ServicePermission) permission;
+		ServicePermission x;
+
+		int desired = sp.getMask();
+		int effective = 0;
+
+		// short circuit if the "*" Permission was added
+		if (all_allowed) {
+			x = (ServicePermission) permissions.get("*");
+			if (x != null) {
+				effective |= x.getMask();
+				if ((effective & desired) == desired)
+					return (true);
+			}
+		}
+
+		// strategy:
+		// Check for full match first. Then work our way up the
+		// name looking for matches on a.b.*
+
+		String name = sp.getName();
+
+		x = (ServicePermission) permissions.get(name);
+
+		if (x != null) {
+			// we have a direct hit!
+			effective |= x.getMask();
+			if ((effective & desired) == desired)
+				return (true);
+		}
+
+		// work our way up the tree...
+		int last, offset;
+
+		offset = name.length() - 1;
+
+		while ((last = name.lastIndexOf(".", offset)) != -1) {
+
+			name = name.substring(0, last + 1) + "*";
+			x = (ServicePermission) permissions.get(name);
+
+			if (x != null) {
+				effective |= x.getMask();
+				if ((effective & desired) == desired)
+					return (true);
+			}
+			offset = last - 1;
+		}
+
+		// we don't have to check for "*" as it was already checked
+		// at the top (all_allowed), so we just return false
+		return (false);
+	}
+
+	/**
+	 * Returns an enumeration of all the <code>ServicePermission</code>
+	 * objects in the container.
+	 * 
+	 * @return Enumeration of all the ServicePermission objects.
+	 */
+
+	public Enumeration elements() {
+		return (permissions.elements());
+	}
+}

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceReference.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceReference.java?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceReference.java (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceReference.java Wed Oct 18 15:01:22 2006
@@ -1,153 +1,153 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceReference.java,v 1.14 2006/03/14 01:21:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2000, 2005). 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework;
-
-/**
- * A reference to a service.
- * 
- * <p>
- * The Framework returns <code>ServiceReference</code> objects from the
- * <code>BundleContext.getServiceReference</code> and
- * <code>BundleContext.getServiceReferences</code> methods.
- * <p>
- * A <code>ServiceReference</code> object may be shared between bundles and
- * can be used to examine the properties of the service and to get the service
- * object.
- * <p>
- * Every service registered in the Framework has a unique
- * <code>ServiceRegistration</code> object and may have multiple, distinct
- * <code>ServiceReference</code> objects referring to it.
- * <code>ServiceReference</code> objects associated with a
- * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
- * and are considered equal (more specifically, their <code>equals()</code>
- * method will return <code>true</code> when compared).
- * <p>
- * If the same service object is registered multiple times,
- * <code>ServiceReference</code> objects associated with different
- * <code>ServiceRegistration</code> objects are not equal.
- * 
- * @version $Revision: 1.14 $
- * @see BundleContext#getServiceReference
- * @see BundleContext#getServiceReferences
- * @see BundleContext#getService
- */
-
-public interface ServiceReference {
-	/**
-	 * Returns the property value to which the specified property key is mapped
-	 * in the properties <code>Dictionary</code> object of the service
-	 * referenced by this <code>ServiceReference</code> object.
-	 * 
-	 * <p>
-	 * Property keys are case-insensitive.
-	 * 
-	 * <p>
-	 * This method must continue to return property values after the service has
-	 * been unregistered. This is so references to unregistered services (for
-	 * example, <code>ServiceReference</code> objects stored in the log) can
-	 * still be interrogated.
-	 * 
-	 * @param key The property key.
-	 * @return The property value to which the key is mapped; <code>null</code>
-	 *         if there is no property named after the key.
-	 */
-	public Object getProperty(String key);
-
-	/**
-	 * Returns an array of the keys in the properties <code>Dictionary</code>
-	 * object of the service referenced by this <code>ServiceReference</code>
-	 * object.
-	 * 
-	 * <p>
-	 * This method will continue to return the keys after the service has been
-	 * unregistered. This is so references to unregistered services (for
-	 * example, <code>ServiceReference</code> objects stored in the log) can
-	 * still be interrogated.
-	 * 
-	 * <p>
-	 * This method is <i>case-preserving </i>; this means that every key in the
-	 * returned array must have the same case as the corresponding key in the
-	 * properties <code>Dictionary</code> that was passed to the
-	 * {@link BundleContext#registerService(String[],Object,java.util.Dictionary)} or
-	 * {@link ServiceRegistration#setProperties} methods.
-	 * 
-	 * @return An array of property keys.
-	 */
-	public String[] getPropertyKeys();
-
-	/**
-	 * Returns the bundle that registered the service referenced by this
-	 * <code>ServiceReference</code> object.
-	 * 
-	 * <p>
-	 * This method must return <code>null</code> when the service has been
-	 * unregistered. This can be used to determine if the service has been
-	 * unregistered.
-	 * 
-	 * @return The bundle that registered the service referenced by this
-	 *         <code>ServiceReference</code> object; <code>null</code> if
-	 *         that service has already been unregistered.
-	 * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
-	 */
-	public Bundle getBundle();
-
-	/**
-	 * Returns the bundles that are using the service referenced by this
-	 * <code>ServiceReference</code> object. Specifically, this method returns
-	 * the bundles whose usage count for that service is greater than zero.
-	 * 
-	 * @return An array of bundles whose usage count for the service referenced
-	 *         by this <code>ServiceReference</code> object is greater than
-	 *         zero; <code>null</code> if no bundles are currently using that
-	 *         service.
-	 * 
-	 * @since 1.1
-	 */
-	public Bundle[] getUsingBundles();
-
-	/**
-	 * Tests if the bundle that registered the service referenced by this
-	 * <code>ServiceReference</code> and the specified bundle use the same
-	 * source for the package of the specified class name.
-	 * <p>
-	 * This method performs the following checks:
-	 * <ol>
-	 * <li>Get the package name from the specified class name.</li>
-	 * <li>For the bundle that registered the service referenced by this
-	 * <code>ServiceReference</code> (registrant bundle); find the source for
-	 * the package. If no source is found then return <code>true</code> if the
-	 * registrant bundle is equal to the specified bundle; otherwise return
-	 * <code>false</code>.</li>
-	 * <li>If the package source of the registrant bundle is equal to the
-	 * package source of the specified bundle then return <code>true</code>;
-	 * otherwise return <code>false</code>.</li>
-	 * </ol>
-	 * 
-	 * @param bundle The <code>Bundle</code> object to check.
-	 * @param className The class name to check.
-	 * @return <code>true</code> if the bundle which registered the service
-	 *         referenced by this <code>ServiceReference</code> and the
-	 *         specified bundle use the same source for the package of the
-	 *         specified class name. Otherwise <code>false</code> is returned.
-	 * 
-	 * @since 1.3
-	 */
-	public boolean isAssignableTo(Bundle bundle, String className);
-
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceReference.java,v 1.15 2006/06/16 16:31:18 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2006). 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A reference to a service.
+ * 
+ * <p>
+ * The Framework returns <code>ServiceReference</code> objects from the
+ * <code>BundleContext.getServiceReference</code> and
+ * <code>BundleContext.getServiceReferences</code> methods.
+ * <p>
+ * A <code>ServiceReference</code> object may be shared between bundles and
+ * can be used to examine the properties of the service and to get the service
+ * object.
+ * <p>
+ * Every service registered in the Framework has a unique
+ * <code>ServiceRegistration</code> object and may have multiple, distinct
+ * <code>ServiceReference</code> objects referring to it.
+ * <code>ServiceReference</code> objects associated with a
+ * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
+ * and are considered equal (more specifically, their <code>equals()</code>
+ * method will return <code>true</code> when compared).
+ * <p>
+ * If the same service object is registered multiple times,
+ * <code>ServiceReference</code> objects associated with different
+ * <code>ServiceRegistration</code> objects are not equal.
+ * 
+ * @version $Revision: 1.15 $
+ * @see BundleContext#getServiceReference
+ * @see BundleContext#getServiceReferences
+ * @see BundleContext#getService
+ */
+
+public interface ServiceReference {
+	/**
+	 * Returns the property value to which the specified property key is mapped
+	 * in the properties <code>Dictionary</code> object of the service
+	 * referenced by this <code>ServiceReference</code> object.
+	 * 
+	 * <p>
+	 * Property keys are case-insensitive.
+	 * 
+	 * <p>
+	 * This method must continue to return property values after the service has
+	 * been unregistered. This is so references to unregistered services (for
+	 * example, <code>ServiceReference</code> objects stored in the log) can
+	 * still be interrogated.
+	 * 
+	 * @param key The property key.
+	 * @return The property value to which the key is mapped; <code>null</code>
+	 *         if there is no property named after the key.
+	 */
+	public Object getProperty(String key);
+
+	/**
+	 * Returns an array of the keys in the properties <code>Dictionary</code>
+	 * object of the service referenced by this <code>ServiceReference</code>
+	 * object.
+	 * 
+	 * <p>
+	 * This method will continue to return the keys after the service has been
+	 * unregistered. This is so references to unregistered services (for
+	 * example, <code>ServiceReference</code> objects stored in the log) can
+	 * still be interrogated.
+	 * 
+	 * <p>
+	 * This method is <i>case-preserving </i>; this means that every key in the
+	 * returned array must have the same case as the corresponding key in the
+	 * properties <code>Dictionary</code> that was passed to the
+	 * {@link BundleContext#registerService(String[],Object,java.util.Dictionary)} or
+	 * {@link ServiceRegistration#setProperties} methods.
+	 * 
+	 * @return An array of property keys.
+	 */
+	public String[] getPropertyKeys();
+
+	/**
+	 * Returns the bundle that registered the service referenced by this
+	 * <code>ServiceReference</code> object.
+	 * 
+	 * <p>
+	 * This method must return <code>null</code> when the service has been
+	 * unregistered. This can be used to determine if the service has been
+	 * unregistered.
+	 * 
+	 * @return The bundle that registered the service referenced by this
+	 *         <code>ServiceReference</code> object; <code>null</code> if
+	 *         that service has already been unregistered.
+	 * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
+	 */
+	public Bundle getBundle();
+
+	/**
+	 * Returns the bundles that are using the service referenced by this
+	 * <code>ServiceReference</code> object. Specifically, this method returns
+	 * the bundles whose usage count for that service is greater than zero.
+	 * 
+	 * @return An array of bundles whose usage count for the service referenced
+	 *         by this <code>ServiceReference</code> object is greater than
+	 *         zero; <code>null</code> if no bundles are currently using that
+	 *         service.
+	 * 
+	 * @since 1.1
+	 */
+	public Bundle[] getUsingBundles();
+
+	/**
+	 * Tests if the bundle that registered the service referenced by this
+	 * <code>ServiceReference</code> and the specified bundle use the same
+	 * source for the package of the specified class name.
+	 * <p>
+	 * This method performs the following checks:
+	 * <ol>
+	 * <li>Get the package name from the specified class name.</li>
+	 * <li>For the bundle that registered the service referenced by this
+	 * <code>ServiceReference</code> (registrant bundle); find the source for
+	 * the package. If no source is found then return <code>true</code> if the
+	 * registrant bundle is equal to the specified bundle; otherwise return
+	 * <code>false</code>.</li>
+	 * <li>If the package source of the registrant bundle is equal to the
+	 * package source of the specified bundle then return <code>true</code>;
+	 * otherwise return <code>false</code>.</li>
+	 * </ol>
+	 * 
+	 * @param bundle The <code>Bundle</code> object to check.
+	 * @param className The class name to check.
+	 * @return <code>true</code> if the bundle which registered the service
+	 *         referenced by this <code>ServiceReference</code> and the
+	 *         specified bundle use the same source for the package of the
+	 *         specified class name. Otherwise <code>false</code> is returned.
+	 * 
+	 * @since 1.3
+	 */
+	public boolean isAssignableTo(Bundle bundle, String className);
+
+}

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceRegistration.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceRegistration.java?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceRegistration.java (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServiceRegistration.java Wed Oct 18 15:01:22 2006
@@ -1,112 +1,112 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceRegistration.java,v 1.11 2006/03/14 01:21:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2000, 2005). 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework;
-
-import java.util.Dictionary;
-
-/**
- * A registered service.
- * 
- * <p>
- * The Framework returns a <code>ServiceRegistration</code> object when a
- * <code>BundleContext.registerService</code> method invocation is successful.
- * The <code>ServiceRegistration</code> object is for the private use of the
- * registering bundle and should not be shared with other bundles.
- * <p>
- * The <code>ServiceRegistration</code> object may be used to update the
- * properties of the service or to unregister the service.
- * 
- * @version $Revision: 1.11 $
- * @see BundleContext#registerService(String[],Object,Dictionary)
- */
-
-public interface ServiceRegistration {
-	/**
-	 * Returns a <code>ServiceReference</code> object for a service being
-	 * registered.
-	 * <p>
-	 * The <code>ServiceReference</code> object may be shared with other
-	 * bundles.
-	 * 
-	 * @throws java.lang.IllegalStateException If this
-	 *         <code>ServiceRegistration</code> object has already been
-	 *         unregistered.
-	 * @return <code>ServiceReference</code> object.
-	 */
-	public ServiceReference getReference();
-
-	/**
-	 * Updates the properties associated with a service.
-	 * 
-	 * <p>
-	 * The {@link Constants#OBJECTCLASS} and {@link Constants#SERVICE_ID} keys
-	 * cannot be modified by this method. These values are set by the Framework
-	 * when the service is registered in the OSGi environment.
-	 * 
-	 * <p>
-	 * The following steps are required to modify service properties:
-	 * <ol>
-	 * <li>The service's properties are replaced with the provided properties.
-	 * <li>A service event of type {@link ServiceEvent#MODIFIED} is
-	 * fired.
-	 * </ol>
-	 * 
-	 * @param properties The properties for this service. See {@link Constants}
-	 *        for a list of standard service property keys. Changes should not
-	 *        be made to this object after calling this method. To update the
-	 *        service's properties this method should be called again.
-	 * 
-	 * @throws IllegalStateException If this <code>ServiceRegistration</code>
-	 *         object has already been unregistered.
-	 * @throws IllegalArgumentException If <code>properties</code> contains
-	 *         case variants of the same key name.
-	 */
-	public void setProperties(Dictionary properties);
-
-	/**
-	 * Unregisters a service. Remove a <code>ServiceRegistration</code> object
-	 * from the Framework service registry. All <code>ServiceReference</code>
-	 * objects associated with this <code>ServiceRegistration</code> object
-	 * can no longer be used to interact with the service.
-	 * 
-	 * <p>
-	 * The following steps are required to unregister a service:
-	 * <ol>
-	 * <li>The service is removed from the Framework service registry so that
-	 * it can no longer be used. <code>ServiceReference</code> objects for the
-	 * service may no longer be used to get a service object for the service.
-	 * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is
-	 * fired so that bundles using this service can release their
-	 * use of it.
-	 * <li>For each bundle whose use count for this service is greater than
-	 * zero: <br>
-	 * The bundle's use count for this service is set to zero. <br>
-	 * If the service was registered with a {@link ServiceFactory} object, the
-	 * <code>ServiceFactory.ungetService</code> method is called to release
-	 * the service object for the bundle.
-	 * </ol>
-	 * 
-	 * @throws java.lang.IllegalStateException If this
-	 *         <code>ServiceRegistration</code> object has already been
-	 *         unregistered.
-	 * @see BundleContext#ungetService
-	 * @see ServiceFactory#ungetService
-	 */
-	public void unregister();
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceRegistration.java,v 1.12 2006/06/16 16:31:18 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2000, 2006). 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.Dictionary;
+
+/**
+ * A registered service.
+ * 
+ * <p>
+ * The Framework returns a <code>ServiceRegistration</code> object when a
+ * <code>BundleContext.registerService</code> method invocation is successful.
+ * The <code>ServiceRegistration</code> object is for the private use of the
+ * registering bundle and should not be shared with other bundles.
+ * <p>
+ * The <code>ServiceRegistration</code> object may be used to update the
+ * properties of the service or to unregister the service.
+ * 
+ * @version $Revision: 1.12 $
+ * @see BundleContext#registerService(String[],Object,Dictionary)
+ */
+
+public interface ServiceRegistration {
+	/**
+	 * Returns a <code>ServiceReference</code> object for a service being
+	 * registered.
+	 * <p>
+	 * The <code>ServiceReference</code> object may be shared with other
+	 * bundles.
+	 * 
+	 * @throws java.lang.IllegalStateException If this
+	 *         <code>ServiceRegistration</code> object has already been
+	 *         unregistered.
+	 * @return <code>ServiceReference</code> object.
+	 */
+	public ServiceReference getReference();
+
+	/**
+	 * Updates the properties associated with a service.
+	 * 
+	 * <p>
+	 * The {@link Constants#OBJECTCLASS} and {@link Constants#SERVICE_ID} keys
+	 * cannot be modified by this method. These values are set by the Framework
+	 * when the service is registered in the OSGi environment.
+	 * 
+	 * <p>
+	 * The following steps are required to modify service properties:
+	 * <ol>
+	 * <li>The service's properties are replaced with the provided properties.
+	 * <li>A service event of type {@link ServiceEvent#MODIFIED} is
+	 * fired.
+	 * </ol>
+	 * 
+	 * @param properties The properties for this service. See {@link Constants}
+	 *        for a list of standard service property keys. Changes should not
+	 *        be made to this object after calling this method. To update the
+	 *        service's properties this method should be called again.
+	 * 
+	 * @throws IllegalStateException If this <code>ServiceRegistration</code>
+	 *         object has already been unregistered.
+	 * @throws IllegalArgumentException If <code>properties</code> contains
+	 *         case variants of the same key name.
+	 */
+	public void setProperties(Dictionary properties);
+
+	/**
+	 * Unregisters a service. Remove a <code>ServiceRegistration</code> object
+	 * from the Framework service registry. All <code>ServiceReference</code>
+	 * objects associated with this <code>ServiceRegistration</code> object
+	 * can no longer be used to interact with the service.
+	 * 
+	 * <p>
+	 * The following steps are required to unregister a service:
+	 * <ol>
+	 * <li>The service is removed from the Framework service registry so that
+	 * it can no longer be used. <code>ServiceReference</code> objects for the
+	 * service may no longer be used to get a service object for the service.
+	 * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is
+	 * fired so that bundles using this service can release their
+	 * use of it.
+	 * <li>For each bundle whose use count for this service is greater than
+	 * zero: <br>
+	 * The bundle's use count for this service is set to zero. <br>
+	 * If the service was registered with a {@link ServiceFactory} object, the
+	 * <code>ServiceFactory.ungetService</code> method is called to release
+	 * the service object for the bundle.
+	 * </ol>
+	 * 
+	 * @throws java.lang.IllegalStateException If this
+	 *         <code>ServiceRegistration</code> object has already been
+	 *         unregistered.
+	 * @see BundleContext#ungetService
+	 * @see ServiceFactory#ungetService
+	 */
+	public void unregister();
+}

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/SynchronousBundleListener.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/SynchronousBundleListener.java?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/SynchronousBundleListener.java (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/SynchronousBundleListener.java Wed Oct 18 15:01:22 2006
@@ -1,52 +1,52 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/SynchronousBundleListener.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2001, 2005). 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework;
-
-/**
- * A synchronous <code>BundleEvent</code> listener. When a <code>BundleEvent</code> is
- * fired, it is synchronously delivered to a <code>BundleListener</code>.
- * 
- * <p>
- * <code>SynchronousBundleListener</code> is a listener interface that may be
- * implemented by a bundle developer.
- * <p>
- * A <code>SynchronousBundleListener</code> object is registered with the
- * Framework using the {@link BundleContext#addBundleListener} method.
- * <code>SynchronousBundleListener</code> objects are called with a
- * <code>BundleEvent</code> object when a bundle has been installed, resolved,
- * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
- * <p>
- * Unlike normal <code>BundleListener</code> objects,
- * <code>SynchronousBundleListener</code>s are synchronously called during
- * bundle lifecycle processing. The bundle lifecycle processing will not proceed
- * until all <code>SynchronousBundleListener</code>s have completed.
- * <code>SynchronousBundleListener</code> objects will be called prior to
- * <code>BundleListener</code> objects.
- * <p>
- * <code>AdminPermission[bundle,LISTENER]</code> is required to add or remove a
- * <code>SynchronousBundleListener</code> object.
- * 
- * @version $Revision: 1.13 $
- * @since 1.1
- * @see BundleEvent
- */
-
-public interface SynchronousBundleListener extends BundleListener {
-	// This is a marker interface
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/SynchronousBundleListener.java,v 1.14 2006/06/16 16:31:18 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2001, 2006). 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A synchronous <code>BundleEvent</code> listener. When a <code>BundleEvent</code> is
+ * fired, it is synchronously delivered to a <code>BundleListener</code>.
+ * 
+ * <p>
+ * <code>SynchronousBundleListener</code> is a listener interface that may be
+ * implemented by a bundle developer.
+ * <p>
+ * A <code>SynchronousBundleListener</code> object is registered with the
+ * Framework using the {@link BundleContext#addBundleListener} method.
+ * <code>SynchronousBundleListener</code> objects are called with a
+ * <code>BundleEvent</code> object when a bundle has been installed, resolved,
+ * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
+ * <p>
+ * Unlike normal <code>BundleListener</code> objects,
+ * <code>SynchronousBundleListener</code>s are synchronously called during
+ * bundle lifecycle processing. The bundle lifecycle processing will not proceed
+ * until all <code>SynchronousBundleListener</code>s have completed.
+ * <code>SynchronousBundleListener</code> objects will be called prior to
+ * <code>BundleListener</code> objects.
+ * <p>
+ * <code>AdminPermission[bundle,LISTENER]</code> is required to add or remove a
+ * <code>SynchronousBundleListener</code> object.
+ * 
+ * @version $Revision: 1.14 $
+ * @since 1.1
+ * @see BundleEvent
+ */
+
+public interface SynchronousBundleListener extends BundleListener {
+	// This is a marker interface
+}

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/Version.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/Version.java?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/Version.java (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/Version.java Wed Oct 18 15:01:22 2006
@@ -1,353 +1,353 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Version.java,v 1.15 2006/03/14 01:21:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2005). 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework;
-
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-
-/**
- * Version identifier for bundles and packages.
- * 
- * <p>
- * Version identifiers have four components.
- * <ol>
- * <li>Major version. A non-negative integer.</li>
- * <li>Minor version. A non-negative integer.</li>
- * <li>Micro version. A non-negative integer.</li>
- * <li>Qualifier. A text string. See <code>Version(String)</code> for the
- * format of the qualifier string.</li>
- * </ol>
- * 
- * <p>
- * <code>Version</code> objects are immutable.
- * 
- * @version $Revision: 1.15 $
- * @since 1.3
- */
-
-public class Version implements Comparable {
-	private final int			major;
-	private final int			minor;
-	private final int			micro;
-	private final String		qualifier;
-	private static final String	SEPARATOR		= ".";					//$NON-NLS-1$
-
-	/**
-	 * The empty version "0.0.0". Equivalent to calling
-	 * <code>new Version(0,0,0)</code>.
-	 */
-	public static final Version	emptyVersion	= new Version(0, 0, 0);
-
-	/**
-	 * Creates a version identifier from the specified numerical components.
-	 * 
-	 * <p>
-	 * The qualifier is set to the empty string.
-	 * 
-	 * @param major Major component of the version identifier.
-	 * @param minor Minor component of the version identifier.
-	 * @param micro Micro component of the version identifier.
-	 * @throws IllegalArgumentException If the numerical components are
-	 *         negative.
-	 */
-	public Version(int major, int minor, int micro) {
-		this(major, minor, micro, null);
-	}
-
-	/**
-	 * Creates a version identifier from the specifed components.
-	 * 
-	 * @param major Major component of the version identifier.
-	 * @param minor Minor component of the version identifier.
-	 * @param micro Micro component of the version identifier.
-	 * @param qualifier Qualifier component of the version identifier. If
-	 *        <code>null</code> is specified, then the qualifier will be set
-	 *        to the empty string.
-	 * @throws IllegalArgumentException If the numerical components are negative
-	 *         or the qualifier string is invalid.
-	 */
-	public Version(int major, int minor, int micro, String qualifier) {
-		if (qualifier == null) {
-			qualifier = ""; //$NON-NLS-1$
-		}
-
-		this.major = major;
-		this.minor = minor;
-		this.micro = micro;
-		this.qualifier = qualifier;
-		validate();
-	}
-
-	/**
-	 * Created a version identifier from the specified string.
-	 * 
-	 * <p>
-	 * Here is the grammar for version strings.
-	 * 
-	 * <pre>
-	 * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
-	 * major ::= digit+
-	 * minor ::= digit+
-	 * micro ::= digit+
-	 * qualifier ::= (alpha|digit|'_'|'-')+
-	 * digit ::= [0..9]
-	 * alpha ::= [a..zA..Z]
-	 * </pre>
-	 * 
-	 * There must be no whitespace in version.
-	 * 
-	 * @param version String representation of the version identifier.
-	 * @throws IllegalArgumentException If <code>version</code> is improperly
-	 *         formatted.
-	 */
-	public Version(String version) {
-		int major = 0;
-		int minor = 0;
-		int micro = 0;
-		String qualifier = ""; //$NON-NLS-1$
-
-		try {
-			StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
-			major = Integer.parseInt(st.nextToken());
-
-			if (st.hasMoreTokens()) {
-				st.nextToken(); // consume delimiter
-				minor = Integer.parseInt(st.nextToken());
-
-				if (st.hasMoreTokens()) {
-					st.nextToken(); // consume delimiter
-					micro = Integer.parseInt(st.nextToken());
-
-					if (st.hasMoreTokens()) {
-						st.nextToken(); // consume delimiter
-						qualifier = st.nextToken();
-
-						if (st.hasMoreTokens()) {
-							throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
-						}
-					}
-				}
-			}
-		}
-		catch (NoSuchElementException e) {
-			throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
-		}
-
-		this.major = major;
-		this.minor = minor;
-		this.micro = micro;
-		this.qualifier = qualifier;
-		validate();
-	}
-
-	/**
-	 * Called by the Version constructors to validate the version components.
-	 * 
-	 * @throws IllegalArgumentException If the numerical components are negative
-	 *         or the qualifier string is invalid.
-	 */
-	private void validate() {
-		if (major < 0) {
-			throw new IllegalArgumentException("negative major"); //$NON-NLS-1$
-		}
-		if (minor < 0) {
-			throw new IllegalArgumentException("negative minor"); //$NON-NLS-1$
-		}
-		if (micro < 0) {
-			throw new IllegalArgumentException("negative micro"); //$NON-NLS-1$
-		}
-		int length = qualifier.length();
-		for (int i = 0; i < length; i++) {
-			if ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".indexOf(qualifier.charAt(i)) == -1) { //$NON-NLS-1$
-				throw new IllegalArgumentException("invalid qualifier"); //$NON-NLS-1$
-			}
-		}
-	}
-
-	/**
-	 * Parses a version identifier from the specified string.
-	 * 
-	 * <p>
-	 * See <code>Version(String)</code> for the format of the version string.
-	 * 
-	 * @param version String representation of the version identifier. Leading
-	 *        and trailing whitespace will be ignored.
-	 * @return A <code>Version</code> object representing the version
-	 *         identifier. If <code>version</code> is <code>null</code> or
-	 *         the empty string then <code>emptyVersion</code> will be
-	 *         returned.
-	 * @throws IllegalArgumentException If <code>version</code> is improperly
-	 *         formatted.
-	 */
-	public static Version parseVersion(String version) {
-		if (version == null) {
-			return emptyVersion;
-		}
-
-		version = version.trim();
-		if (version.length() == 0) {
-			return emptyVersion;
-		}
-
-		return new Version(version);
-	}
-
-	/**
-	 * Returns the major component of this version identifier.
-	 * 
-	 * @return The major component.
-	 */
-	public int getMajor() {
-		return major;
-	}
-
-	/**
-	 * Returns the minor component of this version identifier.
-	 * 
-	 * @return The minor component.
-	 */
-	public int getMinor() {
-		return minor;
-	}
-
-	/**
-	 * Returns the micro component of this version identifier.
-	 * 
-	 * @return The micro component.
-	 */
-	public int getMicro() {
-		return micro;
-	}
-
-	/**
-	 * Returns the qualifier component of this version identifier.
-	 * 
-	 * @return The qualifier component.
-	 */
-	public String getQualifier() {
-		return qualifier;
-	}
-
-	/**
-	 * Returns the string representation of this version identifier.
-	 * 
-	 * <p>
-	 * The format of the version string will be <code>major.minor.micro</code>
-	 * if qualifier is the empty string or
-	 * <code>major.minor.micro.qualifier</code> otherwise.
-	 * 
-	 * @return The string representation of this version identifier.
-	 */
-	public String toString() {
-		String base = major + SEPARATOR + minor + SEPARATOR + micro;
-		if (qualifier.length() == 0) { //$NON-NLS-1$
-			return base;
-		}
-		else {
-			return base + SEPARATOR + qualifier;
-		}
-	}
-
-	/**
-	 * Returns a hash code value for the object.
-	 * 
-	 * @return An integer which is a hash code value for this object.
-	 */
-	public int hashCode() {
-		return (major << 24) + (minor << 16) + (micro << 8)
-				+ qualifier.hashCode();
-	}
-
-	/**
-	 * Compares this <code>Version</code> object to another object.
-	 * 
-	 * <p>
-	 * A version is considered to be <b>equal to </b> another version if the
-	 * major, minor and micro components are equal and the qualifier component
-	 * is equal (using <code>String.equals</code>).
-	 * 
-	 * @param object The <code>Version</code> object to be compared.
-	 * @return <code>true</code> if <code>object</code> is a
-	 *         <code>Version</code> and is equal to this object;
-	 *         <code>false</code> otherwise.
-	 */
-	public boolean equals(Object object) {
-		if (object == this) { // quicktest
-			return true;
-		}
-
-		if (!(object instanceof Version)) {
-			return false;
-		}
-
-		Version other = (Version) object;
-		return (major == other.major) && (minor == other.minor)
-				&& (micro == other.micro) && qualifier.equals(other.qualifier);
-	}
-
-	/**
-	 * Compares this <code>Version</code> object to another object.
-	 * 
-	 * <p>
-	 * A version is considered to be <b>less than </b> another version if its
-	 * major component is less than the other version's major component, or the
-	 * major components are equal and its minor component is less than the other
-	 * version's minor component, or the major and minor components are equal
-	 * and its micro component is less than the other version's micro component,
-	 * or the major, minor and micro components are equal and it's qualifier
-	 * component is less than the other version's qualifier component (using
-	 * <code>String.compareTo</code>).
-	 * 
-	 * <p>
-	 * A version is considered to be <b>equal to</b> another version if the
-	 * major, minor and micro components are equal and the qualifier component
-	 * is equal (using <code>String.compareTo</code>).
-	 * 
-	 * @param object The <code>Version</code> object to be compared.
-	 * @return A negative integer, zero, or a positive integer if this object is
-	 *         less than, equal to, or greater than the specified
-	 *         <code>Version</code> object.
-	 * @throws ClassCastException If the specified object is not a
-	 *         <code>Version</code>.
-	 */
-	public int compareTo(Object object) {
-		if (object == this) { // quicktest
-			return 0;
-		}
-
-		Version other = (Version) object;
-
-		int result = major - other.major;
-		if (result != 0) {
-			return result;
-		}
-
-		result = minor - other.minor;
-		if (result != 0) {
-			return result;
-		}
-
-		result = micro - other.micro;
-		if (result != 0) {
-			return result;
-		}
-
-		return qualifier.compareTo(other.qualifier);
-	}
-}
\ No newline at end of file
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Version.java,v 1.16 2006/06/16 16:31:18 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2006). 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * Version identifier for bundles and packages.
+ * 
+ * <p>
+ * Version identifiers have four components.
+ * <ol>
+ * <li>Major version. A non-negative integer.</li>
+ * <li>Minor version. A non-negative integer.</li>
+ * <li>Micro version. A non-negative integer.</li>
+ * <li>Qualifier. A text string. See <code>Version(String)</code> for the
+ * format of the qualifier string.</li>
+ * </ol>
+ * 
+ * <p>
+ * <code>Version</code> objects are immutable.
+ * 
+ * @version $Revision: 1.16 $
+ * @since 1.3
+ */
+
+public class Version implements Comparable {
+	private final int			major;
+	private final int			minor;
+	private final int			micro;
+	private final String		qualifier;
+	private static final String	SEPARATOR		= ".";					//$NON-NLS-1$
+
+	/**
+	 * The empty version "0.0.0". Equivalent to calling
+	 * <code>new Version(0,0,0)</code>.
+	 */
+	public static final Version	emptyVersion	= new Version(0, 0, 0);
+
+	/**
+	 * Creates a version identifier from the specified numerical components.
+	 * 
+	 * <p>
+	 * The qualifier is set to the empty string.
+	 * 
+	 * @param major Major component of the version identifier.
+	 * @param minor Minor component of the version identifier.
+	 * @param micro Micro component of the version identifier.
+	 * @throws IllegalArgumentException If the numerical components are
+	 *         negative.
+	 */
+	public Version(int major, int minor, int micro) {
+		this(major, minor, micro, null);
+	}
+
+	/**
+	 * Creates a version identifier from the specifed components.
+	 * 
+	 * @param major Major component of the version identifier.
+	 * @param minor Minor component of the version identifier.
+	 * @param micro Micro component of the version identifier.
+	 * @param qualifier Qualifier component of the version identifier. If
+	 *        <code>null</code> is specified, then the qualifier will be set
+	 *        to the empty string.
+	 * @throws IllegalArgumentException If the numerical components are negative
+	 *         or the qualifier string is invalid.
+	 */
+	public Version(int major, int minor, int micro, String qualifier) {
+		if (qualifier == null) {
+			qualifier = ""; //$NON-NLS-1$
+		}
+
+		this.major = major;
+		this.minor = minor;
+		this.micro = micro;
+		this.qualifier = qualifier;
+		validate();
+	}
+
+	/**
+	 * Created a version identifier from the specified string.
+	 * 
+	 * <p>
+	 * Here is the grammar for version strings.
+	 * 
+	 * <pre>
+	 * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
+	 * major ::= digit+
+	 * minor ::= digit+
+	 * micro ::= digit+
+	 * qualifier ::= (alpha|digit|'_'|'-')+
+	 * digit ::= [0..9]
+	 * alpha ::= [a..zA..Z]
+	 * </pre>
+	 * 
+	 * There must be no whitespace in version.
+	 * 
+	 * @param version String representation of the version identifier.
+	 * @throws IllegalArgumentException If <code>version</code> is improperly
+	 *         formatted.
+	 */
+	public Version(String version) {
+		int major = 0;
+		int minor = 0;
+		int micro = 0;
+		String qualifier = ""; //$NON-NLS-1$
+
+		try {
+			StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
+			major = Integer.parseInt(st.nextToken());
+
+			if (st.hasMoreTokens()) {
+				st.nextToken(); // consume delimiter
+				minor = Integer.parseInt(st.nextToken());
+
+				if (st.hasMoreTokens()) {
+					st.nextToken(); // consume delimiter
+					micro = Integer.parseInt(st.nextToken());
+
+					if (st.hasMoreTokens()) {
+						st.nextToken(); // consume delimiter
+						qualifier = st.nextToken();
+
+						if (st.hasMoreTokens()) {
+							throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+		}
+		catch (NoSuchElementException e) {
+			throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
+		}
+
+		this.major = major;
+		this.minor = minor;
+		this.micro = micro;
+		this.qualifier = qualifier;
+		validate();
+	}
+
+	/**
+	 * Called by the Version constructors to validate the version components.
+	 * 
+	 * @throws IllegalArgumentException If the numerical components are negative
+	 *         or the qualifier string is invalid.
+	 */
+	private void validate() {
+		if (major < 0) {
+			throw new IllegalArgumentException("negative major"); //$NON-NLS-1$
+		}
+		if (minor < 0) {
+			throw new IllegalArgumentException("negative minor"); //$NON-NLS-1$
+		}
+		if (micro < 0) {
+			throw new IllegalArgumentException("negative micro"); //$NON-NLS-1$
+		}
+		int length = qualifier.length();
+		for (int i = 0; i < length; i++) {
+			if ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".indexOf(qualifier.charAt(i)) == -1) { //$NON-NLS-1$
+				throw new IllegalArgumentException("invalid qualifier"); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Parses a version identifier from the specified string.
+	 * 
+	 * <p>
+	 * See <code>Version(String)</code> for the format of the version string.
+	 * 
+	 * @param version String representation of the version identifier. Leading
+	 *        and trailing whitespace will be ignored.
+	 * @return A <code>Version</code> object representing the version
+	 *         identifier. If <code>version</code> is <code>null</code> or
+	 *         the empty string then <code>emptyVersion</code> will be
+	 *         returned.
+	 * @throws IllegalArgumentException If <code>version</code> is improperly
+	 *         formatted.
+	 */
+	public static Version parseVersion(String version) {
+		if (version == null) {
+			return emptyVersion;
+		}
+
+		version = version.trim();
+		if (version.length() == 0) {
+			return emptyVersion;
+		}
+
+		return new Version(version);
+	}
+
+	/**
+	 * Returns the major component of this version identifier.
+	 * 
+	 * @return The major component.
+	 */
+	public int getMajor() {
+		return major;
+	}
+
+	/**
+	 * Returns the minor component of this version identifier.
+	 * 
+	 * @return The minor component.
+	 */
+	public int getMinor() {
+		return minor;
+	}
+
+	/**
+	 * Returns the micro component of this version identifier.
+	 * 
+	 * @return The micro component.
+	 */
+	public int getMicro() {
+		return micro;
+	}
+
+	/**
+	 * Returns the qualifier component of this version identifier.
+	 * 
+	 * @return The qualifier component.
+	 */
+	public String getQualifier() {
+		return qualifier;
+	}
+
+	/**
+	 * Returns the string representation of this version identifier.
+	 * 
+	 * <p>
+	 * The format of the version string will be <code>major.minor.micro</code>
+	 * if qualifier is the empty string or
+	 * <code>major.minor.micro.qualifier</code> otherwise.
+	 * 
+	 * @return The string representation of this version identifier.
+	 */
+	public String toString() {
+		String base = major + SEPARATOR + minor + SEPARATOR + micro;
+		if (qualifier.length() == 0) { //$NON-NLS-1$
+			return base;
+		}
+		else {
+			return base + SEPARATOR + qualifier;
+		}
+	}
+
+	/**
+	 * Returns a hash code value for the object.
+	 * 
+	 * @return An integer which is a hash code value for this object.
+	 */
+	public int hashCode() {
+		return (major << 24) + (minor << 16) + (micro << 8)
+				+ qualifier.hashCode();
+	}
+
+	/**
+	 * Compares this <code>Version</code> object to another object.
+	 * 
+	 * <p>
+	 * A version is considered to be <b>equal to </b> another version if the
+	 * major, minor and micro components are equal and the qualifier component
+	 * is equal (using <code>String.equals</code>).
+	 * 
+	 * @param object The <code>Version</code> object to be compared.
+	 * @return <code>true</code> if <code>object</code> is a
+	 *         <code>Version</code> and is equal to this object;
+	 *         <code>false</code> otherwise.
+	 */
+	public boolean equals(Object object) {
+		if (object == this) { // quicktest
+			return true;
+		}
+
+		if (!(object instanceof Version)) {
+			return false;
+		}
+
+		Version other = (Version) object;
+		return (major == other.major) && (minor == other.minor)
+				&& (micro == other.micro) && qualifier.equals(other.qualifier);
+	}
+
+	/**
+	 * Compares this <code>Version</code> object to another object.
+	 * 
+	 * <p>
+	 * A version is considered to be <b>less than </b> another version if its
+	 * major component is less than the other version's major component, or the
+	 * major components are equal and its minor component is less than the other
+	 * version's minor component, or the major and minor components are equal
+	 * and its micro component is less than the other version's micro component,
+	 * or the major, minor and micro components are equal and it's qualifier
+	 * component is less than the other version's qualifier component (using
+	 * <code>String.compareTo</code>).
+	 * 
+	 * <p>
+	 * A version is considered to be <b>equal to</b> another version if the
+	 * major, minor and micro components are equal and the qualifier component
+	 * is equal (using <code>String.compareTo</code>).
+	 * 
+	 * @param object The <code>Version</code> object to be compared.
+	 * @return A negative integer, zero, or a positive integer if this object is
+	 *         less than, equal to, or greater than the specified
+	 *         <code>Version</code> object.
+	 * @throws ClassCastException If the specified object is not a
+	 *         <code>Version</code>.
+	 */
+	public int compareTo(Object object) {
+		if (object == this) { // quicktest
+			return 0;
+		}
+
+		Version other = (Version) object;
+
+		int result = major - other.major;
+		if (result != 0) {
+			return result;
+		}
+
+		result = minor - other.minor;
+		if (result != 0) {
+			return result;
+		}
+
+		result = micro - other.micro;
+		if (result != 0) {
+			return result;
+		}
+
+		return qualifier.compareTo(other.qualifier);
+	}
+}

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/package.html
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/package.html?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/package.html (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/package.html Wed Oct 18 15:01:22 2006
@@ -1,6 +1,6 @@
-<!-- $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/package.html,v 1.2 2004/12/01 19:01:49 hargrave Exp $ -->
+<!-- $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/package.html,v 1.3 2006/07/12 21:07:03 hargrave Exp $ -->
 <BODY>
-<p>The OSGi Framework Package. Specification Version 1.3.
+<p>Framework Package Version 1.3.
 <p>Bundles wishing to use this package must list the package
 in the Import-Package header of the bundle's manifest.
 For example:

Added: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/packageinfo
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/packageinfo?view=auto&rev=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/packageinfo (added)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/packageinfo Wed Oct 18 15:01:22 2006
@@ -0,0 +1 @@
+version 1.3

Modified: incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java?view=diff&rev=465392&r1=465391&r2=465392
==============================================================================
--- incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java (original)
+++ incubator/felix/trunk/org.osgi.core/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java Wed Oct 18 15:01:22 2006
@@ -1,118 +1,118 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleLocationCondition.java,v 1.17 2006/03/14 01:20:40 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005). 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.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.service.condpermadmin;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Hashtable;
-
-import org.osgi.framework.*;
-
-/**
- * Condition to test if the location of a bundle matches a pattern. Pattern
- * matching is done according to the filter string matching rules.
- * 
- * @version $Revision: 1.17 $
- */
-public class BundleLocationCondition {
-	private static final String	CONDITION_TYPE	= "org.osgi.service.condpermadmin.BundleLocationCondition";
-
-	/**
-	 * Constructs a condition that tries to match the passed Bundle's location
-	 * to the location pattern.
-	 * 
-	 * @param bundle The Bundle being evaluated.
-	 * @param info The ConditionInfo to construct the condition for. The args of
-	 *        the ConditionInfo must be a single String which specifies the
-	 *        location pattern to match against the Bundle location. Matching is
-	 *        done according to the filter string matching rules. Any '*'
-	 *        characters in the location argument are used as wildcards when
-	 *        matching bundle locations unless they are escaped with a '\'
-	 *        character.
-	 * @return Condition object for the requested condition.
-	 */
-	static public Condition getCondition(final Bundle bundle, ConditionInfo info) {
-		if (!CONDITION_TYPE.equals(info.getType()))
-			throw new IllegalArgumentException(
-					"ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
-		String[] args = info.getArgs();
-		if (args.length != 1)
-			throw new IllegalArgumentException("Illegal number of args: "
-					+ args.length);
-		String bundleLocation = (String) AccessController
-				.doPrivileged(new PrivilegedAction() {
-					public Object run() {
-						return bundle.getLocation();
-					}
-				});
-		Filter filter = null;
-		try {
-			filter = FrameworkUtil.createFilter("(location="
-					+ escapeLocation(args[0]) + ")");
-		}
-		catch (InvalidSyntaxException e) {
-			// this should never happen, but just incase
-			throw new RuntimeException("Invalid filter: " + e.getFilter());
-		}
-		Hashtable matchProps = new Hashtable(2);
-		matchProps.put("location", bundleLocation);
-		return filter.match(matchProps) ? Condition.TRUE : Condition.FALSE;
-	}
-
-	private BundleLocationCondition() {
-		// private constructor to prevent objects of this type
-	}
-
-	/**
-	 * Escape the value string such that '(', ')' and '\' are escaped. The '\'
-	 * char is only escaped if it is not followed by a '*'.
-	 * 
-	 * @param value unescaped value string.
-	 * @return escaped value string.
-	 */
-	private static String escapeLocation(String value) {
-		boolean escaped = 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 '\\' :
-					if (i + 1 < outlen && output[i + 1] == '*')
-						break;
-				case '(' :
-				case ')' :
-					output[cursor] = '\\';
-					cursor++;
-					escaped = true;
-					break;
-			}
-
-			output[cursor] = c;
-			cursor++;
-		}
-
-		return escaped ? new String(output, 0, cursor) : value;
-	}
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleLocationCondition.java,v 1.18 2006/06/16 16:31:37 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2005, 2006). 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Hashtable;
+
+import org.osgi.framework.*;
+
+/**
+ * Condition to test if the location of a bundle matches a pattern. Pattern
+ * matching is done according to the filter string matching rules.
+ * 
+ * @version $Revision: 1.18 $
+ */
+public class BundleLocationCondition {
+	private static final String	CONDITION_TYPE	= "org.osgi.service.condpermadmin.BundleLocationCondition";
+
+	/**
+	 * Constructs a condition that tries to match the passed Bundle's location
+	 * to the location pattern.
+	 * 
+	 * @param bundle The Bundle being evaluated.
+	 * @param info The ConditionInfo to construct the condition for. The args of
+	 *        the ConditionInfo must be a single String which specifies the
+	 *        location pattern to match against the Bundle location. Matching is
+	 *        done according to the filter string matching rules. Any '*'
+	 *        characters in the location argument are used as wildcards when
+	 *        matching bundle locations unless they are escaped with a '\'
+	 *        character.
+	 * @return Condition object for the requested condition.
+	 */
+	static public Condition getCondition(final Bundle bundle, ConditionInfo info) {
+		if (!CONDITION_TYPE.equals(info.getType()))
+			throw new IllegalArgumentException(
+					"ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+		String[] args = info.getArgs();
+		if (args.length != 1)
+			throw new IllegalArgumentException("Illegal number of args: "
+					+ args.length);
+		String bundleLocation = (String) AccessController
+				.doPrivileged(new PrivilegedAction() {
+					public Object run() {
+						return bundle.getLocation();
+					}
+				});
+		Filter filter = null;
+		try {
+			filter = FrameworkUtil.createFilter("(location="
+					+ escapeLocation(args[0]) + ")");
+		}
+		catch (InvalidSyntaxException e) {
+			// this should never happen, but just incase
+			throw new RuntimeException("Invalid filter: " + e.getFilter());
+		}
+		Hashtable matchProps = new Hashtable(2);
+		matchProps.put("location", bundleLocation);
+		return filter.match(matchProps) ? Condition.TRUE : Condition.FALSE;
+	}
+
+	private BundleLocationCondition() {
+		// private constructor to prevent objects of this type
+	}
+
+	/**
+	 * Escape the value string such that '(', ')' and '\' are escaped. The '\'
+	 * char is only escaped if it is not followed by a '*'.
+	 * 
+	 * @param value unescaped value string.
+	 * @return escaped value string.
+	 */
+	private static String escapeLocation(String value) {
+		boolean escaped = 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 '\\' :
+					if (i + 1 < outlen && output[i + 1] == '*')
+						break;
+				case '(' :
+				case ')' :
+					output[cursor] = '\\';
+					cursor++;
+					escaped = true;
+					break;
+			}
+
+			output[cursor] = c;
+			cursor++;
+		}
+
+		return escaped ? new String(output, 0, cursor) : value;
+	}
+}