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 2012/05/11 22:19:07 UTC

svn commit: r1337360 [4/7] - in /felix/trunk/framework: ./ src/main/java/org/apache/felix/framework/ src/main/java/org/apache/felix/framework/resolver/ src/main/java/org/apache/felix/framework/wiring/ src/main/java/org/osgi/framework/ src/main/java/org...

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceEvent.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). 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,10 +22,9 @@ import java.util.EventObject;
 /**
  * An event from the Framework describing a service lifecycle change.
  * <p>
- * {@code ServiceEvent} objects are delivered to
- * {@code ServiceListener}s and {@code AllServiceListener}s when a
- * change occurs in this service's lifecycle. A type code is used to identify
- * the event type for future extendability.
+ * {@code ServiceEvent} objects are delivered to {@code ServiceListener}s and
+ * {@code AllServiceListener}s when a change occurs in this service's lifecycle.
+ * A type code is used to identify the event type for future extendability.
  * 
  * <p>
  * OSGi Alliance reserves the right to extend the set of types.
@@ -33,20 +32,20 @@ import java.util.EventObject;
  * @Immutable
  * @see ServiceListener
  * @see AllServiceListener
- * @version $Id: 2b9458d90004411b6ca0cb4b361bc282b04c85eb $
+ * @version $Id: 49e34e0ad5564d6f4ca0ab0053b272c22b9fb917 $
  */
 
 public class ServiceEvent extends EventObject {
-	static final long				serialVersionUID	= 8792901483909409299L;
+	static final long					serialVersionUID	= 8792901483909409299L;
 	/**
 	 * Reference to the service that had a change occur in its lifecycle.
 	 */
-	private final ServiceReference< ? >	reference;
+	private final ServiceReference<?>	reference;
 
 	/**
 	 * Type of service lifecycle change.
 	 */
-	private final int				type;
+	private final int					type;
 
 	/**
 	 * This service has been registered.
@@ -56,7 +55,7 @@ public class ServiceEvent extends EventO
 	 * 
 	 * @see BundleContext#registerService(String[],Object,Dictionary)
 	 */
-	public final static int			REGISTERED			= 0x00000001;
+	public final static int				REGISTERED			= 0x00000001;
 
 	/**
 	 * The properties of a registered service have been modified.
@@ -64,9 +63,9 @@ public class ServiceEvent extends EventO
 	 * This event is synchronously delivered <strong>after</strong> the service
 	 * properties have been modified.
 	 * 
-	 * @see ServiceRegistration#setProperties
+	 * @see ServiceRegistration#setProperties(Dictionary)
 	 */
-	public final static int			MODIFIED			= 0x00000002;
+	public final static int				MODIFIED			= 0x00000002;
 
 	/**
 	 * This service is in the process of being unregistered.
@@ -75,16 +74,16 @@ public class ServiceEvent extends EventO
 	 * has completed unregistering.
 	 * 
 	 * <p>
-	 * If a bundle is using a service that is {@code UNREGISTERING}, the
-	 * bundle should release its use of the service when it receives this event.
-	 * If the bundle does not release its use of the service when it receives
-	 * this event, the Framework will automatically release the bundle's use of
-	 * the service while completing the service unregistration operation.
+	 * If a bundle is using a service that is {@code UNREGISTERING}, the bundle
+	 * should release its use of the service when it receives this event. If the
+	 * bundle does not release its use of the service when it receives this
+	 * event, the Framework will automatically release the bundle's use of the
+	 * service while completing the service unregistration operation.
 	 * 
-	 * @see ServiceRegistration#unregister
-	 * @see BundleContext#ungetService
+	 * @see ServiceRegistration#unregister()
+	 * @see BundleContext#ungetService(ServiceReference)
 	 */
-	public final static int			UNREGISTERING		= 0x00000004;
+	public final static int				UNREGISTERING		= 0x00000004;
 
 	/**
 	 * The properties of a registered service have been modified and the new
@@ -92,23 +91,23 @@ public class ServiceEvent extends EventO
 	 * <p>
 	 * This event is synchronously delivered <strong>after</strong> the service
 	 * properties have been modified. This event is only delivered to listeners
-	 * which were added with a non-{@code null} filter where the filter
-	 * matched the service properties prior to the modification but the filter
-	 * does not match the modified service properties.
+	 * which were added with a non-{@code null} filter where the filter matched
+	 * the service properties prior to the modification but the filter does not
+	 * match the modified service properties.
 	 * 
-	 * @see ServiceRegistration#setProperties
+	 * @see ServiceRegistration#setProperties(Dictionary)
 	 * @since 1.5
 	 */
-	public final static int			MODIFIED_ENDMATCH	= 0x00000008;
+	public final static int				MODIFIED_ENDMATCH	= 0x00000008;
 
 	/**
 	 * Creates a new service event object.
 	 * 
 	 * @param type The event type.
-	 * @param reference A {@code ServiceReference} object to the service
-	 * 	that had a lifecycle change.
+	 * @param reference A {@code ServiceReference} object to the service that
+	 *        had a lifecycle change.
 	 */
-	public ServiceEvent(int type, ServiceReference< ? > reference) {
+	public ServiceEvent(int type, ServiceReference<?> reference) {
 		super(reference);
 		this.reference = reference;
 		this.type = type;
@@ -122,17 +121,17 @@ public class ServiceEvent extends EventO
 	 * 
 	 * @return Reference to the service that had a lifecycle change.
 	 */
-	public ServiceReference< ? > getServiceReference() {
+	public ServiceReference<?> getServiceReference() {
 		return reference;
 	}
 
 	/**
 	 * Returns the type of event. The event type values are:
 	 * <ul>
-	 * <li>{@link #REGISTERED} </li> 
-	 * <li>{@link #MODIFIED} </li> 
-	 * <li>{@link #MODIFIED_ENDMATCH} </li> 
-	 * <li>{@link #UNREGISTERING} </li>
+	 * <li>{@link #REGISTERED}</li>
+	 * <li>{@link #MODIFIED}</li>
+	 * <li>{@link #MODIFIED_ENDMATCH}</li>
+	 * <li>{@link #UNREGISTERING}</li>
 	 * </ul>
 	 * 
 	 * @return Type of service lifecycle change.

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceException.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,18 +20,17 @@ package org.osgi.framework;
  * A service exception used to indicate that a service problem occurred.
  * 
  * <p>
- * A {@code ServiceException} object is created by the Framework or
- * service implementation to denote an exception condition in the service. A
- * type code is used to identify the exception type for future extendability.
- * Service implementations may also create subclasses of
- * {@code ServiceException}. When subclassing, the subclass should set
- * the type to {@link #SUBCLASSED} to indicate that
- * {@code ServiceException} has been subclassed.
+ * A {@code ServiceException} object is created by the Framework or service
+ * implementation to denote an exception condition in the service. A type code
+ * is used to identify the exception type for future extendability. Service
+ * implementations may also create subclasses of {@code ServiceException}. When
+ * subclassing, the subclass should set the type to {@link #SUBCLASSED} to
+ * indicate that {@code ServiceException} has been subclassed.
  * 
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Id: 453b6021eed4543f754e20696b9f8b33a7e121ee $
+ * @version $Id: 9f763412635f59585bb615cbc449fc7ab72b7103 $
  * @since 1.5
  */
 
@@ -67,7 +66,7 @@ public class ServiceException extends Ru
 	/**
 	 * An error occurred invoking a remote service.
 	 */
-	public static final int REMOTE 				= 5;
+	public static final int	REMOTE				= 5;
 	/**
 	 * The service factory resulted in a recursive call to itself for the
 	 * requesting bundle.
@@ -97,8 +96,8 @@ public class ServiceException extends Ru
 	}
 
 	/**
-	 * Creates a {@code ServiceException} with the specified message,
-	 * type and exception cause.
+	 * Creates a {@code ServiceException} with the specified message, type and
+	 * exception cause.
 	 * 
 	 * @param msg The associated message.
 	 * @param type The type for this exception.
@@ -110,8 +109,7 @@ public class ServiceException extends Ru
 	}
 
 	/**
-	 * Creates a {@code ServiceException} with the specified message and
-	 * type.
+	 * Creates a {@code ServiceException} with the specified message and type.
 	 * 
 	 * @param msg The message.
 	 * @param type The type for this exception.
@@ -122,8 +120,8 @@ public class ServiceException extends Ru
 	}
 
 	/**
-	 * Returns the type for this exception or {@code UNSPECIFIED} if the
-	 * type was unspecified or unknown.
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the type
+	 * was unspecified or unknown.
 	 * 
 	 * @return The type of this exception.
 	 */

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceFactory.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceFactory.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceFactory.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). 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.
@@ -43,9 +43,9 @@ package org.osgi.framework;
  * concurrently call a {@code ServiceFactory}.
  * 
  * @param <S> Type of Service
- * @see BundleContext#getService
+ * @see BundleContext#getService(ServiceReference)
  * @ThreadSafe
- * @version $Id: 94cd1a0127aaad9beb484f557342a8fbd0be2322 $
+ * @version $Id: 535776e702ec5ace54f577218ff8f7920741558b $
  */
 
 public interface ServiceFactory<S> {
@@ -85,7 +85,7 @@ public interface ServiceFactory<S> {
 	 *        requested service.
 	 * @return A service object that <strong>must</strong> be an instance of all
 	 *         the classes named when the service was registered.
-	 * @see BundleContext#getService
+	 * @see BundleContext#getService(ServiceReference)
 	 */
 	public S getService(Bundle bundle, ServiceRegistration<S> registration);
 
@@ -108,8 +108,7 @@ public interface ServiceFactory<S> {
 	 * @param service The service object returned by a previous call to the
 	 *        {@link #getService(Bundle, ServiceRegistration) getService}
 	 *        method.
-	 * @see BundleContext#ungetService
+	 * @see BundleContext#ungetService(ServiceReference)
 	 */
-	public void ungetService(Bundle bundle, ServiceRegistration<S> registration,
-			S service);
+	public void ungetService(Bundle bundle, ServiceRegistration<S> registration, S service);
 }

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceListener.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceListener.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceListener.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceListener.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). 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.
@@ -19,39 +19,37 @@ package org.osgi.framework;
 import java.util.EventListener;
 
 /**
- * A {@code ServiceEvent} listener. {@code ServiceListener} is a
- * listener interface that may be implemented by a bundle developer. When a
+ * A {@code ServiceEvent} listener. {@code ServiceListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
  * {@code ServiceEvent} is fired, it is synchronously delivered to a
- * {@code ServiceListener}. The Framework may deliver
- * {@code ServiceEvent} objects to a {@code ServiceListener} out
- * of order and may concurrently call and/or reenter a
- * {@code ServiceListener}.
+ * {@code ServiceListener}. The Framework may deliver {@code ServiceEvent}
+ * objects to a {@code ServiceListener} out of order and may concurrently call
+ * and/or reenter a {@code ServiceListener}.
  * 
  * <p>
- * A {@code ServiceListener} object is registered with the Framework
- * using the {@code BundleContext.addServiceListener} method.
- * {@code ServiceListener} objects are called with a
- * {@code ServiceEvent} object when a service is registered, modified, or
- * is in the process of unregistering.
+ * A {@code ServiceListener} object is registered with the Framework using the
+ * {@code BundleContext.addServiceListener} method. {@code ServiceListener}
+ * objects are called with a {@code ServiceEvent} object when a service is
+ * registered, modified, or is in the process of unregistering.
  * 
  * <p>
- * {@code ServiceEvent} object delivery to {@code ServiceListener}
- * objects is filtered by the filter specified when the listener was registered.
- * If the Java Runtime Environment supports permissions, then additional
- * filtering is done. {@code ServiceEvent} objects are only delivered to
- * the listener if the bundle which defines the listener object's class has the
- * appropriate {@code ServicePermission} to get the service using at
- * least one of the named classes under which the service was registered.
+ * {@code ServiceEvent} object delivery to {@code ServiceListener} objects is
+ * filtered by the filter specified when the listener was registered. If the
+ * Java Runtime Environment supports permissions, then additional filtering is
+ * done. {@code ServiceEvent} objects are only delivered to the listener if the
+ * bundle which defines the listener object's class has the appropriate
+ * {@code ServicePermission} to get the service using at least one of the named
+ * classes under which the service was registered.
  * 
  * <p>
- * {@code ServiceEvent} object delivery to {@code ServiceListener}
- * objects is further filtered according to package sources as defined in
+ * {@code ServiceEvent} object delivery to {@code ServiceListener} objects is
+ * further filtered according to package sources as defined in
  * {@link ServiceReference#isAssignableTo(Bundle, String)}.
  * 
  * @see ServiceEvent
  * @see ServicePermission
  * @ThreadSafe
- * @version $Id: d73f8e9b4babc8b53b5d1cbe7b17b732f54bb2a3 $
+ * @version $Id: 601dfda6183ab7f18cd3916958a39734ea141c25 $
  */
 
 public interface ServiceListener extends EventListener {

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServicePermission.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServicePermission.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServicePermission.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServicePermission.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). 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.
@@ -41,66 +41,64 @@ import java.util.Set;
 /**
  * A bundle's authority to register or get a service.
  * <ul>
- * <li>The {@code register} action allows a bundle to register a service on
- * the specified names.
- * <li>The {@code get} action allows a bundle to detect a service and get
- * it.
+ * <li>The {@code register} action allows a bundle to register a service on the
+ * specified names.
+ * <li>The {@code get} 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} to get the specific service.
+ * certain services unless they have the appropriate {@code ServicePermission}
+ * to get the specific service.
  * 
  * @ThreadSafe
- * @version $Id: 1b6ee9543f4cbc16add8dc8c40dfa9a6dfee7aa2 $
+ * @version $Id: 96438ad164d7f0f4273787226298bf8208cf0034 $
  */
 
 public final class ServicePermission extends BasicPermission {
-	static final long			serialVersionUID	= -7662148639076511574L;
+	static final long								serialVersionUID	= -7662148639076511574L;
 	/**
 	 * The action string {@code get}.
 	 */
-	public final static String	GET					= "get";
+	public final static String						GET					= "get";
 	/**
 	 * The action string {@code register}.
 	 */
-	public final static String	REGISTER			= "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;
-	final static int						ACTION_NONE			= 0;
+	private final static int						ACTION_GET			= 0x00000001;
+	private final static int						ACTION_REGISTER		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_GET | ACTION_REGISTER;
+	final static int								ACTION_NONE			= 0;
 
 	/**
 	 * The actions mask.
 	 */
-	transient int							action_mask;
+	transient int									action_mask;
 
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private volatile String		actions				= null;
+	private volatile String							actions				= null;
 
 	/**
 	 * The service used by this ServicePermission. Must be null if not
 	 * constructed with a service.
 	 */
-	transient final ServiceReference< ? >					service;
+	transient final ServiceReference<?>				service;
 
 	/**
 	 * The object classes for this ServicePermission. Must be null if not
 	 * constructed with a service.
 	 */
-	transient final String[]				objectClass;
+	transient final String[]						objectClass;
 
 	/**
 	 * If this ServicePermission was constructed with a filter, this holds a
 	 * Filter matching object used to evaluate the filter in implies.
 	 */
-	transient Filter						filter;
+	transient Filter								filter;
 
 	/**
 	 * This map holds the properties of the permission, used to match a filter
@@ -112,13 +110,13 @@ public final class ServicePermission ext
 	/**
 	 * True if constructed with a name and the name is "*" or ends with ".*".
 	 */
-	private transient boolean				wildcard;
+	private transient boolean						wildcard;
 
 	/**
 	 * If constructed with a name and the name ends with ".*", this contains the
 	 * name without the final "*".
 	 */
-	private transient String				prefix;
+	private transient String						prefix;
 
 	/**
 	 * Create a new ServicePermission.
@@ -139,9 +137,9 @@ public final class ServicePermission ext
 	 * *
 	 * </pre>
 	 * 
-	 * For the {@code get} action, the name can also be a filter
-	 * expression. The filter gives access to the service properties as well as
-	 * the following attributes:
+	 * For the {@code get} action, the name can also be a filter expression. The
+	 * filter gives access to the service properties as well as the following
+	 * attributes:
 	 * <ul>
 	 * <li>signer - A Distinguished Name chain used to sign the bundle
 	 * publishing the service. Wildcards in a DN are not matched according to
@@ -159,33 +157,29 @@ public final class ServicePermission ext
 	 * Service properties names are case insensitive.
 	 * 
 	 * <p>
-	 * There are two possible actions: {@code get} and
-	 * {@code register}. The {@code get} permission allows the owner
-	 * of this permission to obtain a service with this name. The
-	 * {@code register} permission allows the bundle to register a service
-	 * under that name.
+	 * There are two possible actions: {@code get} and {@code register}. The
+	 * {@code get} permission allows the owner of this permission to obtain a
+	 * service with this name. The {@code register} permission allows the bundle
+	 * to register a service under that name.
 	 * 
 	 * @param name The service class name
 	 * @param actions {@code get},{@code register} (canonical order)
 	 * @throws IllegalArgumentException If the specified name is a filter
-	 *         expression and either the specified action is not
-	 *         {@code get} or the filter has an invalid syntax.
+	 *         expression and either the specified action is not {@code get} or
+	 *         the filter has an invalid syntax.
 	 */
 	public ServicePermission(String name, String actions) {
 		this(name, parseActions(actions));
-		if ((filter != null)
-				&& ((action_mask & ACTION_ALL) != ACTION_GET)) {
-			throw new IllegalArgumentException(
-					"invalid action string for filter expression");
+		if ((filter != null) && ((action_mask & ACTION_ALL) != ACTION_GET)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
 		}
 	}
 
 	/**
-	 * Creates a new requested {@code ServicePermission} object to be used
-	 * by code that must perform {@code checkPermission} for the
-	 * {@code get} action. {@code ServicePermission} objects created
-	 * with this constructor cannot be added to a {@code ServicePermission}
-	 * permission collection.
+	 * Creates a new requested {@code ServicePermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code get}
+	 * action. {@code ServicePermission} objects created with this constructor
+	 * cannot be added to a {@code ServicePermission} permission collection.
 	 * 
 	 * @param reference The requested service.
 	 * @param actions The action {@code get}.
@@ -193,12 +187,11 @@ public final class ServicePermission ext
 	 *         {@code get} or reference is {@code null}.
 	 * @since 1.5
 	 */
-	public ServicePermission(ServiceReference< ? > reference, String actions) {
+	public ServicePermission(ServiceReference<?> reference, String actions) {
 		super(createName(reference));
 		setTransients(null, parseActions(actions));
 		this.service = reference;
-		this.objectClass = (String[]) reference
-				.getProperty(Constants.OBJECTCLASS);
+		this.objectClass = (String[]) reference.getProperty(Constants.OBJECTCLASS);
 		if ((action_mask & ACTION_ALL) != ACTION_GET) {
 			throw new IllegalArgumentException("invalid action string");
 		}
@@ -210,7 +203,7 @@ public final class ServicePermission ext
 	 * @param reference ServiceReference to use to create permission name.
 	 * @return permission name.
 	 */
-	private static String createName(ServiceReference< ? > reference) {
+	private static String createName(ServiceReference<?> reference) {
 		if (reference == null) {
 			throw new IllegalArgumentException("reference must not be null");
 		}
@@ -248,8 +241,7 @@ public final class ServicePermission ext
 			String name = getName();
 			int l = name.length();
 			/* if "*" or endsWith ".*" */
-			wildcard = ((name.charAt(l - 1) == '*') && ((l == 1) || (name
-					.charAt(l - 2) == '.')));
+			wildcard = ((name.charAt(l - 1) == '*') && ((l == 1) || (name.charAt(l - 2) == '.')));
 			if (wildcard && (l > 1)) {
 				prefix = name.substring(0, l - 1);
 			}
@@ -281,9 +273,7 @@ public final class ServicePermission ext
 			char c;
 
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
 
 			// check for the known strings
@@ -295,8 +285,7 @@ public final class ServicePermission ext
 				matchlen = 3;
 				mask |= ACTION_GET;
 
-			}
-			else
+			} 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')
@@ -308,11 +297,9 @@ public final class ServicePermission ext
 					matchlen = 8;
 					mask |= ACTION_REGISTER;
 
-				}
-				else {
+				} else {
 					// parse error
-					throw new IllegalArgumentException("invalid permission: "
-							+ actions);
+					throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 
 			// make sure we didn't just match the tail of a word
@@ -322,7 +309,7 @@ public final class ServicePermission ext
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -330,8 +317,7 @@ public final class ServicePermission ext
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -363,18 +349,16 @@ public final class ServicePermission ext
 
 		try {
 			return FrameworkUtil.createFilter(filterString);
-		}
-		catch (InvalidSyntaxException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid filter");
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
 			iae.initCause(e);
 			throw iae;
 		}
 	}
 
 	/**
-	 * Determines if a {@code ServicePermission} object "implies" the
-	 * specified permission.
+	 * Determines if a {@code ServicePermission} object "implies" the specified
+	 * permission.
 	 * 
 	 * @param p The target permission to check.
 	 * @return {@code true} if the specified permission is implied by this
@@ -432,13 +416,11 @@ public final class ServicePermission ext
 			int pl = prefix.length();
 			for (int i = 0, l = requestedNames.length; i < l; i++) {
 				String requestedName = requestedNames[i];
-				if ((requestedName.length() > pl)
-						&& requestedName.startsWith(prefix)) {
+				if ((requestedName.length() > pl) && requestedName.startsWith(prefix)) {
 					return true;
 				}
 			}
-		}
-		else {
+		} else {
 			String name = getName();
 			for (int i = 0, l = requestedNames.length; i < l; i++) {
 				if (requestedNames[i].equals(name)) {
@@ -499,8 +481,8 @@ public final class ServicePermission ext
 	 * 
 	 * @param obj The object to test for equality.
 	 * @return true if obj is a {@code ServicePermission}, and has the same
-	 *         class name and actions as this {@code ServicePermission}
-	 *         object; {@code false} otherwise.
+	 *         class name and actions as this {@code ServicePermission} object;
+	 *         {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -513,10 +495,7 @@ public final class ServicePermission ext
 
 		ServicePermission sp = (ServicePermission) obj;
 
-		return (action_mask == sp.action_mask)
-				&& getName().equals(sp.getName())
-				&& ((service == sp.service) || ((service != null) && (service
-						.compareTo(sp.service) == 0)));
+		return (action_mask == sp.action_mask) && getName().equals(sp.getName()) && ((service == sp.service) || ((service != null) && (service.compareTo(sp.service) == 0)));
 	}
 
 	/**
@@ -537,8 +516,7 @@ public final class ServicePermission ext
 	 * 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 {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		if (service != null) {
 			throw new NotSerializableException("cannot serialize");
 		}
@@ -553,8 +531,7 @@ public final class ServicePermission ext
 	 * readObject is called to restore the state of this permission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
 		setTransients(parseFilter(getName()), parseActions(actions));
@@ -598,13 +575,13 @@ public final class ServicePermission ext
 		}
 		return properties = new Properties(props, service);
 	}
-	
+
 	static private final class Properties extends AbstractMap<String, Object> {
-		private final Map<String, Object>	properties;
-		private final ServiceReference< ? >	service;
+		private final Map<String, Object>							properties;
+		private final ServiceReference<?>							service;
 		private transient volatile Set<Map.Entry<String, Object>>	entries;
 
-		Properties(Map<String, Object> properties, ServiceReference< ? > service) {
+		Properties(Map<String, Object> properties, ServiceReference<?> service) {
 			this.properties = properties;
 			this.service = service;
 			entries = null;
@@ -629,8 +606,7 @@ public final class ServicePermission ext
 			if (entries != null) {
 				return entries;
 			}
-			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
-					properties.entrySet());
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(properties.entrySet());
 			add: for (String key : service.getPropertyKeys()) {
 				for (String k : properties.keySet()) {
 					if (key.equalsIgnoreCase(k)) {
@@ -641,7 +617,7 @@ public final class ServicePermission ext
 			}
 			return entries = Collections.unmodifiableSet(all);
 		}
-		
+
 		static private final class Entry implements Map.Entry<String, Object> {
 			private final String	k;
 			private final Object	v;
@@ -650,22 +626,27 @@ public final class ServicePermission ext
 				this.k = key;
 				this.v = value;
 			}
+
 			public String getKey() {
 				return k;
 			}
+
 			public Object getValue() {
 				return v;
 			}
+
 			public Object setValue(Object value) {
 				throw new UnsupportedOperationException();
 			}
+
 			public String toString() {
 				return k + "=" + v;
 			}
+
 			public int hashCode() {
-				return ((k == null) ? 0 : k.hashCode())
-						^ ((v == null) ? 0 : v.hashCode());
+				return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
 			}
+
 			public boolean equals(Object obj) {
 				if (obj == this) {
 					return true;
@@ -673,7 +654,7 @@ public final class ServicePermission ext
 				if (!(obj instanceof Map.Entry)) {
 					return false;
 				}
-				Map.Entry< ? , ? > e = (Map.Entry< ? , ? >) obj;
+				Map.Entry<?, ?> e = (Map.Entry<?, ?>) obj;
 				final Object key = e.getKey();
 				if ((k == key) || ((k != null) && k.equals(key))) {
 					final Object value = e.getValue();
@@ -695,7 +676,7 @@ public final class ServicePermission ext
  * @see java.security.PermissionCollection
  */
 final class ServicePermissionCollection extends PermissionCollection {
-	static final long	serialVersionUID	= 662615640374640621L;
+	static final long									serialVersionUID	= 662615640374640621L;
 	/**
 	 * Table of permissions.
 	 * 
@@ -709,7 +690,7 @@ final class ServicePermissionCollection 
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private boolean		all_allowed;
+	private boolean										all_allowed;
 
 	/**
 	 * Table of permissions with filter expressions.
@@ -733,26 +714,22 @@ final class ServicePermissionCollection 
 	 * @param permission The Permission object to add.
 	 * @throws IllegalArgumentException If the specified permission is not a
 	 *         ServicePermission object.
-	 * @throws SecurityException If this
-	 *         {@code ServicePermissionCollection} object has been marked
-	 *         read-only.
+	 * @throws SecurityException If this {@code ServicePermissionCollection}
+	 *         object has been marked read-only.
 	 */
 	public void add(final Permission permission) {
 		if (!(permission instanceof ServicePermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 
 		final ServicePermission sp = (ServicePermission) permission;
 		if (sp.service != null) {
-			throw new IllegalArgumentException("cannot add to collection: "
-					+ sp);
+			throw new IllegalArgumentException("cannot add to collection: " + sp);
 		}
-		
+
 		final String name = sp.getName();
 		final Filter f = sp.filter;
 		synchronized (this) {
@@ -763,25 +740,21 @@ final class ServicePermissionCollection 
 				if (pc == null) {
 					filterPermissions = pc = new HashMap<String, ServicePermission>();
 				}
-			}
-			else {
+			} else {
 				pc = permissions;
 			}
 			final ServicePermission existing = pc.get(name);
-			
+
 			if (existing != null) {
 				final int oldMask = existing.action_mask;
 				final int newMask = sp.action_mask;
 				if (oldMask != newMask) {
-					pc
-							.put(name, new ServicePermission(name, oldMask
-							| newMask));
+					pc.put(name, new ServicePermission(name, oldMask | newMask));
 				}
-			}
-			else {
+			} else {
 				pc.put(name, sp);
 			}
-			
+
 			if (!all_allowed) {
 				if (name.equals("*")) {
 					all_allowed = true;
@@ -795,9 +768,8 @@ final class ServicePermissionCollection 
 	 * {@code permission}.
 	 * 
 	 * @param permission The Permission object to compare.
-	 * @return {@code true} if {@code permission} is a proper
-	 *         subset of a permission in the set; {@code false}
-	 *         otherwise.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
 	 */
 	public boolean implies(final Permission permission) {
 		if (!(permission instanceof ServicePermission)) {
@@ -823,7 +795,7 @@ final class ServicePermissionCollection 
 					}
 				}
 			}
-			
+
 			String[] requestedNames = requested.objectClass;
 			/* if requested permission not created with ServiceReference */
 			if (requestedNames == null) {
@@ -846,7 +818,7 @@ final class ServicePermissionCollection 
 			}
 			perms = pc.values();
 		}
-		
+
 		/* iterate one by one over filteredPermissions */
 		for (ServicePermission perm : perms) {
 			if (perm.implies0(requested, effective)) {
@@ -865,8 +837,7 @@ final class ServicePermissionCollection 
 	 * @param effective The effective actions.
 	 * @return The new effective actions.
 	 */
-	private int effective(String requestedName, final int desired,
-			int effective) {
+	private int effective(String requestedName, final int desired, int effective) {
 		final Map<String, ServicePermission> pc = permissions;
 		ServicePermission sp = pc.get(requestedName);
 		// strategy:
@@ -899,10 +870,10 @@ final class ServicePermissionCollection 
 		 */
 		return effective;
 	}
-	
+
 	/**
-	 * Returns an enumeration of all the {@code ServicePermission}
-	 * objects in the container.
+	 * Returns an enumeration of all the {@code ServicePermission} objects in
+	 * the container.
 	 * 
 	 * @return Enumeration of all the ServicePermission objects.
 	 */
@@ -914,17 +885,13 @@ final class ServicePermissionCollection 
 		}
 		return Collections.enumeration(all);
 	}
-	
+
 	/* serialization logic */
-	private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", Hashtable.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE),
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
 			new ObjectStreamField("filterPermissions", HashMap.class)	};
 
-	private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
-		Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(
-				permissions);
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
@@ -932,15 +899,12 @@ final class ServicePermissionCollection 
 		out.writeFields();
 	}
 
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields
-				.get("permissions", null);
+		Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields.get("permissions", null);
 		permissions = new HashMap<String, ServicePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
-		HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields
-				.get("filterPermissions", null);
+		HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields.get("filterPermissions", null);
 		filterPermissions = fp;
 	}
 }

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceReference.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceReference.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceReference.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceReference.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). 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.
@@ -26,36 +26,36 @@ import java.util.Dictionary;
  * {@code BundleContext.getServiceReference} and
  * {@code BundleContext.getServiceReferences} methods.
  * <p>
- * A {@code ServiceReference} object may be shared between bundles and can
- * be used to examine the properties of the service and to get the service
- * object.
+ * A {@code ServiceReference} 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} object and may have multiple, distinct
- * {@code ServiceReference} objects referring to it.
- * {@code ServiceReference} objects associated with a
- * {@code ServiceRegistration} object have the same {@code hashCode}
- * and are considered equal (more specifically, their {@code equals()}
- * method will return {@code true} when compared).
+ * {@code ServiceReference} objects referring to it. {@code ServiceReference}
+ * objects associated with a {@code ServiceRegistration} object have the same
+ * {@code hashCode} and are considered equal (more specifically, their
+ * {@code equals()} method will return {@code true} when compared).
  * <p>
  * If the same service object is registered multiple times,
  * {@code ServiceReference} objects associated with different
  * {@code ServiceRegistration} objects are not equal.
  * 
  * @param <S> Type of Service.
- * @see BundleContext#getServiceReference
- * @see BundleContext#getServiceReferences
- * @see BundleContext#getService
+ * @see BundleContext#getServiceReference(Class)
+ * @see BundleContext#getServiceReference(String)
+ * @see BundleContext#getServiceReferences(Class, String)
+ * @see BundleContext#getServiceReferences(String, String)
+ * @see BundleContext#getService(ServiceReference)
  * @ThreadSafe
  * @noimplement
- * @version $Id: 771b9b4d4f65dbe593154d02912edba51a085b0c $
+ * @version $Id: 75352193f9f11a2c19692890153c6ff91611023b $
  */
 
 public interface ServiceReference<S> extends Comparable<Object> {
 	/**
 	 * Returns the property value to which the specified property key is mapped
-	 * in the properties {@code Dictionary} object of the service
-	 * referenced by this {@code ServiceReference} object.
+	 * in the properties {@code Dictionary} object of the service referenced by
+	 * this {@code ServiceReference} object.
 	 * 
 	 * <p>
 	 * Property keys are case-insensitive.
@@ -63,32 +63,31 @@ public interface ServiceReference<S> ext
 	 * <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} objects stored in the log) can
-	 * still be interrogated.
+	 * example, {@code ServiceReference} 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}
-	 *         if there is no property named after the key.
+	 * @return The property value to which the key is mapped; {@code null} 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}
-	 * object of the service referenced by this {@code ServiceReference}
-	 * object.
+	 * Returns an array of the keys in the properties {@code Dictionary} object
+	 * of the service referenced by this {@code ServiceReference} 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} objects stored in the log) can
-	 * still be interrogated.
+	 * example, {@code ServiceReference} 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} that was passed to the
 	 * {@link BundleContext#registerService(String[],Object,Dictionary)} or
-	 * {@link ServiceRegistration#setProperties} methods.
+	 * {@link ServiceRegistration#setProperties(Dictionary)} methods.
 	 * 
 	 * @return An array of property keys.
 	 */
@@ -104,21 +103,20 @@ public interface ServiceReference<S> ext
 	 * unregistered.
 	 * 
 	 * @return The bundle that registered the service referenced by this
-	 *         {@code ServiceReference} object; {@code null} if that
-	 *         service has already been unregistered.
+	 *         {@code ServiceReference} object; {@code null} if that service has
+	 *         already been unregistered.
 	 * @see BundleContext#registerService(String[],Object,Dictionary)
 	 */
 	public Bundle getBundle();
 
 	/**
 	 * Returns the bundles that are using the service referenced by this
-	 * {@code ServiceReference} object. Specifically, this method returns
-	 * the bundles whose usage count for that service is greater than zero.
+	 * {@code ServiceReference} 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} object is greater than
-	 *         zero; {@code null} if no bundles are currently using that
-	 *         service.
+	 *         by this {@code ServiceReference} object is greater than zero;
+	 *         {@code null} if no bundles are currently using that service.
 	 * 
 	 * @since 1.1
 	 */
@@ -126,17 +124,16 @@ public interface ServiceReference<S> ext
 
 	/**
 	 * Tests if the bundle that registered the service referenced by this
-	 * {@code ServiceReference} and the specified bundle use the same
-	 * source for the package of the specified class name.
+	 * {@code ServiceReference} 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} (registrant bundle); find the source for
-	 * the package. If no source is found then return {@code true} if the
-	 * registrant bundle is equal to the specified bundle; otherwise return
-	 * {@code false}.</li>
+	 * {@code ServiceReference} (registrant bundle); find the source for the
+	 * package. If no source is found then return {@code true} if the registrant
+	 * bundle is equal to the specified bundle; otherwise return {@code false}.</li>
 	 * <li>If the package source of the registrant bundle is equal to the
 	 * package source of the specified bundle then return {@code true};
 	 * otherwise return {@code false}.</li>
@@ -145,11 +142,11 @@ public interface ServiceReference<S> ext
 	 * @param bundle The {@code Bundle} object to check.
 	 * @param className The class name to check.
 	 * @return {@code true} if the bundle which registered the service
-	 *         referenced by this {@code ServiceReference} and the
-	 *         specified bundle use the same source for the package of the
-	 *         specified class name. Otherwise {@code false} is returned.
-	 * @throws IllegalArgumentException If the specified {@code Bundle} was
-	 *         not created by the same framework instance as this
+	 *         referenced by this {@code ServiceReference} and the specified
+	 *         bundle use the same source for the package of the specified class
+	 *         name. Otherwise {@code false} is returned.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was not
+	 *         created by the same framework instance as this
 	 *         {@code ServiceReference}.
 	 * @since 1.3
 	 */
@@ -162,24 +159,23 @@ public interface ServiceReference<S> ext
 	 * <p>
 	 * If this {@code ServiceReference} and the specified
 	 * {@code ServiceReference} have the same {@link Constants#SERVICE_ID
-	 * service id} they are equal. This {@code ServiceReference} is less
-	 * than the specified {@code ServiceReference} if it has a lower
+	 * service id} they are equal. This {@code ServiceReference} is less than
+	 * the specified {@code ServiceReference} if it has a lower
 	 * {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
-	 * higher service ranking. Otherwise, if this {@code ServiceReference}
-	 * and the specified {@code ServiceReference} have the same
+	 * higher service ranking. Otherwise, if this {@code ServiceReference} and
+	 * the specified {@code ServiceReference} have the same
 	 * {@link Constants#SERVICE_RANKING service ranking}, this
 	 * {@code ServiceReference} is less than the specified
-	 * {@code ServiceReference} if it has a higher
-	 * {@link Constants#SERVICE_ID service id} and greater if it has a lower
-	 * service id.
+	 * {@code ServiceReference} if it has a higher {@link Constants#SERVICE_ID
+	 * service id} and greater if it has a lower service id.
 	 * 
 	 * @param reference The {@code ServiceReference} to be compared.
 	 * @return Returns a negative integer, zero, or a positive integer if this
-	 *         {@code ServiceReference} is less than, equal to, or greater
-	 *         than the specified {@code ServiceReference}.
+	 *         {@code ServiceReference} is less than, equal to, or greater than
+	 *         the specified {@code ServiceReference}.
 	 * @throws IllegalArgumentException If the specified
-	 *         {@code ServiceReference} was not created by the same
-	 *         framework instance as this {@code ServiceReference}.
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code ServiceReference}.
 	 * @since 1.4
 	 */
 	public int compareTo(Object reference);

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/ServiceRegistration.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/ServiceRegistration.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/ServiceRegistration.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). 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.
@@ -23,31 +23,28 @@ import java.util.Dictionary;
  * 
  * <p>
  * The Framework returns a {@code ServiceRegistration} object when a
- * {@code BundleContext.registerService} method invocation is successful.
- * The {@code ServiceRegistration} object is for the private use of the
- * registering bundle and should not be shared with other bundles.
+ * {@code BundleContext.registerService} method invocation is successful. The
+ * {@code ServiceRegistration} object is for the private use of the registering
+ * bundle and should not be shared with other bundles.
  * <p>
- * The {@code ServiceRegistration} object may be used to update the
- * properties of the service or to unregister the service.
+ * The {@code ServiceRegistration} object may be used to update the properties
+ * of the service or to unregister the service.
  * 
  * @param <S> Type of Service.
  * @see BundleContext#registerService(String[],Object,Dictionary)
  * @ThreadSafe
  * @noimplement
- * @version $Id: dc742ff3749821529f9ae62e05d9bd5d8eca00d7 $
+ * @version $Id: a84248da0db0538708d2394a9478153e06b8afb9 $
  */
 
 public interface ServiceRegistration<S> {
 	/**
-	 * Returns a {@code ServiceReference} object for a service being
-	 * registered.
+	 * Returns a {@code ServiceReference} object for a service being registered.
 	 * <p>
-	 * The {@code ServiceReference} object may be shared with other
-	 * bundles.
+	 * The {@code ServiceReference} object may be shared with other bundles.
 	 * 
-	 * @throws IllegalStateException If this
-	 *         {@code ServiceRegistration} object has already been
-	 *         unregistered.
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
 	 * @return {@code ServiceReference} object.
 	 */
 	public ServiceReference<S> getReference();
@@ -72,43 +69,41 @@ public interface ServiceRegistration<S> 
 	 *        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}
-	 *         object has already been unregistered.
-	 * @throws IllegalArgumentException If {@code properties} contains
-	 *         case variants of the same key name.
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @throws IllegalArgumentException If {@code properties} contains case
+	 *         variants of the same key name.
 	 */
-	public void setProperties(Dictionary<String, ? > properties);
+	public void setProperties(Dictionary<String, ?> properties);
 
 	/**
-	 * Unregisters a service. Remove a {@code ServiceRegistration} object
-	 * from the Framework service registry. All {@code ServiceReference}
-	 * objects associated with this {@code ServiceRegistration} object
-	 * can no longer be used to interact with the service once unregistration is
-	 * complete.
+	 * Unregisters a service. Remove a {@code ServiceRegistration} object from
+	 * the Framework service registry. All {@code ServiceReference} objects
+	 * associated with this {@code ServiceRegistration} object can no longer be
+	 * used to interact with the service once unregistration is complete.
 	 * 
 	 * <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 obtained.
+	 * <li>The service is removed from the Framework service registry so that it
+	 * can no longer be obtained.
 	 * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is fired
 	 * so that bundles using this service can release their use of the service.
 	 * Once delivery of the service event is complete, the
-	 * {@code ServiceReference} objects for the service may no longer be
-	 * used to get a service object for the service.
+	 * {@code ServiceReference} objects for the service may no longer be used to
+	 * get a service object for the service.
 	 * <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} method is called to release
-	 * the service object for the bundle.
+	 * {@code ServiceFactory.ungetService} method is called to release the
+	 * service object for the bundle.
 	 * </ol>
 	 * 
-	 * @throws IllegalStateException If this
-	 *         {@code ServiceRegistration} object has already been
-	 *         unregistered.
-	 * @see BundleContext#ungetService
-	 * @see ServiceFactory#ungetService
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @see BundleContext#ungetService(ServiceReference)
+	 * @see ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)
 	 */
 	public void unregister();
 }

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/SignerProperty.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/SignerProperty.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/SignerProperty.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/SignerProperty.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2012). 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.
@@ -26,7 +26,7 @@ import java.util.Map;
  * during filter expression evaluation in the permission implies method.
  * 
  * @Immutable
- * @version $Id: 3589831a7594cf36e645a51ab9b9ae5ebfd80beb $
+ * @version $Id: 94eea19050b84907f1257d7a12ebf8ab404f4473 $
  */
 final class SignerProperty {
 	private final Bundle	bundle;
@@ -70,20 +70,17 @@ final class SignerProperty {
 		SignerProperty other = (SignerProperty) o;
 		Bundle matchBundle = bundle != null ? bundle : other.bundle;
 		String matchPattern = bundle != null ? other.pattern : pattern;
-		Map<X509Certificate, List<X509Certificate>> signers = matchBundle
-				.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		Map<X509Certificate, List<X509Certificate>> signers = matchBundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
 		for (List<X509Certificate> signerCerts : signers.values()) {
 			List<String> dnChain = new ArrayList<String>(signerCerts.size());
 			for (X509Certificate signerCert : signerCerts) {
 				dnChain.add(signerCert.getSubjectDN().getName());
 			}
 			try {
-				if (FrameworkUtil.matchDistinguishedNameChain(matchPattern,
-						dnChain)) {
+				if (FrameworkUtil.matchDistinguishedNameChain(matchPattern, dnChain)) {
 					return true;
 				}
-			}
-			catch (IllegalArgumentException e) {
+			} catch (IllegalArgumentException e) {
 				continue; // bad pattern
 			}
 		}
@@ -107,8 +104,7 @@ final class SignerProperty {
 		if (bundle == null) {
 			return false;
 		}
-		Map<X509Certificate, List<X509Certificate>> signers = bundle
-				.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		Map<X509Certificate, List<X509Certificate>> signers = bundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
 		return !signers.isEmpty();
 	}
 }

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java Fri May 11 20:19:02 2012
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2011). 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,38 +17,37 @@
 package org.osgi.framework;
 
 /**
- * A synchronous {@code BundleEvent} listener.
- * {@code SynchronousBundleListener} is a listener interface that may be
- * implemented by a bundle developer. When a {@code BundleEvent} is fired,
- * it is synchronously delivered to a {@code SynchronousBundleListener}.
- * The Framework may deliver {@code BundleEvent} objects to a
- * {@code SynchronousBundleListener} out of order and may concurrently call
- * and/or reenter a {@code SynchronousBundleListener}.
+ * A synchronous {@code BundleEvent} listener. {@code SynchronousBundleListener}
+ * is a listener interface that may be implemented by a bundle developer. When a
+ * {@code BundleEvent} is fired, it is synchronously delivered to a
+ * {@code SynchronousBundleListener}. The Framework may deliver
+ * {@code BundleEvent} objects to a {@code SynchronousBundleListener} out of
+ * order and may concurrently call and/or reenter a
+ * {@code SynchronousBundleListener}.
  * 
  * <p>
  * For {@code BundleEvent} types {@link BundleEvent#STARTED STARTED} and
  * {@link BundleEvent#LAZY_ACTIVATION LAZY_ACTIVATION}, the Framework must not
  * hold the referenced bundle's &quot;state change&quot; lock when the
- * {@code BundleEvent} is delivered to a
- * {@code SynchronousBundleListener}. For the other
- * {@code BundleEvent} types, the Framework must hold the referenced
+ * {@code BundleEvent} is delivered to a {@code SynchronousBundleListener}. For
+ * the other {@code BundleEvent} types, the Framework must hold the referenced
  * bundle's &quot;state change&quot; lock when the {@code BundleEvent} is
  * delivered to a {@code SynchronousBundleListener}. A
- * {@code SynchronousBundleListener} cannot directly call life cycle
- * methods on the referenced bundle when the Framework is holding the referenced
- * bundle's &quot;state change&quot; lock.
+ * {@code SynchronousBundleListener} cannot directly call life cycle methods on
+ * the referenced bundle when the Framework is holding the referenced bundle's
+ * &quot;state change&quot; lock.
  * 
  * <p>
- * A {@code SynchronousBundleListener} object is registered with the
- * Framework using the {@link BundleContext#addBundleListener} method.
+ * A {@code SynchronousBundleListener} object is registered with the Framework
+ * using the {@link BundleContext#addBundleListener(BundleListener)} method.
  * {@code SynchronousBundleListener} objects are called with a
  * {@code BundleEvent} object when a bundle has been installed, resolved,
  * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
  * <p>
  * Unlike normal {@code BundleListener} objects,
- * {@code SynchronousBundleListener}s are synchronously called during
- * bundle lifecycle processing. The bundle lifecycle processing will not proceed
- * until all {@code SynchronousBundleListener}s have completed.
+ * {@code SynchronousBundleListener}s are synchronously called during bundle
+ * lifecycle processing. The bundle lifecycle processing will not proceed until
+ * all {@code SynchronousBundleListener}s have completed.
  * {@code SynchronousBundleListener} objects will be called prior to
  * {@code BundleListener} objects.
  * <p>
@@ -58,7 +57,7 @@ package org.osgi.framework;
  * @since 1.1
  * @see BundleEvent
  * @ThreadSafe
- * @version $Id: b22484f48ebdcb2141da9bba9eb65f5c40e0f520 $
+ * @version $Id: 74246f4ceeba7f9a5ee198048522f93d4691c51a $
  */
 
 public interface SynchronousBundleListener extends BundleListener {

Added: felix/trunk/framework/src/main/java/org/osgi/framework/UnfilteredServiceListener.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/UnfilteredServiceListener.java?rev=1337360&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/UnfilteredServiceListener.java (added)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/UnfilteredServiceListener.java Fri May 11 20:19:02 2012
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). 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 org.osgi.framework.hooks.service.ListenerHook;
+
+/**
+ * A {@code ServiceEvent} listener that does <i>not</i> filter based upon any
+ * filter string specified to
+ * {@link BundleContext#addServiceListener(ServiceListener, String)}. Using an
+ * {@code UnfilteredServiceListener} and specifying a filter string to
+ * {@link BundleContext#addServiceListener(ServiceListener, String)} allows the
+ * listener to receive all {@code ServiceEvent} objects while still advising
+ * {@link ListenerHook} implementation of the service interests in the filter
+ * string.
+ * 
+ * For example, an implementation of Declarative Services would add an
+ * {@code UnfilteredServiceListener} with a filter string listing all the
+ * services referenced by all the service components. The Declarative Services
+ * implementation would receive all {@code ServiceEvent} objects for internal
+ * processing and a Remote Services discovery service implementation can observe
+ * the service interests of the service components using a {@link ListenerHook}.
+ * When the set of service components being processed changes, the Declarative
+ * Services implementation would re-add the {@code UnfilteredServiceListener}
+ * with an updated filter string.
+ * 
+ * <p>
+ * When a {@code ServiceEvent} is fired, it is synchronously delivered to an
+ * {@code UnfilteredServiceListener}. The Framework may deliver
+ * {@code ServiceEvent} objects to an {@code UnfilteredServiceListener} out of
+ * order and may concurrently call and/or reenter an
+ * {@code UnfilteredServiceListener}.
+ * 
+ * <p>
+ * An {@code UnfilteredServiceListener} object is registered with the Framework
+ * using the {@code BundleContext.addServiceListener} method.
+ * {@code UnfilteredServiceListener} objects are called with a
+ * {@code ServiceEvent} object when a service is registered, modified, or is in
+ * the process of unregistering.
+ * 
+ * <p>
+ * {@code ServiceEvent} object delivery to {@code UnfilteredServiceListener}
+ * objects are <i>not</i> filtered by the filter specified when the listener was
+ * registered. If the Java Runtime Environment supports permissions, then some
+ * filtering is done. {@code ServiceEvent} objects are only delivered to the
+ * listener if the bundle which defines the listener object's class has the
+ * appropriate {@code ServicePermission} to get the service using at least one
+ * of the named classes under which the service was registered.
+ * 
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @ThreadSafe
+ * @since 1.7
+ * @version $Id: 543a345802f8dc7a49d29e8fb7aee7004ee2b329 $
+ */
+
+public interface UnfilteredServiceListener extends ServiceListener {
+	// This is a marker interface
+}

Modified: felix/trunk/framework/src/main/java/org/osgi/framework/Version.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/osgi/framework/Version.java?rev=1337360&r1=1337359&r2=1337360&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/osgi/framework/Version.java (original)
+++ felix/trunk/framework/src/main/java/org/osgi/framework/Version.java Fri May 11 20:19:02 2012
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2004, 2012). 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
@@ -20,7 +20,7 @@ import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
 
 /**
- * Version identifier for bundles and packages.
+ * Version identifier for capabilities such as bundles and packages.
  * 
  * <p>
  * Version identifiers have four components.
@@ -28,8 +28,8 @@ import java.util.StringTokenizer;
  * <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)} for the
- * format of the qualifier string.</li>
+ * <li>Qualifier. A text string. See {@code Version(String)} for the format of
+ * the qualifier string.</li>
  * </ol>
  * 
  * <p>
@@ -37,7 +37,7 @@ import java.util.StringTokenizer;
  * 
  * @since 1.3
  * @Immutable
- * @version $Id: a71e2e2d7685e65b5bbe375efdf97fda16eff0a5 $
+ * @version $Id: a0b5a865f7fbf2b3dcb77a13b2e99da0b64702bb $
  */
 
 public class Version implements Comparable<Version> {
@@ -46,7 +46,8 @@ public class Version implements Comparab
 	private final int			micro;
 	private final String		qualifier;
 	private static final String	SEPARATOR		= ".";
-	private transient String	versionString;
+	private transient String	versionString /* default to null */;
+	private transient int		hash /* default to 0 */;
 
 	/**
 	 * The empty version "0.0.0".
@@ -76,8 +77,8 @@ public class Version implements Comparab
 	 * @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} is specified, then the qualifier will be set to
-	 *        the empty string.
+	 *        {@code null} 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.
 	 */
@@ -90,15 +91,14 @@ public class Version implements Comparab
 		this.minor = minor;
 		this.micro = micro;
 		this.qualifier = qualifier;
-		versionString = null;
 		validate();
 	}
 
 	/**
-	 * Created a version identifier from the specified string.
+	 * Creates a version identifier from the specified string.
 	 * 
 	 * <p>
-	 * Here is the grammar for version strings.
+	 * Version string grammar:
 	 * 
 	 * <pre>
 	 * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
@@ -110,9 +110,8 @@ public class Version implements Comparab
 	 * alpha ::= [a..zA..Z]
 	 * </pre>
 	 * 
-	 * There must be no whitespace in version.
-	 * 
-	 * @param version String representation of the version identifier.
+	 * @param version String representation of the version identifier. There
+	 *        must be no whitespace in the argument.
 	 * @throws IllegalArgumentException If {@code version} is improperly
 	 *         formatted.
 	 */
@@ -124,31 +123,28 @@ public class Version implements Comparab
 
 		try {
 			StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
-			maj = Integer.parseInt(st.nextToken());
+			maj = parseInt(st.nextToken(), version);
 
 			if (st.hasMoreTokens()) { // minor
 				st.nextToken(); // consume delimiter
-				min = Integer.parseInt(st.nextToken());
+				min = parseInt(st.nextToken(), version);
 
 				if (st.hasMoreTokens()) { // micro
 					st.nextToken(); // consume delimiter
-					mic = Integer.parseInt(st.nextToken());
+					mic = parseInt(st.nextToken(), version);
 
-					if (st.hasMoreTokens()) { // qualifier
+					if (st.hasMoreTokens()) { // qualifier separator
 						st.nextToken(); // consume delimiter
 						qual = st.nextToken(""); // remaining string
 
 						if (st.hasMoreTokens()) { // fail safe
-							throw new IllegalArgumentException(
-									"invalid format: " + version);
+							throw new IllegalArgumentException("invalid version \"" + version + "\": invalid format");
 						}
 					}
 				}
 			}
-		}
-		catch (NoSuchElementException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid format: " + version);
+		} catch (NoSuchElementException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid version \"" + version + "\": invalid format");
 			iae.initCause(e);
 			throw iae;
 		}
@@ -157,11 +153,27 @@ public class Version implements Comparab
 		minor = min;
 		micro = mic;
 		qualifier = qual;
-		versionString = null;
 		validate();
 	}
 
 	/**
+	 * Parse numeric component into an int.
+	 * 
+	 * @param value Numeric component
+	 * @param version Complete version string for exception message, if any
+	 * @return int value of numeric component
+	 */
+	private static int parseInt(String value, String version) {
+		try {
+			return Integer.parseInt(value);
+		} catch (NumberFormatException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid version \"" + version + "\": non-numeric \"" + value + "\"");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
 	 * Called by the Version constructors to validate the version components.
 	 * 
 	 * @throws IllegalArgumentException If the numerical components are negative
@@ -169,17 +181,15 @@ public class Version implements Comparab
 	 */
 	private void validate() {
 		if (major < 0) {
-			throw new IllegalArgumentException("negative major");
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + major + "\"");
 		}
 		if (minor < 0) {
-			throw new IllegalArgumentException("negative minor");
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + minor + "\"");
 		}
 		if (micro < 0) {
-			throw new IllegalArgumentException("negative micro");
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + micro + "\"");
 		}
-		char[] chars = qualifier.toCharArray();
-		for (int i = 0, length = chars.length; i < length; i++) {
-	        char ch = chars[i];
+		for (char ch : qualifier.toCharArray()) {
 			if (('A' <= ch) && (ch <= 'Z')) {
 				continue;
 			}
@@ -192,8 +202,7 @@ public class Version implements Comparab
 			if ((ch == '_') || (ch == '-')) {
 				continue;
 			}
-			throw new IllegalArgumentException("invalid qualifier: "
-					+ qualifier);
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": invalid qualifier \"" + qualifier + "\"");
 		}
 	}
 
@@ -205,10 +214,9 @@ public class Version implements Comparab
 	 * 
 	 * @param version String representation of the version identifier. Leading
 	 *        and trailing whitespace will be ignored.
-	 * @return A {@code Version} object representing the version
-	 *         identifier. If {@code version} is {@code null} or
-	 *         the empty string then {@code emptyVersion} will be
-	 *         returned.
+	 * @return A {@code Version} object representing the version identifier. If
+	 *         {@code version} is {@code null} or the empty string then
+	 *         {@code emptyVersion} will be returned.
 	 * @throws IllegalArgumentException If {@code version} is improperly
 	 *         formatted.
 	 */
@@ -265,13 +273,22 @@ public class Version implements Comparab
 	 * Returns the string representation of this version identifier.
 	 * 
 	 * <p>
-	 * The format of the version string will be {@code major.minor.micro}
-	 * if qualifier is the empty string or
-	 * {@code major.minor.micro.qualifier} otherwise.
+	 * The format of the version string will be {@code major.minor.micro} if
+	 * qualifier is the empty string or {@code major.minor.micro.qualifier}
+	 * otherwise.
 	 * 
 	 * @return The string representation of this version identifier.
 	 */
 	public String toString() {
+		return toString0();
+	}
+
+	/**
+	 * Internal toString behavior
+	 * 
+	 * @return The string representation of this version identifier.
+	 */
+	String toString0() {
 		if (versionString != null) {
 			return versionString;
 		}
@@ -295,8 +312,15 @@ public class Version implements Comparab
 	 * @return An integer which is a hash code value for this object.
 	 */
 	public int hashCode() {
-		return (major << 24) + (minor << 16) + (micro << 8)
-				+ qualifier.hashCode();
+		if (hash != 0) {
+			return hash;
+		}
+		int h = 31 * 17;
+		h = 31 * h + major;
+		h = 31 * h + minor;
+		h = 31 * h + micro;
+		h = 31 * h + qualifier.hashCode();
+		return hash = h;
 	}
 
 	/**
@@ -308,9 +332,8 @@ public class Version implements Comparab
 	 * is equal (using {@code String.equals}).
 	 * 
 	 * @param object The {@code Version} object to be compared.
-	 * @return {@code true} if {@code object} is a
-	 *         {@code Version} and is equal to this object;
-	 *         {@code false} otherwise.
+	 * @return {@code true} if {@code object} is a {@code Version} and is equal
+	 *         to this object; {@code false} otherwise.
 	 */
 	public boolean equals(Object object) {
 		if (object == this) { // quicktest
@@ -322,15 +345,14 @@ public class Version implements Comparab
 		}
 
 		Version other = (Version) object;
-		return (major == other.major) && (minor == other.minor)
-				&& (micro == other.micro) && qualifier.equals(other.qualifier);
+		return (major == other.major) && (minor == other.minor) && (micro == other.micro) && qualifier.equals(other.qualifier);
 	}
 
 	/**
 	 * Compares this {@code Version} object to another {@code Version}.
 	 * 
 	 * <p>
-	 * A version is considered to be <b>less than </b> another version if its
+	 * 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