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 2009/07/24 19:06:44 UTC

svn commit: r797561 [6/9] - in /felix/trunk: org.osgi.compendium/ org.osgi.compendium/src/main/java/info/dmtree/ org.osgi.compendium/src/main/java/info/dmtree/notification/ org.osgi.compendium/src/main/java/info/dmtree/notification/spi/ org.osgi.compen...

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPService.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,6 +20,8 @@
  * 
  * Each UPnP device contains zero or more services. The UPnP description for a
  * service defines actions, their arguments, and event characteristics.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPService {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPStateVariable.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,13 +19,15 @@
  * The meta-information of a UPnP state variable as declared in the device's
  * service state table (SST).
  * <p>
- * Method calls to interact with a device (e.g. <code>UPnPAction.invoke(...);</code>)
- * use this class to encapsulate meta information about the input and output
- * arguments.
+ * Method calls to interact with a device (e.g.
+ * <code>UPnPAction.invoke(...);</code>) use this class to encapsulate meta
+ * information about the input and output arguments.
  * <p>
  * The actual values of the arguments are passed as Java objects. The mapping of
  * types from UPnP data types to Java data types is described with the field
  * definitions.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPStateVariable {
 	/**

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html Fri Jul 24 17:06:37 2009
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>UPnP Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.upnp; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo Fri Jul 24 17:06:37 2009
@@ -0,0 +1 @@
+version 1.1

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Authorization.java,v 1.11 2007/02/07 18:53:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -60,7 +58,7 @@
  * <code>Authorization</code> object), the service explicitly checks that the
  * calling bundle has permission to make the call.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface Authorization {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Group.java,v 1.8 2006/06/16 16:31:41 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -87,7 +85,7 @@
  *  
  * </pre>
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  */
 public interface Group extends User {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Role.java,v 1.10 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -47,7 +45,7 @@
  * <code>UserAdminPermission</code> in the same way that properties for other
  * <code>Role</code> objects are.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Role {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/User.java,v 1.9 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -39,7 +37,7 @@
  * Credentials are <code>Dictionary</code> objects and have semantics that are
  * similar to the properties in the <code>Role</code> class.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public interface User extends Role {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdmin.java,v 1.12 2006/07/12 21:21:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -45,7 +43,7 @@
  * <code>Role</code> objects, in which each <code>Role</code> object has a unique
  * name.
  * 
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
  */
 public interface UserAdmin {
 	/**
@@ -74,7 +72,7 @@
 
 	/**
 	 * Removes the <code>Role</code> object with the given name from this User
-	 * Admin service.
+	 * Admin service and all groups it is a member of.
 	 * 
 	 * <p>
 	 * If the <code>Role</code> object was removed, a <code>UserAdminEvent</code>

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java,v 1.9 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -35,7 +33,7 @@
  * @see UserAdmin
  * @see UserAdminListener
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public class UserAdminEvent {
 	private ServiceReference	ref;

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminListener.java,v 1.8 2006/06/16 16:31:41 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -32,7 +30,7 @@
  * @see UserAdmin
  * @see UserAdminEvent
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  */
 public interface UserAdminListener {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java,v 1.13 2006/07/12 21:21:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2009). 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.
@@ -18,7 +16,9 @@
 package org.osgi.service.useradmin;
 
 import java.io.IOException;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
@@ -27,8 +27,8 @@
  * Admin service.
  * 
  * <p>
- * This class represents access to the <code>Role</code> objects managed by a User
- * Admin service and their properties and credentials (in the case of
+ * This class represents access to the <code>Role</code> objects managed by a
+ * User Admin service and their properties and credentials (in the case of
  * {@link User} objects).
  * <p>
  * The permission name is the name (or name prefix) of a property or credential.
@@ -40,10 +40,11 @@
  * 
  * <p>
  * The <code>UserAdminPermission</code> with the reserved name &quot;admin&quot;
- * represents the permission required for creating and removing <code>Role</code>
- * objects in the User Admin service, as well as adding and removing members in
- * a <code>Group</code> object. This <code>UserAdminPermission</code> does not have
- * any actions associated with it.
+ * represents the permission required for creating and removing
+ * <code>Role</code> objects in the User Admin service, as well as adding and
+ * removing members in a <code>Group</code> object. This
+ * <code>UserAdminPermission</code> does not have any actions associated with
+ * it.
  * 
  * <p>
  * The actions to be granted are passed to the constructor in a string
@@ -64,7 +65,7 @@
  *                    existence of User object credentials whose names
  *                    start with the name argument specified in the
  *                    constructor.
- *  
+ * 
  * </pre>
  * 
  * The action string is converted to lowercase before processing.
@@ -78,7 +79,7 @@
  *  (org.osgi.service.useradmin.UserAdminPermission &quot;admin&quot;)
  *  (org.osgi.service.useradmin.UserAdminPermission &quot;com.foo.*&quot; &quot;changeProperty,getCredential,changeCredential&quot;)
  *  (org.osgi.service.useradmin.UserAdminPermission &quot;user.*&quot;, &quot;changeProperty,changeCredential&quot;)
- *  
+ * 
  * </pre>
  * 
  * The first permission statement grants the bundle the permission to perform
@@ -106,7 +107,7 @@
  *    permission org.osgi.service.useradmin.UserAdminPermission
  *      &quot;user.password&quot;, &quot;getCredential&quot;;
  *  };
- *  
+ * 
  * </pre>
  * 
  * <p>
@@ -114,10 +115,11 @@
  * validate any password credentials (for authentication purposes), but the
  * bundle is not allowed to change any properties or credentials.
  * 
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
  */
 public final class UserAdminPermission extends BasicPermission {
-    static final long serialVersionUID = -1179971692401603789L;
+	static final long			serialVersionUID			= -1179971692401603789L;
 	/**
 	 * The permission name &quot;admin&quot;.
 	 */
@@ -146,30 +148,26 @@
 	/**
 	 * No actions.
 	 */
-	static final int			ACTION_NONE					= 0x0;
+	static final int			ACTION_NONE					= 0;
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private String				actions						= null;
+	private volatile String		actions						= null;
 	/**
 	 * The actions mask.
 	 */
-	private transient int		action_mask					= ACTION_NONE;
-	/*
-	 * Description of this <code> UserAdminPermission </code> (returned by <code>
-	 * toString </code> )
-	 */
-	private transient String	description;
+	private transient int		action_mask;
 
 	/**
-	 * Creates a new <code>UserAdminPermission</code> with the specified name and
-	 * actions. <code>name</code> is either the reserved string &quot;admin&quot;
-	 * or the name of a credential or property, and <code>actions</code> contains
-	 * a comma-separated list of the actions granted on the specified name.
-	 * Valid actions are <code>changeProperty</code>,<code>changeCredential</code>,
-	 * and getCredential.
+	 * Creates a new <code>UserAdminPermission</code> with the specified name
+	 * and actions. <code>name</code> is either the reserved string
+	 * &quot;admin&quot; or the name of a credential or property, and
+	 * <code>actions</code> contains a comma-separated list of the actions
+	 * granted on the specified name. Valid actions are
+	 * <code>changeProperty</code>,<code>changeCredential</code>, and
+	 * getCredential.
 	 * 
 	 * @param name the name of this <code>UserAdminPermission</code>
 	 * @param actions the action string.
@@ -178,7 +176,7 @@
 	 *         &quot;admin&quot; and <code>actions</code> are specified.
 	 */
 	public UserAdminPermission(String name, String actions) {
-		this(name, getMask(actions));
+		this(name, parseActions(actions));
 	}
 
 	/**
@@ -190,7 +188,7 @@
 	 */
 	UserAdminPermission(String name, int mask) {
 		super(name);
-		init(mask);
+		setTransients(mask);
 	}
 
 	/**
@@ -198,7 +196,7 @@
 	 * 
 	 * @param mask action mask
 	 */
-	private void init(int mask) {
+	private synchronized void setTransients(int mask) {
 		if (getName().equals(ADMIN)) {
 			if (mask != ACTION_NONE) {
 				throw new IllegalArgumentException("Actions specified for "
@@ -214,21 +212,32 @@
 	}
 
 	/**
-	 * Parses the action string into the action mask.
+	 * Returns the current action mask.
+	 * <p>
+	 * Used by the UserAdminPermissionCollection class.
+	 * 
+	 * @return Current action mask.
+	 */
+	synchronized int getActionsMask() {
+		return action_mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
 	 * 
 	 * @param actions Action string.
 	 * @return action mask.
 	 */
-	private static int getMask(String actions) {
+	private static int parseActions(String actions) {
 		boolean seencomma = false;
 		int mask = ACTION_NONE;
 		if (actions == null) {
-			return (mask);
+			return mask;
 		}
 		char[] a = actions.toCharArray();
 		int i = a.length - 1;
 		if (i < 0)
-			return (mask);
+			return mask;
 		while (i != -1) {
 			char c;
 			// skip whitespace
@@ -265,7 +274,7 @@
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -284,7 +293,7 @@
 		if (seencomma) {
 			throw new IllegalArgumentException("invalid permission: " + actions);
 		}
-		return (mask);
+		return mask;
 	}
 
 	private static boolean match_change(char[] a, int i) {
@@ -323,15 +332,14 @@
 	}
 
 	/**
-	 * Checks if this <code>UserAdminPermission</code> object &quot;implies&quot;
-	 * the specified permission.
+	 * Checks if this <code>UserAdminPermission</code> object
+	 * &quot;implies&quot; the specified permission.
 	 * <P>
 	 * More specifically, this method returns <code>true</code> if:
 	 * <p>
 	 * <ul>
 	 * <li><i>p </i> is an instanceof <code>UserAdminPermission</code>,
-	 * <li><i>p </i>'s actions are a proper subset of this object's actions,
-	 * and
+	 * <li><i>p </i>'s actions are a proper subset of this object's actions, and
 	 * <li><i>p </i>'s name is implied by this object's name. For example,
 	 * &quot;java.*&quot; implies &quot;java.home&quot;.
 	 * </ul>
@@ -343,19 +351,18 @@
 	 */
 	public boolean implies(Permission p) {
 		if (p instanceof UserAdminPermission) {
-			UserAdminPermission target = (UserAdminPermission) p;
-			return (// Check that the we have the requested action
-			((target.action_mask & action_mask) == target.action_mask)
-					&&
-					// If the target action mask is ACTION_NONE, it must be an
+			UserAdminPermission requested = (UserAdminPermission) p;
+			int mask = getActionsMask();
+			int targetMask = requested.getActionsMask();
+			return // Check that the we have the requested action
+			((targetMask & mask) == targetMask) &&
+			// If the target action mask is ACTION_NONE, it must be an
 					// admin permission, and then we must be that too
-					(target.action_mask != ACTION_NONE || action_mask == ACTION_NONE) &&
-			// Check that name name matches
-			super.implies(p));
-		}
-		else {
-			return (false);
+					(targetMask != ACTION_NONE || mask == ACTION_NONE) &&
+					// Check that name name matches
+					super.implies(p);
 		}
+		return false;
 	}
 
 	/**
@@ -365,38 +372,40 @@
 	 * @return the canonical string representation of the actions.
 	 */
 	public String getActions() {
-		if (actions == null) {
+		String result = actions;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			boolean comma = false;
-			if ((action_mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
+			int mask = getActionsMask();
+			if ((mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
 				sb.append(CHANGE_CREDENTIAL);
 				comma = true;
 			}
-			if ((action_mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
+			if ((mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
 				if (comma)
 					sb.append(',');
 				sb.append(CHANGE_PROPERTY);
 				comma = true;
 			}
-			if ((action_mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
+			if ((mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
 				if (comma)
 					sb.append(',');
 				sb.append(GET_CREDENTIAL);
 			}
-			actions = sb.toString();
+			actions = result = sb.toString();
 		}
-		return (actions);
+		return result;
 	}
 
 	/**
 	 * Returns a new <code>PermissionCollection</code> object for storing
 	 * <code>UserAdminPermission</code> objects.
 	 * 
-	 * @return a new <code>PermissionCollection</code> object suitable for storing
-	 *         <code>UserAdminPermission</code> objects.
+	 * @return a new <code>PermissionCollection</code> object suitable for
+	 *         storing <code>UserAdminPermission</code> objects.
 	 */
 	public PermissionCollection newPermissionCollection() {
-		return (new UserAdminPermissionCollection());
+		return new UserAdminPermissionCollection();
 	}
 
 	/**
@@ -407,38 +416,32 @@
 	 * @param obj the object to be compared for equality with this object.
 	 * 
 	 * @return <code>true</code> if <code>obj</code> is a
-	 *         <code>UserAdminPermission</code> object, and has the same name and
-	 *         actions as this <code>UserAdminPermission</code> object.
+	 *         <code>UserAdminPermission</code> object, and has the same name
+	 *         and actions as this <code>UserAdminPermission</code> object.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
-			return (true);
+			return true;
 		}
-		if (obj instanceof UserAdminPermission) {
-			UserAdminPermission uap = (UserAdminPermission) obj;
-			return ((action_mask == uap.action_mask) && getName().equals(
-					uap.getName()));
+		if (!(obj instanceof UserAdminPermission)) {
+			return false;
 		}
-		else {
-			return (false);
-		}
-	}
 
-	/**
-	 * Returns the hash code of this <code>UserAdminPermission</code> object.
-	 */
-	public int hashCode() {
-		return (getName().hashCode() ^ getActions().hashCode());
+		UserAdminPermission uap = (UserAdminPermission) obj;
+
+		return (getActionsMask() == uap.getActionsMask())
+				&& getName().equals(uap.getName());
 	}
 
 	/**
-	 * Returns the current action mask. Used by the
-	 * <code>UserAdminPermissionCollection</code> class.
+	 * Returns the hash code value for this object.
 	 * 
-	 * @return the actions mask.
+	 * @return A hash code value for this object.
 	 */
-	int getMask() {
-		return (action_mask);
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
 	}
 
 	/**
@@ -457,10 +460,11 @@
 	/*
 	 * Restores this object from a stream (i.e., deserializes it).
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream ois)
+	private synchronized void readObject(java.io.ObjectInputStream s)
 			throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		init(getMask(actions));
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(parseActions(actions));
 	}
 
 	/**
@@ -472,42 +476,42 @@
 	 * @see "<code>org.osgi.service.permissionadmin.PermissionInfo.getEncoded</code>"
 	 */
 	public String toString() {
-		if (description == null) {
-			StringBuffer sb = new StringBuffer();
-			sb.append('(');
-			sb.append(getClass().getName());
-			sb.append(" \"");
-			sb.append(getName());
-			String actions = getActions();
-			if (actions.length() > 0) {
-				sb.append("\" \"");
-				sb.append(actions);
-			}
-			sb.append("\")");
-			description = sb.toString();
+		StringBuffer sb = new StringBuffer();
+		sb.append('(');
+		sb.append(getClass().getName());
+		sb.append(" \"");
+		sb.append(getName());
+		String a = getActions();
+		if (a.length() > 0) {
+			sb.append("\" \"");
+			sb.append(a);
 		}
-		return (description);
+		sb.append("\")");
+		return sb.toString();
 	}
 }
+
 /**
  * A <code>UserAdminPermissionCollection</code> stores a set of
  * <code>UserAdminPermission</code> permissions.
  */
 
 final class UserAdminPermissionCollection extends PermissionCollection {
-    static final long serialVersionUID = -7222111885230120581L;
+	static final long		serialVersionUID	= -7222111885230120581L;
 	/**
 	 * Table of permissions.
 	 * 
 	 * @serial
+	 * @GuardedBy this
 	 */
-	private Hashtable	permissions;
+	private final Hashtable	permissions;
 	/**
 	 * Boolean saying if "*" is in the collection.
 	 * 
 	 * @serial
+	 * @GuardedBy this
 	 */
-	private boolean		all_allowed;
+	private boolean			all_allowed;
 
 	/**
 	 * Creates an empty <code>UserAdminPermissionCollection</code> object.
@@ -518,15 +522,17 @@
 	}
 
 	/**
-	 * Adds the given permission to this <code>UserAdminPermissionCollection</code>.
-	 * The key for the hash is the name.
+	 * Adds the given permission to this
+	 * <code>UserAdminPermissionCollection</code>. The key for the hash is the
+	 * name.
 	 * 
 	 * @param permission the <code>Permission</code> object to add.
 	 * 
 	 * @throws IllegalArgumentException If the given permission is not a
 	 *         <code>UserAdminPermission</code>
-	 * @throws SecurityException If this <code>UserAdminPermissionCollection</code>
-	 *         object has been marked readonly
+	 * @throws SecurityException If this
+	 *         <code>UserAdminPermissionCollection</code> object has been marked
+	 *         readonly
 	 */
 	public void add(Permission permission) {
 		if (!(permission instanceof UserAdminPermission))
@@ -536,24 +542,27 @@
 			throw new SecurityException("Attempt to add a Permission to a "
 					+ "readonly PermissionCollection");
 		}
-		UserAdminPermission uap = (UserAdminPermission) permission;
-		String name = uap.getName();
-		UserAdminPermission existing = (UserAdminPermission) permissions
-				.get(name);
-		if (existing != null) {
-			int oldMask = existing.getMask();
-			int newMask = uap.getMask();
-			if (oldMask != newMask) {
-				permissions.put(name, new UserAdminPermission(name, oldMask
-						| newMask));
+		final UserAdminPermission uap = (UserAdminPermission) permission;
+		final String name = uap.getName();
+		synchronized (this) {
+			final UserAdminPermission existing = (UserAdminPermission) permissions
+					.get(name);
+			if (existing != null) {
+				int oldMask = existing.getActionsMask();
+				int newMask = uap.getActionsMask();
+				if (oldMask != newMask) {
+					permissions.put(name, new UserAdminPermission(name, oldMask
+							| newMask));
+				}
+			}
+			else {
+				permissions.put(name, uap);
+			}
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
 			}
-		}
-		else {
-			permissions.put(name, permission);
-		}
-		if (!all_allowed) {
-			if (name.equals("*"))
-				all_allowed = true;
 		}
 	}
 
@@ -568,33 +577,36 @@
 	 */
 	public boolean implies(Permission permission) {
 		if (!(permission instanceof UserAdminPermission)) {
-			return (false);
+			return false;
 		}
-		UserAdminPermission uap = (UserAdminPermission) permission;
+		final UserAdminPermission requested = (UserAdminPermission) permission;
+		String name = requested.getName();
+		final int desired = requested.getActionsMask();
 		UserAdminPermission x;
-		int desired = uap.getMask();
 		int effective = 0;
-		// Short circuit if the "*" Permission was added.
-		// desired can only be ACTION_NONE when name is "admin".
-		if (all_allowed && desired != UserAdminPermission.ACTION_NONE) {
-			x = (UserAdminPermission) permissions.get("*");
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired) {
-					return (true);
+		synchronized (this) {
+			// Short circuit if the "*" Permission was added.
+			// desired can only be ACTION_NONE when name is "admin".
+			if (all_allowed && (desired != UserAdminPermission.ACTION_NONE)) {
+				x = (UserAdminPermission) permissions.get("*");
+				if (x != null) {
+					effective |= x.getActionsMask();
+					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.*
+
+			x = (UserAdminPermission) permissions.get(name);
 		}
-		// strategy:
-		// Check for full match first. Then work our way up the
-		// name looking for matches on a.b.*
-		String name = uap.getName();
-		x = (UserAdminPermission) permissions.get(name);
 		if (x != null) {
 			// we have a direct hit!
-			effective |= x.getMask();
+			effective |= x.getActionsMask();
 			if ((effective & desired) == desired) {
-				return (true);
+				return true;
 			}
 		}
 		// work our way up the tree...
@@ -602,27 +614,30 @@
 		int offset = name.length() - 1;
 		while ((last = name.lastIndexOf(".", offset)) != -1) {
 			name = name.substring(0, last + 1) + "*";
-			x = (UserAdminPermission) permissions.get(name);
+			synchronized (this) {
+				x = (UserAdminPermission) permissions.get(name);
+			}
 			if (x != null) {
-				effective |= x.getMask();
+				effective |= x.getActionsMask();
 				if ((effective & desired) == desired) {
-					return (true);
+					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);
+		return false;
 	}
 
 	/**
-	 * Returns an enumeration of all the <code>UserAdminPermission</code> objects
-	 * in the container.
+	 * Returns an enumeration of all the <code>UserAdminPermission</code>
+	 * objects in the container.
 	 * 
-	 * @return an enumeration of all the <code>UserAdminPermission</code> objects.
+	 * @return an enumeration of all the <code>UserAdminPermission</code>
+	 *         objects.
 	 */
 	public Enumeration elements() {
-		return (permissions.elements());
+		return permissions.elements();
 	}
 }

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html Fri Jul 24 17:06:37 2009
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>User Admin Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.useradmin; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo Fri Jul 24 17:06:37 2009
@@ -0,0 +1 @@
+version 1.1

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/BasicEnvelope.java,v 1.9 2006/06/16 16:31:43 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,7 +19,7 @@
  * <code>BasicEnvelope</code> is an implementation of the {@link Envelope}
  * interface
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public class BasicEnvelope implements Envelope {
 	Object	value;

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Consumer.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -53,7 +51,7 @@
  * different types of objects from the Producer service. The Consumer service
  * should have <code>WirePermission</code> for each of these scope names.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Consumer {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Envelope.java,v 1.8 2006/06/16 16:31:43 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -45,7 +43,7 @@
  * @see WirePermission
  * @see BasicEnvelope
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  */
 public interface Envelope {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Producer.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -66,7 +64,7 @@
  * different types of objects (composite) to the Consumer service. The Producer
  * service should have <code>WirePermission</code> for each of these scope names.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Producer {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Wire.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -55,7 +53,7 @@
  * is used in communication. The semantics of the names depend on the Producer
  * service and must not be interpreted by the Wire Admin service.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Wire {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdmin.java,v 1.11 2006/07/12 21:22:14 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -38,7 +36,7 @@
  * <code>ServicePermission[WireAdmin,GET]</code> to get the Wire Admin service to
  * create, modify, find, and delete <code>Wire</code> objects.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface WireAdmin {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdminEvent.java,v 1.9 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -56,7 +54,7 @@
  * 
  * @see WireAdminListener
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public class WireAdminEvent {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdminListener.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -58,7 +56,7 @@
  * 
  * @see WireAdminEvent
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface WireAdminListener {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireConstants.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,7 +19,7 @@
  * Defines standard names for <code>Wire</code> properties, wire filter
  * attributes, Consumer and Producer service properties.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface WireConstants {
 	/**

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WirePermission.java,v 1.13 2006/07/12 21:22:14 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2009). 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.
@@ -18,15 +16,17 @@
 package org.osgi.service.wireadmin;
 
 import java.io.IOException;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
 /**
  * Permission for the scope of a <code>Wire</code> object. When a
- * <code>Envelope</code> object is used for communication with the <code>poll</code>
- * or <code>update</code> method, and the scope is set, then the <code>Wire</code>
- * object must verify that the Consumer service has
+ * <code>Envelope</code> object is used for communication with the
+ * <code>poll</code> or <code>update</code> method, and the scope is set, then
+ * the <code>Wire</code> object must verify that the Consumer service has
  * <code>WirePermission[name,CONSUME]</code> and the Producer service has
  * <code>WirePermission[name,PRODUCE]</code> for all names in the scope.
  * <p>
@@ -35,43 +35,45 @@
  * scope names starting with the string "Door". The last period is required due
  * to the implementations of the <code>BasicPermission</code> class.
  * 
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
  */
 final public class WirePermission extends BasicPermission {
-    static final long serialVersionUID = -5583709391516569321L;
+	static final long			serialVersionUID	= -5583709391516569321L;
 	/**
-	 * The action string for the <code>PRODUCE</code> action: value is "produce".
+	 * The action string for the <code>produce</code> action.
 	 */
-	public static final String	PRODUCE			= "produce";
+	public static final String	PRODUCE				= "produce";
 	/**
-	 * The action string for the <code>CONSUME</code> action: value is "consume".
+	 * The action string for the <code>consume</code> action.
 	 */
-	public static final String	CONSUME			= "consume";
-	private final static int	ACTION_PRODUCE	= 0x00000001;
-	private final static int	ACTION_CONSUME	= 0x00000002;
-	private final static int	ACTION_ALL		= ACTION_PRODUCE
-														| ACTION_CONSUME;
-	private final static int	ACTION_NONE		= 0;
+	public static final String	CONSUME				= "consume";
+	private final static int	ACTION_PRODUCE		= 0x00000001;
+	private final static int	ACTION_CONSUME		= 0x00000002;
+	private final static int	ACTION_ALL			= ACTION_PRODUCE
+															| ACTION_CONSUME;
+	private final static int	ACTION_NONE			= 0;
 	/**
 	 * The actions mask.
 	 */
-	private transient int		action_mask		= ACTION_NONE;
+	private transient int		action_mask;
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private String				actions			= null;
+	private volatile String		actions				= null;
 
 	/**
 	 * Create a new WirePermission with the given name (may be wildcard) and
 	 * actions.
+	 * 
 	 * @param name Wire name.
-	 * @param actions <code>produce</code>, <code>consume</code>
-	 *        (canonical order).
+	 * @param actions <code>produce</code>, <code>consume</code> (canonical
+	 *        order).
 	 */
 	public WirePermission(String name, String actions) {
-		this(name, getMask(actions));
+		this(name, parseActions(actions));
 	}
 
 	/**
@@ -82,7 +84,7 @@
 	 */
 	WirePermission(String name, int mask) {
 		super(name);
-		init(mask);
+		setTransients(mask);
 	}
 
 	/**
@@ -90,7 +92,7 @@
 	 * 
 	 * @param mask action mask
 	 */
-	private void init(int mask) {
+	private synchronized void setTransients(int mask) {
 		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
 			throw new IllegalArgumentException("invalid action string");
 		}
@@ -98,12 +100,22 @@
 	}
 
 	/**
+	 * Returns the current action mask. Used by the WirePermissionCollection
+	 * object.
+	 * 
+	 * @return The actions mask.
+	 */
+	synchronized int getActionsMask() {
+		return action_mask;
+	}
+
+	/**
 	 * Parse action string into action mask.
 	 * 
 	 * @param actions Action string.
 	 * @return action mask.
 	 */
-	private static int getMask(String actions) {
+	private static int parseActions(String actions) {
 		boolean seencomma = false;
 		int mask = ACTION_NONE;
 		if (actions == null) {
@@ -155,7 +167,7 @@
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -178,15 +190,14 @@
 	}
 
 	/**
-	 * Checks if this <code>WirePermission</code> object <code>implies</code> the
-	 * specified permission.
+	 * Checks if this <code>WirePermission</code> object <code>implies</code>
+	 * the specified permission.
 	 * <P>
 	 * More specifically, this method returns <code>true</code> if:
 	 * <p>
 	 * <ul>
 	 * <li><i>p </i> is an instanceof the <code>WirePermission</code> class,
-	 * <li><i>p </i>'s actions are a proper subset of this object's actions,
-	 * and
+	 * <li><i>p </i>'s actions are a proper subset of this object's actions, and
 	 * <li><i>p </i>'s name is implied by this object's name. For example,
 	 * <code>java.*</code> implies <code>java.home</code>.
 	 * </ul>
@@ -198,8 +209,9 @@
 	 */
 	public boolean implies(Permission p) {
 		if (p instanceof WirePermission) {
-			WirePermission target = (WirePermission) p;
-			return ((action_mask & target.action_mask) == target.action_mask)
+			WirePermission requested = (WirePermission) p;
+			int requestedMask = requested.getActionsMask();
+			return ((getActionsMask() & requestedMask) == requestedMask)
 					&& super.implies(p);
 		}
 		return false;
@@ -213,29 +225,31 @@
 	 * @return The canonical string representation of the actions.
 	 */
 	public String getActions() {
-		if (actions == null) {
+		String result = actions;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			boolean comma = false;
-			if ((action_mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
+			int mask = getActionsMask();
+			if ((mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
 				sb.append(PRODUCE);
 				comma = true;
 			}
-			if ((action_mask & ACTION_CONSUME) == ACTION_CONSUME) {
+			if ((mask & ACTION_CONSUME) == ACTION_CONSUME) {
 				if (comma)
 					sb.append(',');
 				sb.append(CONSUME);
 			}
-			actions = sb.toString();
+			actions = result = sb.toString();
 		}
-		return actions;
+		return result;
 	}
 
 	/**
 	 * Returns a new <code>PermissionCollection</code> object for storing
 	 * <code>WirePermission</code> objects.
 	 * 
-	 * @return A new <code>PermissionCollection</code> object suitable for storing
-	 *         <code>WirePermission</code> objects.
+	 * @return A new <code>PermissionCollection</code> object suitable for
+	 *         storing <code>WirePermission</code> objects.
 	 */
 	public PermissionCollection newPermissionCollection() {
 		return new WirePermissionCollection();
@@ -248,8 +262,8 @@
 	 * <code>WirePermission</code> object.
 	 * 
 	 * @param obj The object to test for equality.
-	 * @return true if <code>obj</code> is a <code>WirePermission</code>, and has
-	 *         the same name and actions as this <code>WirePermission</code>
+	 * @return true if <code>obj</code> is a <code>WirePermission</code>, and
+	 *         has the same name and actions as this <code>WirePermission</code>
 	 *         object; <code>false</code> otherwise.
 	 */
 	public boolean equals(Object obj) {
@@ -259,8 +273,9 @@
 		if (!(obj instanceof WirePermission)) {
 			return false;
 		}
-		WirePermission p = (WirePermission) obj;
-		return (action_mask == p.action_mask) && getName().equals(p.getName());
+		WirePermission wp = (WirePermission) obj;
+		return (getActionsMask() == wp.getActionsMask())
+				&& getName().equals(wp.getName());
 	}
 
 	/**
@@ -269,17 +284,9 @@
 	 * @return Hash code value for this object.
 	 */
 	public int hashCode() {
-		return getName().hashCode() ^ getActions().hashCode();
-	}
-
-	/**
-	 * Returns the current action mask. Used by the WirePermissionCollection
-	 * object.
-	 * 
-	 * @return The actions mask.
-	 */
-	int getMask() {
-		return action_mask;
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
 	}
 
 	/**
@@ -297,8 +304,11 @@
 		sb.append(getClass().getName());
 		sb.append(" \"");
 		sb.append(getName());
-		sb.append("\" \"");
-		sb.append(getActions());
+		String a = getActions();
+		if (a.length() > 0) {
+			sb.append("\" \"");
+			sb.append(a);
+		}
 		sb.append("\")");
 		return sb.toString();
 	}
@@ -325,32 +335,35 @@
 			throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
-		init(getMask(actions));
+		setTransients(parseActions(actions));
 	}
 }
+
 /**
- * A <code>WirePermissionCollection</code> stores a set of <code>WirePermission</code>
- * permissions.
+ * A <code>WirePermissionCollection</code> stores a set of
+ * <code>WirePermission</code> permissions.
  */
 
 final class WirePermissionCollection extends PermissionCollection {
-    static final long serialVersionUID = 2617521094909826016L;
+	static final long		serialVersionUID	= 2617521094909826016L;
 	/**
 	 * Table of permissions.
 	 * 
+	 * @GuardedBy this
 	 * @serial
 	 */
-	private Hashtable	permissions;
+	private final Hashtable	permissions;
 	/**
 	 * Boolean saying if "*" is in the collection.
 	 * 
+	 * @GuardedBy this
 	 * @serial
 	 */
-	private boolean		all_allowed;
+	private boolean			all_allowed;
 
 	/**
 	 * Creates an empty WirePermissionCollection object.
-	 *  
+	 * 
 	 */
 	public WirePermissionCollection() {
 		permissions = new Hashtable();
@@ -363,35 +376,40 @@
 	 * @param permission The Permission object to add.
 	 * 
 	 * @throws IllegalArgumentException If the permission is not a
-	 *            WirePermission object.
+	 *         WirePermission object.
 	 * 
 	 * @throws SecurityException If this PermissionCollection has been marked
-	 *            read-only.
+	 *         read-only.
 	 */
 	public void add(Permission permission) {
-		if (!(permission instanceof WirePermission))
+		if (!(permission instanceof WirePermission)) {
 			throw new IllegalArgumentException("invalid permission: "
 					+ permission);
-		if (isReadOnly())
+		}
+		if (isReadOnly()) {
 			throw new SecurityException("attempt to add a Permission to a "
 					+ "readonly PermissionCollection");
-		WirePermission p = (WirePermission) permission;
-		String name = p.getName();
-		WirePermission existing = (WirePermission) permissions.get(name);
-		if (existing != null) {
-			int oldMask = existing.getMask();
-			int newMask = p.getMask();
-			if (oldMask != newMask) {
-				permissions.put(name, new WirePermission(name, oldMask
-						| newMask));
-			}
-		}
-		else {
-			permissions.put(name, permission);
-		}
-		if (!all_allowed) {
-			if (name.equals("*"))
-				all_allowed = true;
+		}
+		WirePermission wp = (WirePermission) permission;
+		String name = wp.getName();
+		synchronized (this) {
+			WirePermission existing = (WirePermission) permissions.get(name);
+			if (existing != null) {
+				int oldMask = existing.getActionsMask();
+				int newMask = wp.getActionsMask();
+				if (oldMask != newMask) {
+					permissions.put(name, new WirePermission(name, oldMask
+							| newMask));
+				}
+			}
+			else {
+				permissions.put(name, wp);
+			}
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
 		}
 	}
 
@@ -401,46 +419,53 @@
 	 * 
 	 * @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.
+	 * @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 WirePermission))
+		if (!(permission instanceof WirePermission)) {
 			return false;
-		WirePermission p = (WirePermission) permission;
+		}
+		WirePermission requested = (WirePermission) permission;
 		WirePermission x;
-		int desired = p.getMask();
+		int desired = requested.getActionsMask();
 		int effective = 0;
-		// short circuit if the "*" Permission was added
-		if (all_allowed) {
-			x = (WirePermission) permissions.get("*");
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
-					return true;
+		String name = requested.getName();
+		synchronized (this) {
+			// short circuit if the "*" Permission was added
+			if (all_allowed) {
+				x = (WirePermission) permissions.get("*");
+				if (x != null) {
+					effective |= x.getActionsMask();
+					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.*
+			x = (WirePermission) permissions.get(name);
 		}
-		// strategy:
-		// Check for full match first. Then work our way up the
-		// name looking for matches on a.b.*
-		String name = p.getName();
-		x = (WirePermission) permissions.get(name);
 		if (x != null) {
 			// we have a direct hit!
-			effective |= x.getMask();
-			if ((effective & desired) == desired)
+			effective |= x.getActionsMask();
+			if ((effective & desired) == desired) {
 				return true;
+			}
 		}
 		// work our way up the tree...
-		int last, offset;
-		offset = name.length() - 1;
+		int last;
+		int offset = name.length() - 1;
 		while ((last = name.lastIndexOf(".", offset)) != -1) {
 			name = name.substring(0, last + 1) + "*";
-			x = (WirePermission) permissions.get(name);
+			synchronized (this) {
+				x = (WirePermission) permissions.get(name);
+			}
 			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
+				effective |= x.getActionsMask();
+				if ((effective & desired) == desired) {
 					return (true);
+				}
 			}
 			offset = last - 1;
 		}

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html Fri Jul 24 17:06:37 2009
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Wire Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.wireadmin; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
+

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo Fri Jul 24 17:06:37 2009
@@ -0,0 +1 @@
+version 1.0

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java Fri Jul 24 17:06:37 2009
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2009). 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.util.cdma;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionInfo;
+
+/**
+ * Class representing an ESN condition. Instances of this class contain a string
+ * value that is matched against the ESN of the device.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6439 $
+ */
+public class ESNCondition {
+	private static final String	ORG_OSGI_UTIL_CDMA_ESN	= "org.osgi.util.cdma.esn";
+	private static final String	ESN;
+	private static final int	ESN_LENGTH				= 8;
+
+	static {
+		ESN = (String) AccessController.doPrivileged(new PrivilegedAction() {
+			public Object run() {
+				String esn = System.getProperty(ORG_OSGI_UTIL_CDMA_ESN);
+				if (esn == null) {
+					return null;
+				}
+				return esn.toUpperCase();
+			}
+		});
+	}
+
+	private ESNCondition() {
+		// prevent instances being constructed
+	}
+
+	/**
+	 * Creates an ESNCondition object.
+	 * 
+	 * @param bundle This parameter is ignored, as the ESN number is the
+	 *        property of the mobile device, and thus the same for all bundles.
+	 * @param conditionInfo Contains the ESN value against which to match the
+	 *        device's ESN. Its {@link ConditionInfo#getArgs()} method should
+	 *        return a String array with one value, the ESN string. The ESN is 8
+	 *        hexadecimal digits (32 bits) without hyphens. Limited pattern
+	 *        matching is allowed: the string is 0 to 7 digits, followed by an
+	 *        asterisk(<code>*</code>).
+	 * @return A Condition object that indicates whether the specified ESN
+	 *         number matches that of the device. If the number ends with an
+	 *         asterisk ( <code>*</code>), then the beginning of the ESN is
+	 *         compared to the pattern.
+	 * @throws IllegalArgumentException If the ESN is not a string of 8
+	 *         hexadecimal digits, or 0 to 7 hexadecimal digits with an
+	 *         <code>*</code> at the end.
+	 */
+	public static Condition getCondition(Bundle bundle,
+			ConditionInfo conditionInfo) {
+		String esn = conditionInfo.getArgs()[0].toUpperCase();
+		int length = esn.length();
+		if (length > ESN_LENGTH) {
+			throw new IllegalArgumentException("ESN too long: " + esn);
+		}
+		if (esn.endsWith("*")) {
+			length--;
+			esn = esn.substring(0, length);
+		}
+		else {
+			if (length < ESN_LENGTH) {
+				throw new IllegalArgumentException("ESN too short: " + esn);
+			}
+		}
+		for (int i = 0; i < length; i++) {
+			char c = esn.charAt(i);
+			if (('0' <= c) && (c <= '9')) {
+				continue;
+			}
+	        if (('A' <= c) && (c <= 'F')) {
+				continue;
+			}
+			throw new IllegalArgumentException("not a valid ESN: " + esn);
+		}
+		if (ESN == null) {
+			System.err
+					.println("The OSGi implementation of org.osgi.util.cdma.ESNCondition needs the system property "
+							+ ORG_OSGI_UTIL_CDMA_ESN + " set.");
+			return Condition.FALSE;
+		}
+		return ESN.startsWith(esn) ? Condition.TRUE : Condition.FALSE;
+	}
+}

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java Fri Jul 24 17:06:37 2009
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2009). 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.util.cdma;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionInfo;
+
+/**
+ * Class representing an MEID condition. Instances of this class contain a
+ * string value that is matched against the MEID of the device.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6439 $
+ */
+public class MEIDCondition {
+	private static final String	ORG_OSGI_UTIL_CDMA_MEID	= "org.osgi.util.cdma.meid";
+	private static final String	MEID;
+	private static final int	MEID_LENGTH				= 14;
+
+	static {
+		MEID = (String) AccessController.doPrivileged(new PrivilegedAction() {
+			public Object run() {
+				String meid = System.getProperty(ORG_OSGI_UTIL_CDMA_MEID);
+				if (meid == null) {
+					return null;
+				}
+				return meid.toUpperCase();
+			}
+		});
+	}
+
+	private MEIDCondition() {
+		// prevent instances being constructed
+	}
+
+	/**
+	 * Creates a MEIDCondition object.
+	 * 
+	 * @param bundle This parameter is ignored, as the MEID number is the
+	 *        property of the mobile device, and thus the same for all bundles.
+	 * @param conditionInfo Contains the MEID value against which to match the
+	 *        device's MEID. Its {@link ConditionInfo#getArgs()} method should
+	 *        return a String array with one value, the MEID string. The MEID is
+	 *        14 hexadecimal digits (56 bits) without hyphens. Limited pattern
+	 *        matching is allowed: the string is 0 to 13 digits, followed by an
+	 *        asterisk(<code>*</code>).
+	 * @return A Condition object that indicates whether the specified MEID
+	 *         number matches that of the device. If the number ends with an
+	 *         asterisk ( <code>*</code>), then the beginning of the MEID is
+	 *         compared to the pattern.
+	 * @throws IllegalArgumentException If the MEID is not a string of 14
+	 *         hexadecimal digits, or 0 to 13 hexadecimal digits with an
+	 *         <code>*</code> at the end.
+	 */
+	public static Condition getCondition(Bundle bundle,
+			ConditionInfo conditionInfo) {
+		String meid = conditionInfo.getArgs()[0].toUpperCase();
+		int length = meid.length();
+		if (length > MEID_LENGTH) {
+			throw new IllegalArgumentException("MEID too long: " + meid);
+		}
+		if (meid.endsWith("*")) {
+			length--;
+			meid = meid.substring(0, length);
+		}
+		else {
+			if (length < MEID_LENGTH) {
+				throw new IllegalArgumentException("MEID too short: " + meid);
+			}
+		}
+		for (int i = 0; i < length; i++) {
+			char c = meid.charAt(i);
+			if (('0' <= c) && (c <= '9')) {
+				continue;
+			}
+			if (('A' <= c) && (c <= 'F')) {
+				continue;
+			}
+			throw new IllegalArgumentException("not a valid MEID: " + meid);
+		}
+		if (MEID == null) {
+			System.err
+					.println("The OSGi implementation of org.osgi.util.cdma.MEIDCondition needs the system property "
+							+ ORG_OSGI_UTIL_CDMA_MEID + " set.");
+			return Condition.FALSE;
+		}
+		return MEID.startsWith(meid) ? Condition.TRUE : Condition.FALSE;
+	}
+}

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html Fri Jul 24 17:06:37 2009
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>CDMA Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.cdma; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo Fri Jul 24 17:06:37 2009
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMEICondition.java,v 1.21 2007/02/19 21:32:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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.
@@ -27,59 +25,74 @@
 /**
  * Class representing an IMEI condition. Instances of this class contain a
  * string value that is matched against the IMEI of the device.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6439 $
  */
 public class IMEICondition {
-	private static final String ORG_OSGI_UTIL_GSM_IMEI = "org.osgi.util.gsm.imei";
-	private static final String imei ;
-		
+	private static final String	ORG_OSGI_UTIL_GSM_IMEI	= "org.osgi.util.gsm.imei";
+	private static final String	IMEI;
+	private static final int	IMEI_LENGTH				= 15;
+
 	static {
-		imei = (String)
-		AccessController.doPrivileged(
-				new PrivilegedAction() {
-					public Object run() {
-					return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
-					}
-				}
-				);
+		IMEI = (String) AccessController.doPrivileged(new PrivilegedAction() {
+			public Object run() {
+				return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
+			}
+		});
 	}
-	
+
 	private IMEICondition() {
+		// prevent instances being constructed
 	}
 
 	/**
-	 * Creates an IMEICondition object.
+	 * Creates an IMEI condition object.
 	 * 
-	 * @param bundle ignored, as the IMEI number is the property of the mobile device,
-	 * 					and thus the same for all bundles.
-	 * @param conditionInfo contains the IMEI value to match the device's IMEI against. Its
-	 * 		{@link ConditionInfo#getArgs()} method should return a String array with one value, the
-	 * 		IMEI string. The IMEI is 15 digits without hypens. Limited pattern matching is allowed,
-	 * 		then the string is 0 to 14 digits, followed by an asterisk(<code>*</code>).
-	 * @return An IMEICondition object, that can tell whether its IMEI number matches that of the device.
-	 * 			If the number contains an asterisk(<code>*</code>), then the beginning
-	 * 			of the imei is compared to the pattern.
-	 * @throws NullPointerException if one of the parameters is <code>null</code>.
-	 * @throws IllegalArgumentException if the IMEI is not a string of 15 digits, or 
-	 * 		0 to 14 digits with an <code>*</code> at the end.
+	 * @param bundle This parameter is ignored, as the IMEI number is a property
+	 *        of the mobile device and thus is the same for all bundles.
+	 * @param conditionInfo Contains the IMEI value against which to match the
+	 *        device's IMEI. Its {@link ConditionInfo#getArgs()} method should
+	 *        return a String array with one value: the IMEI string. The IMEI is
+	 *        15 digits without hyphens. Limited pattern matching is allowed:
+	 *        the string is 0 to 14 digits, followed by an asterisk (
+	 *        <code>*</code>).
+	 * @return A Condition object that indicates whether the specified IMEI
+	 *         number matches that of the device. If the number ends with an
+	 *         asterisk ( <code>*</code>), then the beginning of the IMEI is
+	 *         compared to the pattern.
+	 * @throws IllegalArgumentException If the IMEI is not a string of 15
+	 *         digits, or 0 to 14 digits with an <code>*</code> at the end.
 	 */
-	public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
-		if (bundle==null) throw new NullPointerException("bundle");
+	public static Condition getCondition(Bundle bundle,
+			ConditionInfo conditionInfo) {
 		String imei = conditionInfo.getArgs()[0];
-		if (imei.length()>15) throw new IllegalArgumentException("imei too long: "+imei);
+		int length = imei.length();
+		if (length > IMEI_LENGTH) {
+			throw new IllegalArgumentException("IMEI too long: " + imei);
+		}
 		if (imei.endsWith("*")) {
-			imei = imei.substring(0,imei.length()-1);
-		} else {
-			if (imei.length()!=15) throw new IllegalArgumentException("not a valid imei: "+imei);
+			length--;
+			imei = imei.substring(0, length);
+		}
+		else {
+			if (length < IMEI_LENGTH) {
+				throw new IllegalArgumentException("IMEI too short: " + imei);
+			}
 		}
-		for(int i=0;i<imei.length();i++) {
-			int c = imei.charAt(i);
-			if (c<'0'||c>'9') throw new IllegalArgumentException("not a valid imei: "+imei);
+		for (int i = 0; i < length; i++) {
+			char c = imei.charAt(i);
+			if (('0' <= c) && (c <= '9')) {
+				continue;
+			}
+			throw new IllegalArgumentException("not a valid IMEI: " + imei);
 		}
-		if (IMEICondition.imei==null) {
-			System.err.println("The OSGi Reference Implementation of org.osgi.util.gsm.IMEICondition ");
-			System.err.println("needs the system property "+ORG_OSGI_UTIL_GSM_IMEI+" set.");
+		if (IMEI == null) {
+			System.err
+					.println("The OSGi implementation of org.osgi.util.gsm.IMEICondition needs the system property "
+							+ ORG_OSGI_UTIL_GSM_IMEI + " set.");
 			return Condition.FALSE;
 		}
-		return IMEICondition.imei.startsWith(imei)?Condition.TRUE:Condition.FALSE;
+		return IMEI.startsWith(imei) ? Condition.TRUE : Condition.FALSE;
 	}
 }

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMSICondition.java,v 1.23 2007/02/19 21:32:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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.
@@ -27,58 +25,74 @@
 /**
  * Class representing an IMSI condition. Instances of this class contain a
  * string value that is matched against the IMSI of the subscriber.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6439 $
  */
 public class IMSICondition {
-	private static final String ORG_OSGI_UTIL_GSM_IMSI = "org.osgi.util.gsm.imsi";
-	private static final String imsi;
-	
+	private static final String	ORG_OSGI_UTIL_GSM_IMSI	= "org.osgi.util.gsm.imsi";
+	private static final String	IMSI;
+	private static final int	IMSI_LENGTH				= 15;
+
 	static {
-		imsi = (String)
-		AccessController.doPrivileged(
-				new PrivilegedAction() {
-					public Object run() {
-					return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
-					}
-				}
-				);
+		IMSI = (String) AccessController.doPrivileged(new PrivilegedAction() {
+			public Object run() {
+				return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
+			}
+		});
 	}
 
-	private IMSICondition() {}
+	private IMSICondition() {
+		// prevent instances being constructed
+	}
 
 	/**
 	 * Creates an IMSI condition object.
 	 * 
-	 * @param bundle ignored, as the IMSI number is the same for all bundles.
-	 * @param conditionInfo contains the IMSI value to match the device's IMSI against. Its
-	 * 		{@link ConditionInfo#getArgs()} method should return a String array with one value, the
-	 * 		IMSI string. The IMSI is 15 digits without hypens. Limited pattern matching is allowed,
-	 * 		then the string is 0 to 14 digits, followed by an asterisk(<code>*</code>).
-	 * @return An IMSICondition object, that can tell whether its IMSI number matches that of the device.
-	 * 			If the number contains an asterisk(<code>*</code>), then the beginning
-	 * 			of the IMSI is compared to the pattern.
-	 * @throws NullPointerException if one of the parameters is <code>null</code>.
-	 * @throws IllegalArgumentException if the IMSI is not a string of 15 digits, or 
-	 * 		0 to 14 digits with an <code>*</code> at the end.
+	 * @param bundle This parameter is ignored, as the IMSI number is a property
+	 *        of the mobile subscriber and thus is the same for all bundles.
+	 * @param conditionInfo Contains the IMSI value against which to match the
+	 *        subscriber's IMSI. Its {@link ConditionInfo#getArgs()} method
+	 *        should return a String array with one value: the IMSI string. The
+	 *        IMSI is 15 digits without hyphens. Limited pattern matching is
+	 *        allowed: the string is 0 to 14 digits, followed by an asterisk (
+	 *        <code>*</code>).
+	 * @return A Condition object that indicates whether the specified IMSI
+	 *         number matches that of the subscriber. If the number ends with an
+	 *         asterisk (<code>*</code>), then the beginning of the IMSI is
+	 *         compared to the pattern.
+	 * @throws IllegalArgumentException If the IMSI is not a string of 15
+	 *         digits, or 0 to 14 digits with an <code>*</code> at the end.
 	 */
-	public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
-		if (bundle==null) throw new NullPointerException("bundle");
-		if (conditionInfo==null) throw new NullPointerException("conditionInfo");
+	public static Condition getCondition(Bundle bundle,
+			ConditionInfo conditionInfo) {
 		String imsi = conditionInfo.getArgs()[0];
-		if (imsi.length()>15) throw new IllegalArgumentException("imsi too long: "+imsi);
+		int length = imsi.length();
+		if (length > IMSI_LENGTH) {
+			throw new IllegalArgumentException("IMSI too long: " + imsi);
+		}
 		if (imsi.endsWith("*")) {
-			imsi = imsi.substring(0,imsi.length()-1);
-		} else {
-			if (imsi.length()!=15) throw new IllegalArgumentException("not a valid imei: "+imsi);
+			length--;
+			imsi = imsi.substring(0, length);
+		}
+		else {
+			if (length < IMSI_LENGTH) {
+				throw new IllegalArgumentException("IMSI too short: " + imsi);
+			}
 		}
-		for(int i=0;i<imsi.length();i++) {
-			int c = imsi.charAt(i);
-			if (c<'0'||c>'9') throw new IllegalArgumentException("not a valid imei: "+imsi);
+		for (int i = 0; i < length; i++) {
+			char c = imsi.charAt(i);
+			if (('0' <= c) && (c <= '9')) {
+				continue;
+			}
+			throw new IllegalArgumentException("not a valid IMSI: " + imsi);
 		}
-		if (IMSICondition.imsi==null) {
-			System.err.println("The OSGi Reference Implementation of org.osgi.util.gsm.IMSICondition ");
-			System.err.println("needs the system property "+ORG_OSGI_UTIL_GSM_IMSI+" set.");
+		if (IMSI == null) {
+			System.err
+					.println("The OSGi implementation of org.osgi.util.gsm.IMSICondition needs the system property "
+							+ ORG_OSGI_UTIL_GSM_IMSI + " set.");
 			return Condition.FALSE;
 		}
-		return (IMSICondition.imsi.startsWith(imsi))?Condition.TRUE:Condition.FALSE;
+		return IMSI.startsWith(imsi) ? Condition.TRUE : Condition.FALSE;
 	}
 }

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html Fri Jul 24 17:06:37 2009
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Mobile GSM Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.gsm; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>

Added: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo?rev=797561&view=auto
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo (added)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo Fri Jul 24 17:06:37 2009
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file

Modified: felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
URL: http://svn.apache.org/viewvc/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java?rev=797561&r1=797560&r2=797561&view=diff
==============================================================================
--- felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java (original)
+++ felix/trunk/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java Fri Jul 24 17:06:37 2009
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/Measurement.java,v 1.14 2006/07/11 00:54:06 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -17,7 +15,6 @@
  */
 package org.osgi.util.measurement;
 
-
 /**
  * Represents a value with an error, a unit and a time-stamp.
  * 
@@ -46,15 +43,16 @@
  * Note: This class has a natural ordering that is inconsistent with equals. See
  * {@link #compareTo}.
  * 
- * @version $Revision: 1.14 $
+ * @Immutable
+ * @version $Revision: 5715 $
  */
 public class Measurement implements Comparable {
-	/* package private so it can be accessed by Unit */
-	final double	value;
-	final double	error;
-	final long		time;
-	final Unit		unit;
-	private transient String	name;
+	private final double				value;
+	private final double				error;
+	private final long					time;
+	private final Unit					unit;
+	private transient volatile String	name;
+	private transient volatile int		hashCode;
 
 	/**
 	 * Create a new <code>Measurement</code> object.
@@ -370,7 +368,8 @@
 	 *         object.
 	 */
 	public String toString() {
-		if (name == null) {
+		String result = name;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			sb.append(value);
 			if (error != 0.0d) {
@@ -382,9 +381,10 @@
 				sb.append(" ");
 				sb.append(u);
 			}
-			name = sb.toString();
+			result = sb.toString();
+			name = result;
 		}
-		return name;
+		return result;
 	}
 
 	/**
@@ -422,25 +422,20 @@
 			throw new ArithmeticException("Cannot compare " + this + " and "
 					+ that);
 		}
-		if (value == that.value) {
+		int result = Double.compare(value, that.value);
+		if (result == 0) {
 			return 0;
 		}
-		if (value < that.value) {
-			if ((value + error) >= (that.value - that.error)) {
+		if (result < 0) {
+			if (Double.compare(value + error, that.value - that.error) >= 0) {
 				return 0;
 			}
-			else {
-				return -1;
-			}
+			return -1;
 		}
-		else {
-			if ((value - error) <= (that.value + that.error)) {
-				return 0;
-			}
-			else {
-				return 1;
-			}
+		if (Double.compare(value - error, that.value + that.error) <= 0) {
+			return 0;
 		}
+		return 1;
 	}
 
 	/**
@@ -449,8 +444,16 @@
 	 * @return A hash code value for this object.
 	 */
 	public int hashCode() {
-		long bits = Double.doubleToLongBits(value + error);
-		return ((int) (bits ^ (bits >>> 32))) ^ unit.hashCode();
+		int h = hashCode;
+		if (h == 0) {
+			long bits = Double.doubleToLongBits(value);
+			h = 31 * 17 + ((int) (bits ^ (bits >>> 32)));
+			bits = Double.doubleToLongBits(error);
+			h = 31 * h + ((int) (bits ^ (bits >>> 32)));
+			h = 31 * h + unit.hashCode();
+			hashCode = h;
+		}
+		return h;
 	}
 
 	/**
@@ -474,7 +477,8 @@
 			return false;
 		}
 		Measurement that = (Measurement) obj;
-		return (value == that.value) && (error == that.error)
+		return (Double.compare(value, that.value) == 0)
+				&& (Double.compare(error, that.error) == 0)
 				&& unit.equals(that.unit);
 	}
 }