Skip to content

Commit

Permalink
Merge pull request osgi#401 from bjhargrave/issues/400
Browse files Browse the repository at this point in the history
service: Improve description of natural order and ranking order
  • Loading branch information
bjhargrave authored Jan 20, 2022
2 parents 61df035 + d8eda37 commit 8c50178
Show file tree
Hide file tree
Showing 26 changed files with 224 additions and 237 deletions.
57 changes: 20 additions & 37 deletions org.osgi.framework/src/org/osgi/framework/BundleContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -530,12 +530,10 @@ public interface BundleContext extends BundleReference {
* expression, and the packages for the class names under which the services
* were registered match the context bundle's packages as defined in
* {@link ServiceReference#isAssignableTo(Bundle, String)}.
*
* <p>
* The list is valid at the time of the call to this method. However since
* the Framework is a very dynamic environment, services can be modified or
* unregistered at any time.
*
* <p>
* The specified {@code filter} expression is used to select the registered
* services whose service properties contain keys and values which satisfy
Expand All @@ -545,7 +543,6 @@ public interface BundleContext extends BundleReference {
* {@code filter} expression cannot be parsed, an
* {@link InvalidSyntaxException} will be thrown with a human readable
* message where the filter became unparsable.
*
* <p>
* The result is an array of {@code ServiceReference} objects for all
* services that meet all of the following conditions:
Expand All @@ -567,12 +564,14 @@ public interface BundleContext extends BundleReference {
* </ul>
*
* @param clazz The class name with which the service was registered or
* {@code null} for all services.
* {@code null} for all services.
* @param filter The filter expression or {@code null} for all services.
* @return An array of {@code ServiceReference} objects or {@code null} if
* no services are registered which satisfy the search.
* no services are registered which satisfy the search. There is no
* guarantee that the {@code ServiceReference} objects in the array
* will be in any specific order.
* @throws InvalidSyntaxException If the specified {@code filter} contains
* an invalid filter expression that cannot be parsed.
* an invalid filter expression that cannot be parsed.
* @throws IllegalStateException If this BundleContext is no longer valid.
*/
ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
Expand All @@ -582,12 +581,10 @@ public interface BundleContext extends BundleReference {
* of {@code ServiceReference} objects contains services that were
* registered under the specified class and match the specified filter
* expression.
*
* <p>
* The list is valid at the time of the call to this method. However since
* the Framework is a very dynamic environment, services can be modified or
* unregistered at any time.
*
* <p>
* The specified {@code filter} expression is used to select the registered
* services whose service properties contain keys and values which satisfy
Expand All @@ -597,7 +594,6 @@ public interface BundleContext extends BundleReference {
* {@code filter} expression cannot be parsed, an
* {@link InvalidSyntaxException} will be thrown with a human readable
* message where the filter became unparsable.
*
* <p>
* The result is an array of {@code ServiceReference} objects for all
* services that meet all of the following conditions:
Expand All @@ -615,12 +611,14 @@ public interface BundleContext extends BundleReference {
* </ul>
*
* @param clazz The class name with which the service was registered or
* {@code null} for all services.
* {@code null} for all services.
* @param filter The filter expression or {@code null} for all services.
* @return An array of {@code ServiceReference} objects or {@code null} if
* no services are registered which satisfy the search.
* no services are registered which satisfy the search. There is no
* guarantee that the {@code ServiceReference} objects in the array
* will be in any specific order.
* @throws InvalidSyntaxException If the specified {@code filter} contains
* an invalid filter expression that cannot be parsed.
* an invalid filter expression that cannot be parsed.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @since 1.3
*/
Expand All @@ -629,27 +627,19 @@ public interface BundleContext extends BundleReference {
/**
* Returns a {@code ServiceReference} object for a service that implements
* and was registered under the specified class.
*
* <p>
* The returned {@code ServiceReference} object is valid at the time of the
* call to this method. However as the Framework is a very dynamic
* environment, services can be modified or unregistered at any time.
*
* <p>
* This method is the same as calling
* {@link #getServiceReferences(String, String)} with a {@code null} filter
* expression and then finding the reference with the highest priority. It
* is provided as a convenience for when the caller is interested in any
* service that implements the specified class.
* <p>
* If multiple such services exist, the service with the highest priority is
* selected. This priority is defined as the service reference with the
* highest ranking (as specified in its {@link Constants#SERVICE_RANKING}
* property) is returned.
* <p>
* If there is a tie in ranking, the service with the lowest service id (as
* specified in its {@link Constants#SERVICE_ID} property); that is, the
* service that was registered first is returned.
* If multiple such services exist, the service that is first in the
* {@link ServiceReference#compareTo(Object) ranking order} is returned.
*
* @param clazz The class name with which the service was registered.
* @return A {@code ServiceReference} object, or {@code null} if no services
Expand All @@ -662,28 +652,22 @@ public interface BundleContext extends BundleReference {
/**
* Returns a {@code ServiceReference} object for a service that implements
* and was registered under the name of the specified class.
*
* <p>
* The returned {@code ServiceReference} object is valid at the time of the
* call to this method. However as the Framework is a very dynamic
* environment, services can be modified or unregistered at any time.
*
* <p>
* This method is the same as calling
* {@link #getServiceReferences(Class, String)} with a {@code null} filter
* expression. It is provided as a convenience for when the caller is
* interested in any service that implements the specified class.
* <p>
* If multiple such services exist, the service with the highest ranking (as
* specified in its {@link Constants#SERVICE_RANKING} property) is returned.
* <p>
* If there is a tie in ranking, the service with the lowest service id (as
* specified in its {@link Constants#SERVICE_ID} property); that is, the
* service that was registered first is returned.
* If multiple such services exist, the service that is first in the
* {@link ServiceReference#compareTo(Object) ranking order} is returned.
*
* @param <S> Type of Service.
* @param clazz The class under whose name the service was registered. Must
* not be {@code null}.
* not be {@code null}.
* @return A {@code ServiceReference} object, or {@code null} if no services
* are registered which implement the specified class.
* @throws IllegalStateException If this BundleContext is no longer valid.
Expand All @@ -699,12 +683,10 @@ public interface BundleContext extends BundleReference {
* specified filter expression, and the packages for the class names under
* which the services were registered match the context bundle's packages as
* defined in {@link ServiceReference#isAssignableTo(Bundle, String)}.
*
* <p>
* The collection is valid at the time of the call to this method. However
* since the Framework is a very dynamic environment, services can be
* modified or unregistered at any time.
*
* <p>
* The specified {@code filter} expression is used to select the registered
* services whose service properties contain keys and values which satisfy
Expand All @@ -714,7 +696,6 @@ public interface BundleContext extends BundleReference {
* {@code filter} expression cannot be parsed, an
* {@link InvalidSyntaxException} will be thrown with a human readable
* message where the filter became unparsable.
*
* <p>
* The result is a collection of {@code ServiceReference} objects for all
* services that meet all of the following conditions:
Expand All @@ -736,12 +717,14 @@ public interface BundleContext extends BundleReference {
*
* @param <S> Type of Service
* @param clazz The class under whose name the service was registered. Must
* not be {@code null}.
* not be {@code null}.
* @param filter The filter expression or {@code null} for all services.
* @return A collection of {@code ServiceReference} objects. May be empty if
* no services are registered which satisfy the search.
* no services are registered which satisfy the search. There is no
* guarantee that the {@code ServiceReference} objects in the
* collection will be in any specific order.
* @throws InvalidSyntaxException If the specified {@code filter} contains
* an invalid filter expression that cannot be parsed.
* an invalid filter expression that cannot be parsed.
* @throws IllegalStateException If this BundleContext is no longer valid.
* @since 1.6
*/
Expand Down
23 changes: 20 additions & 3 deletions org.osgi.framework/src/org/osgi/framework/ServiceReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ public interface ServiceReference<S>
/**
* Compares this {@code ServiceReference} with the specified
* {@code ServiceReference} for order.
*
* <p>
* <b>Natural Order</b>
* <p>
* If this {@code ServiceReference} and the specified
* {@code ServiceReference} have the same {@link Constants#SERVICE_ID
Expand All @@ -184,15 +185,31 @@ public interface ServiceReference<S>
* {@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.
* <p>
* Sorting a collection of {@code ServiceReference} objects with natural
* order will result in the first element having the lowest
* {@link Constants#SERVICE_RANKING service ranking} and the last element
* having the highest {@link Constants#SERVICE_RANKING service ranking}.
* <p>
* <b>Ranking Order</b>
* <p>
* <em>Ranking order</em>, as defined in the Core Specification, is the
* reverse of natural order.
* <p>
* Sorting a collection of {@code ServiceReference} objects with ranking
* order will result in the first element having the highest
* {@link Constants#SERVICE_RANKING service ranking} and the last element
* having the lowest {@link Constants#SERVICE_RANKING service ranking}.
*
* @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}.
* @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
* @see "Core Specification, Service Ranking Order"
*/
@Override
public int compareTo(Object reference);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.osgi.annotation.versioning.ConsumerType;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.wiring.BundleCapability;
Expand All @@ -32,7 +33,6 @@
/**
* OSGi Framework Resolver Hook instances are obtained from the OSGi
* {@link ResolverHookFactory Framework Resolver Hook Factory} service.
*
* <p>
* A Resolver Hook instance is called by the framework during a resolve process.
* A resolver hook may influence the outcome of a resolve process by removing
Expand All @@ -41,7 +41,6 @@
* supports all remove operations. Any other attempts to modify a shrinkable
* collection will result in an {@code UnsupportedOperationException} being
* thrown.
*
* <p>
* The following steps outline the way a framework uses the resolver hooks
* during a resolve process.
Expand All @@ -60,7 +59,6 @@
* {@link ResolverHookFactory#begin(Collection)} method to inform the hooks
* about a resolve process beginning and to obtain a Resolver Hook instance that
* will be used for the duration of the resolve process.</li>
*
* <li>Determine the collection of unresolved bundle revisions that may be
* considered for resolution during the current resolution process and place
* each of the bundle revisions in a shrinkable collection {@code Resolvable}.
Expand All @@ -78,7 +76,8 @@
* <li>Determine the collection of available capabilities that have a namespace
* of {@link IdentityNamespace osgi.identity}, are singletons, and have the same
* symbolic name as the singleton bundle revision {@code B} and place each of
* the matching capabilities into a shrinkable collection {@code Collisions}.</li>
* the matching capabilities into a shrinkable collection
* {@code Collisions}.</li>
* <li>Remove the {@link IdentityNamespace osgi.identity} capability provided by
* bundle revision {@code B} from shrinkable collection {@code Collisions}. A
* singleton bundle cannot collide with itself.</li>
Expand Down Expand Up @@ -118,11 +117,11 @@
* <li>For each resolver hook call the {@link #end()} method to inform the hooks
* about a resolve process ending.</li>
* </ol>
* In all cases, the order in which the resolver hooks are called is the reverse
* compareTo ordering of their Service References. That is, the service with the
* highest ranking number must be called first. In cases where a shrinkable
* collection becomes empty the framework is required to call the remaining
* registered hooks.
* In all cases, the resolver hooks are called in
* {@link ServiceReference#compareTo(Object) ranking order}. That is, the
* service with the highest ranking must be called first. In cases where a
* shrinkable collection becomes empty the framework is required to call the
* remaining registered hooks.
* <p>
* Resolver hooks are low level. Implementations of the resolver hook must be
* careful not to create an unresolvable state which is very hard for a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* @author $Id$
*/

@Version("1.0")
@Version("1.0.1")
package org.osgi.framework.hooks.resolver;

import org.osgi.annotation.versioning.Version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,19 @@ public interface ComponentContext {

/**
* Returns the service object for the specified reference name.
*
* <p>
* If the cardinality of the reference is {@code 0..n} or {@code 1..n} and
* multiple services are bound to the reference, the service with the
* highest ranking (as specified in its {@code Constants.SERVICE_RANKING}
* property) is returned. If there is a tie in ranking, the service with the
* lowest service id (as specified in its {@code Constants.SERVICE_ID}
* property); that is, the service that was registered first is returned.
* multiple services are bound to the reference, the service whose
* {@code ServiceReference} is first in the ranking order is returned. See
* {@code ServiceReference.compareTo(Object)}.
*
* @param name The name of a reference as specified in a {@code reference}
* element in this component's description.
* element in this component's description.
* @return A service object for the referenced service or {@code null} if
* the reference cardinality is {@code 0..1} or {@code 0..n} and no
* bound service is available.
* @throws ComponentException If Service Component Runtime catches an
* exception while activating the bound service.
* exception while activating the bound service.
*/
public <S> S locateService(String name);

Expand All @@ -90,14 +87,16 @@ public interface ComponentContext {
* Returns the service objects for the specified reference name.
*
* @param name The name of a reference as specified in a {@code reference}
* element in this component's description.
* element in this component's description.
* @return An array of service objects for the referenced service or
* {@code null} if the reference cardinality is {@code 0..1} or
* {@code 0..n} and no bound service is available. If the reference
* cardinality is {@code 0..1} or {@code 1..1} and a bound service
* is available, the array will have exactly one element.
* is available, the array will have exactly one element. There is
* no guarantee that the service objects in the array will be in any
* specific order.
* @throws ComponentException If Service Component Runtime catches an
* exception while activating a bound service.
* exception while activating a bound service.
*/
public Object[] locateServices(String name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public enum CollectionType {
* services.
* <p>
* The Maps must implement {@code Comparable} with the {@code compareTo}
* method comparing service property maps using the same ordering as
* {@code ServiceReference.compareTo} based upon service ranking and service
* id.
* method comparing service property maps using an ordering which is the
* same as the natural ordering of {@code ServiceReference}s as specified in
* {@code ServiceReference.compareTo}.
*/
PROPERTIES("properties"),

Expand All @@ -64,9 +64,10 @@ public enum CollectionType {
* {@link #PROPERTIES}, and whose value is the bound service object.
* <p>
* The Map.Entries must implement {@code Comparable} with the
* {@code compareTo} method comparing service property maps using the same
* ordering as {@code ServiceReference.compareTo} based upon service ranking
* and service id.
* {@code compareTo} method comparing service property maps using an
* ordering which is the same as the natural ordering of
* {@code ServiceReference}s as specified in
* {@code ServiceReference.compareTo}.
*/
TUPLE("tuple");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* @author $Id$
*/

@Version(COMPONENT_SPECIFICATION_VERSION)
@Version(COMPONENT_SPECIFICATION_VERSION + ".1")
package org.osgi.service.component.annotations;

import static org.osgi.service.component.ComponentConstants.COMPONENT_SPECIFICATION_VERSION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* @author $Id$
*/

@Version(COMPONENT_SPECIFICATION_VERSION)
@Version(COMPONENT_SPECIFICATION_VERSION + ".1")
package org.osgi.service.component;

import static org.osgi.service.component.ComponentConstants.COMPONENT_SPECIFICATION_VERSION;
Expand Down
Loading

0 comments on commit 8c50178

Please sign in to comment.