Upgrade to latest OSGi compendium API. (FELIX-1205)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@797561 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java
index c04fcf8..41c8864 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/ApplicationContext.java,v 1.15 2006/07/11 13:19:02 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,26 +22,26 @@
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
-
/**
* <code>ApplicationContext</code> is the access point for an OSGi-aware
* application to the features of the OSGi Service Platform. Each application
* instance will have its own <code>ApplicationContext</code> instance, which
* will not be reused after destorying the corresponding application instace.
* <p>
- * Application instances can obtain their <code>ApplicationContext</code>
- * using the {@link Framework#getApplicationContext} method.
+ * Application instances can obtain their <code>ApplicationContext</code> using
+ * the {@link Framework#getApplicationContext} method.
* <p>
- * The lifecycle of an <code>ApplicationContext</code> instance is bound to
- * the lifecycle of the corresponding application instance. The
+ * The lifecycle of an <code>ApplicationContext</code> instance is bound to the
+ * lifecycle of the corresponding application instance. The
* <code>ApplicationContext</code> becomes available when the application is
* started and it is invalidated when the application instance is stopped (i.e.
- * the "stop" method of the application activator object returned).
- * All method calls (except {@link #getApplicationId()} and
- * {@link #getInstanceId()}) to an invalidated context object result an
- * <code>IllegalStateException</code>.
+ * the "stop" method of the application activator object returned). All method
+ * calls (except {@link #getApplicationId()} and {@link #getInstanceId()}) to an
+ * invalidated context object result an <code>IllegalStateException</code>.
*
* @see org.osgi.application.Framework
+ *
+ * @version $Revision: 5673 $
*/
public interface ApplicationContext {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java
index cfb4cec..cbb3ee5 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/ApplicationServiceEvent.java,v 1.6 2006/07/11 13:19:02 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +38,7 @@
* @see org.osgi.framework.ServiceEvent
* @see ApplicationServiceListener
*
- * @version $Revision: 1.6 $
+ * @version $Revision: 5673 $
*/
public class ApplicationServiceEvent extends ServiceEvent {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java
index 1a7d36f..7db5d2b 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/ApplicationServiceListener.java,v 1.6 2006/07/12 21:21:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,7 +52,7 @@
* objects is further filtered according to package sources as defined in
* {@link ServiceReference#isAssignableTo(Bundle, String)}.
*
- * @version $Revision: 1.6 $
+ * @version $Revision: 5673 $
* @see ApplicationServiceEvent
* @see ServicePermission
*/
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java b/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java
index 4696115..b81e93c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/Framework.java,v 1.9 2006/07/11 13:19:02 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +19,10 @@
import java.util.Hashtable;
/**
- * Using this class, OSGi-aware applications can obtain their {@link ApplicationContext}.
- *
+ * Using this class, OSGi-aware applications can obtain their
+ * {@link ApplicationContext}.
+ *
+ * @version $Revision: 5673 $
*/
public final class Framework {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/package.html b/org.osgi.compendium/src/main/java/org/osgi/application/package.html
new file mode 100644
index 0000000..5230b62
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Foreign Application Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.application; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/application/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
index 5615148..1993330 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationAdminPermission.java,v 1.34 2006/07/12 21:22:11 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,21 +17,27 @@
package org.osgi.service.application;
import java.security.Permission;
-import java.util.*;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
-import org.osgi.framework.*;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
/**
- * This class implements permissions for manipulating applications and
- * their instances.
+ * This class implements permissions for manipulating applications and their
+ * instances.
* <P>
* ApplicationAdminPermission can be targeted to applications that matches the
* specified filter.
* <P>
* ApplicationAdminPermission may be granted for different actions:
- * <code>lifecycle</code>, <code>schedule</code> and <code>lock</code>.
- * The permission <code>schedule</code> implies the permission
+ * <code>lifecycle</code>, <code>schedule</code> and <code>lock</code>. The
+ * permission <code>schedule</code> implies the permission
* <code>lifecycle</code>.
+ *
+ * @version $Revision: 6860 $
*/
public class ApplicationAdminPermission extends Permission {
private static final long serialVersionUID = 1L;
@@ -146,7 +150,7 @@
try {
newPerm = new ApplicationAdminPermission( this.filter, this.actions );
}catch( InvalidSyntaxException e ) {
- throw new RuntimeException( "Internal error" ); /* this can never happen */
+ throw new RuntimeException(e); /* this can never happen */
}
}
else
@@ -303,6 +307,9 @@
private String pattern;
private ApplicationDescriptor appDesc;
+ /**
+ * @param pattern
+ */
public SignerWrapper(String pattern) {
this.pattern = pattern;
}
@@ -333,71 +340,9 @@
}
private Filter getFilter() {
- String transformedFilter = filter;
-
if (appliedFilter == null) {
try {
- int pos = filter.indexOf("signer"); //$NON-NLS-1$
- if (pos != -1){
-
- //there may be a signer attribute
- StringBuffer filterBuf = new StringBuffer(filter);
- int numAsteriskFound = 0; //use as offset to replace in buffer
-
- int walkbackPos; //temp pos
-
- //find occurences of (signer= and escape out *'s
- while (pos != -1) {
-
- //walk back and look for '(' to see if this is an attr
- walkbackPos = pos-1;
-
- //consume whitespace
- while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
- walkbackPos--;
- }
- if (walkbackPos <0) {
- //filter is invalid - FilterImpl will throw error
- break;
- }
-
- //check to see if we have unescaped '('
- if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
- //'(' was escaped or not there
- pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
- continue;
- }
- pos+=6; //skip over 'signer'
-
- //found signer - consume whitespace before '='
- while (Character.isWhitespace(filter.charAt(pos))) {
- pos++;
- }
-
- //look for '='
- if (filter.charAt(pos) != '=') {
- //attr was signerx - keep looking
- pos = filter.indexOf("signer",pos); //$NON-NLS-1$
- continue;
- }
- pos++; //skip over '='
-
- //found signer value - escape '*'s
- while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
- if (filter.charAt(pos) == '*') {
- filterBuf.insert(pos+numAsteriskFound,'\\');
- numAsteriskFound++;
- }
- pos++;
- }
-
- //end of signer value - look for more?
- pos = filter.indexOf("signer",pos); //$NON-NLS-1$
- } //end while (pos != -1)
- transformedFilter = filterBuf.toString();
- } //end if (pos != -1)
-
- appliedFilter = FrameworkUtil.createFilter( transformedFilter );
+ appliedFilter = FrameworkUtil.createFilter(filter);
} catch (InvalidSyntaxException e) {
//we will return null
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
index 4764bd7..37287e2 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationDescriptor.java,v 1.61 2006/07/10 12:02:31 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +18,9 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.security.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
import java.util.Map;
import org.osgi.framework.Constants;
@@ -30,6 +30,8 @@
* An OSGi service that represents an installed application and stores
* information about it. The application descriptor can be used for instance
* creation.
+ *
+ * @version $Revision: 6860 $
*/
public abstract class ApplicationDescriptor {
@@ -263,8 +265,9 @@
* The following steps are made:
* <UL>
* <LI>Check for the appropriate permission.
- * <LI>Check the locking state of the application. If locked then return
- * null otherwise continue.
+ * <LI>Check the locking state of the application. If locked then throw
+ * an {@link ApplicationException} with the reason code
+ * {@link ApplicationException#APPLICATION_LOCKED}.
* <LI>Calls the <code>launchSpecific()</code> method to create and start an application
* instance.
* <LI>Returns the <code>ApplicationHandle</code> returned by the
@@ -290,7 +293,7 @@
* <code>org.osgi.</code>.</li>
* </ul>
* <P>
- * The method is synchonous, it return only when the application instance was
+ * The method is synchronous, it return only when the application instance was
* successfully started or the attempt to start it failed.
* <P>
* This method never returns <code>null</code>. If launching an application fails,
@@ -386,7 +389,9 @@
* <p>
* The <code>Map</code> argument of the method contains startup
* arguments for the application. The keys used in the Map must be non-null,
- * non-empty <code>String<code> objects.
+ * non-empty <code>String<code> objects. The argument values must be
+ * of primitive types, wrapper classes of primitive types, <code>String</code>
+ * or arrays or collections of these.
* <p>
* The created schedules have a unique identifier within the scope of this
* <code>ApplicationDescriptor</code>. This identifier can be specified
@@ -428,6 +433,9 @@
* <li> {@link ApplicationException#APPLICATION_SCHEDULING_FAILED}
* if the scheduling failed due to some internal reason
* (e.g. persistent storage error).
+ * <li> {@link ApplicationException#APPLICATION_INVALID_STARTUP_ARGUMENT}
+ * if the specified startup argument doesn't satisfy the
+ * type or value constraints of startup arguments.
* </ul>
* @throws SecurityException
* if the caller doesn't have "schedule"
@@ -594,7 +602,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
@@ -614,7 +622,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
@@ -634,7 +642,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
@@ -654,7 +662,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
@@ -682,7 +690,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
@@ -705,7 +713,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java
index c30e112..485f71d 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationException.java,v 1.10 2006/07/10 11:49:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,28 +17,37 @@
package org.osgi.service.application;
/**
- * This exception is used to indicate problems related to application
- * lifecycle management.
+ * This exception is used to indicate problems related to application lifecycle
+ * management.
*
- * <code>ApplicationException</code> object is created by the Application Admin to denote
- * an exception condition in the lifecycle of an application.
- * <code>ApplicationException</code>s should not be created by developers.
- * <br/>
- * <code>ApplicationException</code>s are associated with an error code. This code
- * describes the type of problem reported in this exception. The possible codes are:
+ * <code>ApplicationException</code> object is created by the Application Admin
+ * to denote an exception condition in the lifecycle of an application.
+ * <code>ApplicationException</code>s should not be created by developers. <br/>
+ * <code>ApplicationException</code>s are associated with an error code. This
+ * code describes the type of problem reported in this exception. The possible
+ * codes are:
* <ul>
- * <li> {@link #APPLICATION_LOCKED} - The application couldn't be launched because it is locked.</li>
- * <li> {@link #APPLICATION_NOT_LAUNCHABLE} - The application is not in launchable state.</li>
- * <li> {@link #APPLICATION_INTERNAL_ERROR} - An exception was thrown by the application or its
- * container during launch.</li>
+ * <li> {@link #APPLICATION_LOCKED} - The application couldn't be launched
+ * because it is locked.</li>
+ * <li> {@link #APPLICATION_NOT_LAUNCHABLE} - The application is not in
+ * launchable state.</li>
+ * <li> {@link #APPLICATION_INTERNAL_ERROR} - An exception was thrown by the
+ * application or its container during launch.</li>
* <li> {@link #APPLICATION_SCHEDULING_FAILED} - The scheduling of an application
- * failed.
+ * failed.
+ * <li> {@link #APPLICATION_DUPLICATE_SCHEDULE_ID} - The application scheduling
+ * failed because the specified identifier is already in use.
+ * <li> {@link #APPLICATION_EXITVALUE_NOT_AVAILABLE} - The exit value is not
+ * available for an application instance because the instance has not
+ * terminated.
+ * <li> {@link #APPLICATION_INVALID_STARTUP_ARGUMENT} - One of the specified
+ * startup arguments is invalid, for example its type is not permitted.
* </ul>
*
+ * @version $Revision: 6083 $
*/
public class ApplicationException extends Exception {
private static final long serialVersionUID = -7173190453622508207L;
- private final Throwable cause;
private final int errorCode;
/**
@@ -54,16 +61,17 @@
* attribute is false.
*/
public static final int APPLICATION_NOT_LAUNCHABLE = 0x02;
-
+
/**
- * An exception was thrown by the application or the corresponding
- * container during launch. The exception is available in {@link #getCause()}.
+ * An exception was thrown by the application or the corresponding container
+ * during launch. The exception is available from <code>getCause()</code>.
*/
public static final int APPLICATION_INTERNAL_ERROR = 0x03;
/**
* The application schedule could not be created due to some internal error
- * (for example, the schedule information couldn't be saved).
+ * (for example, the schedule information couldn't be saved due to some
+ * storage error).
*/
public static final int APPLICATION_SCHEDULING_FAILED = 0x04;
@@ -74,11 +82,28 @@
public static final int APPLICATION_DUPLICATE_SCHEDULE_ID = 0x05;
/**
+ * The exit value is not available for an application instance because the
+ * instance has not terminated.
+ *
+ * @since 1.1
+ */
+ public static final int APPLICATION_EXITVALUE_NOT_AVAILABLE = 0x06;
+
+ /**
+ * One of the specified startup arguments is invalid, for example its
+ * type is not permitted.
+ *
+ * @since 1.1
+ */
+ public static final int APPLICATION_INVALID_STARTUP_ARGUMENT = 0x07;
+
+ /**
* Creates an <code>ApplicationException</code> with the specified error code.
* @param errorCode The code of the error
*/
public ApplicationException(int errorCode) {
- this(errorCode,(Throwable) null);
+ super();
+ this.errorCode = errorCode;
}
/**
@@ -88,8 +113,7 @@
* @param cause The cause of this exception.
*/
public ApplicationException(int errorCode, Throwable cause) {
- super();
- this.cause = cause;
+ super(cause);
this.errorCode = errorCode;
}
@@ -99,7 +123,8 @@
* @param message The associated message
*/
public ApplicationException(int errorCode, String message) {
- this(errorCode, message,null);
+ super(message);
+ this.errorCode = errorCode;
}
/**
@@ -110,24 +135,24 @@
* @param cause The cause of this exception.
*/
public ApplicationException(int errorCode, String message, Throwable cause) {
- super(message);
- this.cause = cause;
+ super(message, cause);
this.errorCode = errorCode;
}
/**
- * Returns the cause of this exception or <code>null</code> if no cause
- * was specified when this exception was created.
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
*
- * @return The cause of this exception or <code>null</code> if no cause
- * was specified.
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
}
/**
- * Returns the error code associcated with this exception.
+ * Returns the error code associated with this exception.
+ *
* @return The error code of this exception.
*/
public int getErrorCode() {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java
index a0bdc89..7168269 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationHandle.java,v 1.41 2006/07/10 12:02:31 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +18,9 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.security.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
import org.osgi.framework.Constants;
@@ -29,6 +29,8 @@
* of an application. It provides the functionality to query and manipulate the
* lifecycle state of the represented application instance. It defines constants
* for the lifecycle states.
+ *
+ * @version $Revision: 5901 $
*/
public abstract class ApplicationHandle {
/*
@@ -50,11 +52,19 @@
public final static String APPLICATION_DESCRIPTOR = "application.descriptor";
/**
- * The property key for the state of this appliction instance.
+ * The property key for the state of this application instance.
*/
public final static String APPLICATION_STATE = "application.state";
/**
+ * The property key for the supports exit value property of this application
+ * instance.
+ *
+ * @since 1.1
+ */
+ public final static String APPLICATION_SUPPORTS_EXITVALUE = "application.supports.exitvalue";
+
+ /**
* The application instance is running. This is the initial state of a newly
* created application instance.
*/
@@ -137,6 +147,45 @@
public abstract String getState();
/**
+ * Returns the exit value for the application instance. The timeout
+ * specifies how the method behaves when the application has not yet
+ * terminated. A negative, zero or positive value may be used.
+ * <ul>
+ * <li> negative - The method does not wait for termination. If the
+ * application has not terminated then an <code>ApplicationException</code>
+ * is thrown.</li>
+ *
+ * <li> zero - The method waits until the application terminates.</li>
+ *
+ * <li> positive - The method waits until the application terminates or the
+ * timeout expires. If the timeout expires and the application has not
+ * terminated then an <code>ApplicationException</code> is thrown.</li>
+ * </ul>
+ * <p>
+ * The default implementation throws an
+ * <code>UnsupportedOperationException</code>. The application model should
+ * override this method if exit values are supported.
+ * </p>
+ *
+ * @param timeout The maximum time in milliseconds to wait for the
+ * application to timeout.
+ * @return The exit value for the application instance. The value is
+ * application specific.
+ * @throws UnsupportedOperationException If the application model does not
+ * support exit values.
+ * @throws InterruptedException If the thread is interrupted while waiting
+ * for the timeout.
+ * @throws ApplicationException If the application has not terminated. The
+ * error code will be
+ * {@link ApplicationException#APPLICATION_EXITVALUE_NOT_AVAILABLE}.
+ *
+ * @since 1.1
+ */
+ public Object getExitValue(long timeout) throws ApplicationException, InterruptedException{
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Returns the unique identifier of this instance. This value is also
* available as a service property of this application handle's service.pid.
*
@@ -181,7 +230,7 @@
}catch( SecurityException se ) {
descriptor.isLaunchableSpecific(); /* check whether the bundle was uninstalled */
/* if yes, throws IllegalStateException */
- throw se; /* otherwise throw the catched SecurityException */
+ throw se; /* otherwise throw the caught SecurityException */
}
destroySpecific();
}
@@ -265,7 +314,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
void destroy() {
@@ -284,7 +333,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java
index 46cfe5e..02d776f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ScheduledApplication.java,v 1.20 2006/07/06 14:59:29 sboshev Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,10 +27,12 @@
* Each <code>ScheduledApplication</code> instance has an identifier which is
* unique within the scope of the application being scheduled.
* <p>
- * <code>ScheduledApplication</code> instances are registered as services.
- * The {@link #APPLICATION_PID} service property contains the PID of the
- * application being scheduled, the {@link #SCHEDULE_ID} service property
- * contains the schedule identifier.
+ * <code>ScheduledApplication</code> instances are registered as services. The
+ * {@link #APPLICATION_PID} service property contains the PID of the application
+ * being scheduled, the {@link #SCHEDULE_ID} service property contains the
+ * schedule identifier.
+ *
+ * @version $Revision: 5673 $
*/
public interface ScheduledApplication {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/application/package.html
new file mode 100644
index 0000000..18daeb5
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Application Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.application; version="[1.1,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/application/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintContainer.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintContainer.java
new file mode 100644
index 0000000..23cb758
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintContainer.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceListMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.osgi.service.blueprint.reflect.ServiceMetadata;
+import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
+
+/**
+ * A Blueprint Container represents the managed state of a Blueprint bundle.
+ *
+ * A Blueprint Container provides access to all managed components. These are
+ * the beans, services, and service references. Only bundles in the
+ * <code>ACTIVE</code> state (and also the <code>STARTING</code> state for
+ * bundles awaiting lazy activation) can have an associated Blueprint Container.
+ * A given Bundle Context has at most one associated Blueprint Container.
+ *
+ * A Blueprint Container can be obtained by injecting the predefined
+ * "blueprintContainer" component id. The Blueprint Container is also
+ * registered as a service and its managed components can be queried.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7556 $
+ */
+public interface BlueprintContainer {
+ /**
+ * Returns the set of component ids managed by this Blueprint Container.
+ *
+ * @return An immutable Set of Strings, containing the ids of all of the
+ * components managed within this Blueprint Container.
+ */
+ Set/* <String> */getComponentIds();
+
+ /**
+ * Return the component instance for the specified component id.
+ *
+ * If the component's manager has not yet been activated, calling this
+ * operation will atomically activate it. If the component has singleton
+ * scope, the activation will cause the component instance to be created and
+ * initialized. If the component has prototype scope, then each call to this
+ * method will return a new component instance.
+ *
+ * @param id The component id for the requested component instance.
+ * @return A component instance for the component with the specified
+ * component id.
+ * @throws NoSuchComponentException If no component with the specified
+ * component id is managed by this Blueprint Container.
+ */
+ Object getComponentInstance(String id);
+
+ /**
+ * Return the Component Metadata object for the component with the specified
+ * component id.
+ *
+ * @param id The component id for the requested Component Metadata.
+ * @return The Component Metadata object for the component with the
+ * specified component id.
+ * @throws NoSuchComponentException If no component with the specified
+ * component id is managed by this Blueprint Container.
+ */
+ ComponentMetadata getComponentMetadata(String id);
+
+ /**
+ * Return all {@link ComponentMetadata} objects of the specified Component
+ * Metadata type. The supported Component Metadata types are
+ * {@link ComponentMetadata} (which returns the Component Metadata for all
+ * defined manager types), {@link BeanMetadata} ,
+ * {@link ServiceReferenceMetadata} (which returns both
+ * {@link ReferenceMetadata} and {@link ReferenceListMetadata} objects), and
+ * {@link ServiceMetadata}. The collection will include all Component
+ * Metadata objects of the requested type, including components that are
+ * declared inline.
+ *
+ * @param type The super type or type of the requested Component Metadata
+ * objects.
+ * @return An immutable collection of Component Metadata objects of the
+ * specified type.
+ */
+ /* <T extends ComponentMetadata> */Collection/* <T> */getMetadata(
+ Class/* <T> */type);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintEvent.java
new file mode 100644
index 0000000..8e0dedf
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintEvent.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A Blueprint Event.
+ *
+ * <p>
+ * <code>BlueprintEvent</code> objects are delivered to all registered
+ * {@link BlueprintListener} services. Blueprint Events must be asynchronously
+ * delivered in chronological order with respect to each listener.
+ *
+ * <p>
+ * In addition, after a Blueprint Listener is registered, the Blueprint extender
+ * will synchronously send to this Blueprint Listener the last Blueprint Event
+ * for each ready Blueprint bundle managed by this extender. This
+ * <em>replay</em> of Blueprint Events is designed so that the new Blueprint
+ * Listener can be informed of the state of each Blueprint bundle. Blueprint
+ * Events sent during this replay will have the {@link #isReplay()} flag set.
+ * The Blueprint extender must ensure that this replay phase does not interfere
+ * with new Blueprint Events so that the chronological order of all Blueprint
+ * Events received by the Blueprint Listener is preserved. If the last Blueprint
+ * Event for a given Blueprint bundle is {@link #DESTROYED}, the extender must
+ * not send it during this replay phase.
+ *
+ * <p>
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #CREATING}</li>
+ * <li>{@link #CREATED}</li>
+ * <li>{@link #DESTROYING}</li>
+ * <li>{@link #DESTROYED}</li>
+ * <li>{@link #FAILURE}</li>
+ * <li>{@link #GRACE_PERIOD}</li>
+ * <li>{@link #WAITING}</li>
+ * </ul>
+ *
+ * <p>
+ * In addition to calling the registered {@link BlueprintListener} services, the
+ * Blueprint extender must also send those events to the Event Admin service, if
+ * it is available.
+ *
+ * @see BlueprintListener
+ * @see EventConstants
+ * @Immutable
+ * @version $Revision: 7591 $
+ */
+public class BlueprintEvent {
+
+ /**
+ * The Blueprint extender has started creating a Blueprint Container for the
+ * bundle.
+ */
+ public static final int CREATING = 1;
+ /**
+ * The Blueprint extender has created a Blueprint Container for the bundle.
+ * This event is sent after the Blueprint Container has been registered as a
+ * service.
+ */
+ public static final int CREATED = 2;
+ /**
+ * The Blueprint extender has started destroying the Blueprint Container for
+ * the bundle.
+ */
+ public static final int DESTROYING = 3;
+ /**
+ * The Blueprint Container for the bundle has been completely destroyed.
+ * This event is sent after the Blueprint Container has been unregistered as
+ * a service.
+ */
+ public static final int DESTROYED = 4;
+ /**
+ * The Blueprint Container creation for the bundle has failed. If this event
+ * is sent after a timeout in the Grace Period, the
+ * {@link #getDependencies()} method must return an array of missing
+ * mandatory dependencies. The event must also contain the cause of the
+ * failure as a <code>Throwable</code> through the {@link #getCause()}
+ * method.
+ */
+ public static final int FAILURE = 5;
+ /**
+ * The Blueprint Container has entered the grace period. The list of missing
+ * dependencies must be made available through the
+ * {@link #getDependencies()} method. During the grace period, a
+ * {@link #GRACE_PERIOD} event is sent each time the set of unsatisfied
+ * dependencies changes.
+ */
+ public static final int GRACE_PERIOD = 6;
+ /**
+ * The Blueprint Container is waiting on the availability of a service to
+ * satisfy an invocation on a referenced service. The missing dependency
+ * must be made available through the {@link #getDependencies()} method
+ * which will return an array containing one filter object as a String.
+ */
+ public static final int WAITING = 7;
+
+ /**
+ * Type of this event.
+ *
+ * @see #getType()
+ */
+ private final int type;
+ /**
+ * The time when the event occurred.
+ *
+ * @see #getTimestamp()
+ */
+ private final long timestamp;
+ /**
+ * The Blueprint bundle.
+ *
+ * @see #getBundle()
+ */
+ private final Bundle bundle;
+ /**
+ * The Blueprint extender bundle.
+ *
+ * @see #getExtenderBundle()
+ */
+ private final Bundle extenderBundle;
+ /**
+ * An array containing filters identifying the missing dependencies. Must
+ * not be <code>null</code> when the event type requires it.
+ *
+ * @see #getDependencies()
+ */
+ private final String[] dependencies;
+ /**
+ * Cause of the failure.
+ *
+ * @see #getCause()
+ */
+ private final Throwable cause;
+ /**
+ * Indicate if this event is a replay event or not.
+ *
+ * @see #isReplay()
+ */
+ private final boolean replay;
+
+ /**
+ * Create a simple <code>BlueprintEvent</code> object.
+ *
+ * @param type The type of this event.
+ * @param bundle The Blueprint bundle associated with this event. This
+ * parameter must not be <code>null</code>.
+ * @param extenderBundle The Blueprint extender bundle that is generating
+ * this event. This parameter must not be <code>null</code>.
+ */
+ public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle) {
+ this(type, bundle, extenderBundle, null, null);
+ }
+
+ /**
+ * Create a <code>BlueprintEvent</code> object associated with a set of
+ * dependencies.
+ *
+ * @param type The type of this event.
+ * @param bundle The Blueprint bundle associated with this event. This
+ * parameter must not be <code>null</code>.
+ * @param extenderBundle The Blueprint extender bundle that is generating
+ * this event. This parameter must not be <code>null</code>.
+ * @param dependencies An array of <code>String</code> filters for each
+ * dependency associated with this event. Must be a non-empty array
+ * for event types {@link #GRACE_PERIOD} and {@link #WAITING}. It is
+ * optional for event type {@link #FAILURE}. Must be
+ * <code>null</code> for other event types.
+ */
+ public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
+ String[] dependencies) {
+ this(type, bundle, extenderBundle, dependencies, null);
+ }
+
+ /**
+ * Create a <code>BlueprintEvent</code> object associated with a failure
+ * cause.
+ *
+ * @param type The type of this event.
+ * @param bundle The Blueprint bundle associated with this event. This
+ * parameter must not be <code>null</code>.
+ * @param extenderBundle The Blueprint extender bundle that is generating
+ * this event. This parameter must not be <code>null</code>.
+ * @param cause A <code>Throwable</code> object describing the root cause of
+ * the event. May be <code>null</code>.
+ */
+ public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
+ Throwable cause) {
+ this(type, bundle, extenderBundle, null, cause);
+ }
+
+ /**
+ * Create a <code>BlueprintEvent</code> object associated with a failure
+ * cause and a set of dependencies.
+ *
+ * @param type The type of this event.
+ * @param bundle The Blueprint bundle associated with this event. This
+ * parameter must not be <code>null</code>.
+ * @param extenderBundle The Blueprint extender bundle that is generating
+ * this event. This parameter must not be <code>null</code>.
+ * @param dependencies An array of <code>String</code> filters for each
+ * dependency associated with this event. Must be a non-empty array
+ * for event types {@link #GRACE_PERIOD} and {@link #WAITING}. It is
+ * optional for event type {@link #FAILURE}. Must be
+ * <code>null</code> for other event types.
+ * @param cause A <code>Throwable</code> object describing the root cause of
+ * this event. May be <code>null</code>.
+ */
+ public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
+ String[] dependencies, Throwable cause) {
+ this.type = type;
+ this.timestamp = System.currentTimeMillis();
+ this.bundle = bundle;
+ this.extenderBundle = extenderBundle;
+ this.dependencies = dependencies;
+ this.cause = cause;
+ this.replay = false;
+ if (bundle == null) {
+ throw new NullPointerException("bundle must not be null");
+ }
+ if (extenderBundle == null) {
+ throw new NullPointerException("extenderBundle must not be null");
+ }
+ switch (type) {
+ case WAITING :
+ case GRACE_PERIOD :
+ if (dependencies == null) {
+ throw new NullPointerException(
+ "dependencies must not be null");
+ }
+ if (dependencies.length == 0) {
+ throw new IllegalArgumentException(
+ "dependencies must not be length zero");
+ }
+ break;
+ case FAILURE :
+ if ((dependencies != null) && (dependencies.length == 0)) {
+ throw new IllegalArgumentException(
+ "dependencies must not be length zero");
+ }
+ break;
+ default :
+ if (dependencies != null) {
+ throw new IllegalArgumentException(
+ "dependencies must be null");
+ }
+ break;
+ }
+ }
+
+ /**
+ * Create a new <code>BlueprintEvent</code> from the specified
+ * <code>BlueprintEvent</code>. The <code>timestamp</code> property will be
+ * copied from the original event and only the replay property will be
+ * overridden with the given value.
+ *
+ * @param event The original <code>BlueprintEvent</code> to copy. Must not
+ * be <code>null</code>.
+ * @param replay <code>true</code> if this event should be used as a replay
+ * event.
+ */
+ public BlueprintEvent(BlueprintEvent event, boolean replay) {
+ this.type = event.type;
+ this.timestamp = event.timestamp;
+ this.bundle = event.bundle;
+ this.extenderBundle = event.extenderBundle;
+ this.dependencies = event.dependencies;
+ this.cause = event.cause;
+ this.replay = replay;
+ }
+
+ /**
+ * Return the type of this event.
+ * <p>
+ * The type values are:
+ * <ul>
+ * <li>{@link #CREATING}</li>
+ * <li>{@link #CREATED}</li>
+ * <li>{@link #DESTROYING}</li>
+ * <li>{@link #DESTROYED}</li>
+ * <li>{@link #FAILURE}</li>
+ * <li>{@link #GRACE_PERIOD}</li>
+ * <li>{@link #WAITING}</li>
+ * </ul>
+ *
+ * @return The type of this event.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Return the time at which this event was created.
+ *
+ * @return The time at which this event was created.
+ */
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * Return the Blueprint bundle associated with this event.
+ *
+ * @return The Blueprint bundle associated with this event.
+ */
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ /**
+ * Return the Blueprint extender bundle that is generating this event.
+ *
+ * @return The Blueprint extender bundle that is generating this event.
+ */
+ public Bundle getExtenderBundle() {
+ return extenderBundle;
+ }
+
+ /**
+ * Return the filters identifying the missing dependencies that caused this
+ * event.
+ *
+ * @return The filters identifying the missing dependencies that caused this
+ * event if the event type is one of {@link #WAITING},
+ * {@link #GRACE_PERIOD} or {@link #FAILURE} or <code>null</code>
+ * for the other event types.
+ */
+ public String[] getDependencies() {
+ return dependencies == null ? null : (String[]) dependencies.clone();
+ }
+
+ /**
+ * Return the cause for this {@link #FAILURE} event.
+ *
+ * @return The cause of the failure for this event. May be <code>null</code>
+ * .
+ */
+ public Throwable getCause() {
+ return cause;
+ }
+
+ /**
+ * Return whether this event is a replay event.
+ *
+ * @return <code>true</code> if this event is a replay event and
+ * <code>false</code> otherwise.
+ */
+ public boolean isReplay() {
+ return replay;
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintListener.java
new file mode 100644
index 0000000..937898e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintListener.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+/**
+ * A <code>BlueprintEvent</code> Listener.
+ *
+ * <p>
+ * To receive Blueprint Events, a bundle must register a Blueprint Listener
+ * service.
+ *
+ * After a Blueprint Listener is registered, the Blueprint extender must
+ * synchronously send to this Blueprint Listener the last Blueprint Event for
+ * each ready Blueprint bundle managed by this extender. This replay of
+ * Blueprint Events is designed so that the new Blueprint Listener can be
+ * informed of the state of each Blueprint bundle. Blueprint Events sent during
+ * this replay will have the {@link BlueprintEvent#isReplay() isReplay()} flag
+ * set. The Blueprint extender must ensure that this replay phase does not
+ * interfere with new Blueprint Events so that the chronological order of all
+ * Blueprint Events received by the Blueprint Listener is preserved. If the last
+ * Blueprint Event for a given Blueprint bundle is
+ * {@link BlueprintEvent#DESTROYED DESTROYED}, the extender must not send it
+ * during this replay phase.
+ *
+ * @see BlueprintEvent
+ * @ThreadSafe
+ * @version $Revision: 7564 $
+ */
+public interface BlueprintListener {
+
+ /**
+ * Receives notifications of a Blueprint Event.
+ *
+ * Implementers should quickly process the event and return.
+ *
+ * @param event The {@link BlueprintEvent}.
+ */
+ void blueprintEvent(BlueprintEvent event);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ComponentDefinitionException.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ComponentDefinitionException.java
new file mode 100644
index 0000000..0e29850
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ComponentDefinitionException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+/**
+ * A Blueprint exception indicating that a component definition is in error.
+ *
+ * This exception is thrown when a configuration-related error occurs during
+ * creation of a Blueprint Container.
+ *
+ * @version $Revision: 7556 $
+ */
+public class ComponentDefinitionException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates a Component Definition Exception with no message or exception
+ * cause.
+ */
+ public ComponentDefinitionException() {
+ super();
+ }
+
+ /**
+ * Creates a Component Definition Exception with the specified message
+ *
+ * @param explanation The associated message.
+ */
+ public ComponentDefinitionException(String explanation) {
+ super(explanation);
+ }
+
+ /**
+ * Creates a Component Definition Exception with the specified message and
+ * exception cause.
+ *
+ * @param explanation The associated message.
+ * @param cause The cause of this exception.
+ */
+ public ComponentDefinitionException(String explanation, Throwable cause) {
+ super(explanation, cause);
+ }
+
+ /**
+ * Creates a Component Definition Exception with the exception cause.
+ *
+ * @param cause The cause of this exception.
+ */
+ public ComponentDefinitionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/Converter.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/Converter.java
new file mode 100644
index 0000000..ca6517b
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/Converter.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+/**
+ * Type converter to convert an object to a target type.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7564 $
+ */
+public interface Converter {
+
+ /**
+ * Return if this converter is able to convert the specified object to the
+ * specified type.
+ *
+ * @param sourceObject The source object <code>s</code> to convert.
+ * @param targetType The target type <code>T</code>.
+ *
+ * @return <code>true</code> if the conversion is possible,
+ * <code>false</code> otherwise.
+ */
+ boolean canConvert(Object sourceObject, ReifiedType targetType);
+
+ /**
+ * Convert the specified object to an instance of the specified type.
+ *
+ * @param sourceObject The source object <code>s</code> to convert.
+ * @param targetType The target type <code>T</code>.
+ * @return An instance with a type that is assignable from targetType's raw
+ * class
+ * @throws Exception If the conversion cannot succeed. This exception should
+ * not be thrown when the {@link #canConvert canConvert} method has
+ * returned <code>true</code>.
+ */
+ Object convert(Object sourceObject, ReifiedType targetType)
+ throws Exception;
+}
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/EventConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/EventConstants.java
new file mode 100644
index 0000000..d149ab0
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/EventConstants.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+/**
+ * Event property names used in Event Admin events published by a Blueprint
+ * Container.
+ *
+ * <p>
+ * Each type of event is sent to a different topic:
+ *
+ * <p>
+ * <code>org/osgi/service/blueprint/container/</code><em><event-type></em>
+ *
+ * <p>
+ * where <em><event-type></em> can have the values
+ * {@link BlueprintEvent#CREATING CREATING}, {@link BlueprintEvent#CREATED
+ * CREATED}, {@link BlueprintEvent#DESTROYING DESTROYING},
+ * {@link BlueprintEvent#DESTROYED DESTROYED}, {@link BlueprintEvent#FAILURE
+ * FAILURE}, {@link BlueprintEvent#GRACE_PERIOD GRACE_PERIOD}, or
+ * {@link BlueprintEvent#WAITING WAITING}.
+ *
+ * <p>
+ * Such events have the following properties:
+ * <ul>
+ * <li>{@link #TYPE type}</li>
+ * <li>{@link #EVENT event}</li>
+ * <li>{@link #TIMESTAMP timestamp}</li>
+ * <li>{@link #BUNDLE bundle}</li>
+ * <li>{@link #BUNDLE_SYMBOLICNAME bundle.symbolicName}</li>
+ * <li>{@link #BUNDLE_ID bundle.id}</li>
+ * <li>{@link #BUNDLE_VERSION bundle.version}</li>
+ * <li>{@link #EXTENDER_BUNDLE_SYMBOLICNAME extender.bundle.symbolicName}</li>
+ * <li>{@link #EXTENDER_BUNDLE_ID extender.bundle.id}</li>
+ * <li>{@link #EXTENDER_BUNDLE_VERSION extender.bundle.version}</li>
+ * <li>{@link #DEPENDENCIES dependencies}</li>
+ * <li>{@link #CAUSE cause}</li>
+ * </ul>
+ *
+ * @Immutable
+ * @version $Revision: 7564 $
+ */
+public class EventConstants {
+ private EventConstants() {
+ // non-instantiable class
+ }
+
+ /**
+ * The type of the event that has been issued. This property is of type
+ * <code>Integer</code> and can take one of the values defined in
+ * {@link BlueprintEvent}.
+ */
+ public static final String TYPE = "type";
+
+ /**
+ * The <code>BlueprintEvent</code> object that caused this event. This
+ * property is of type {@link BlueprintEvent}.
+ */
+ public static final String EVENT = "event";
+
+ /**
+ * The time the event was created. This property is of type
+ * <code>Long</code>.
+ */
+ public static final String TIMESTAMP = "timestamp";
+
+ /**
+ * The Blueprint bundle associated with this event. This property is of type
+ * <code>Bundle</code>.
+ */
+ public static final String BUNDLE = "bundle";
+
+ /**
+ * The bundle id of the Blueprint bundle associated with this event. This
+ * property is of type <code>Long</code>.
+ */
+ public static final String BUNDLE_ID = "bundle.id";
+
+ /**
+ * The bundle symbolic name of the Blueprint bundle associated with this
+ * event. This property is of type <code>String</code>.
+ */
+ public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName";
+
+ /**
+ * The bundle version of the Blueprint bundle associated with this event.
+ * This property is of type <code>Version</code>.
+ */
+ public static final String BUNDLE_VERSION = "bundle.version";
+
+ /**
+ * The Blueprint extender bundle that is generating this event. This
+ * property is of type <code>Bundle</code>.
+ */
+ public static final String EXTENDER_BUNDLE = "extender.bundle";
+
+ /**
+ * The bundle id of the Blueprint extender bundle that is generating this
+ * event. This property is of type <code>Long</code>.
+ */
+ public static final String EXTENDER_BUNDLE_ID = "extender.bundle.id";
+
+ /**
+ * The bundle symbolic of the Blueprint extender bundle that is generating
+ * this event. This property is of type <code>String</code>.
+ */
+ public static final String EXTENDER_BUNDLE_SYMBOLICNAME = "extender.bundle.symbolicName";
+
+ /**
+ * The bundle version of the Blueprint extender bundle that is generating
+ * this event. This property is of type <code>Version</code>.
+ */
+ public static final String EXTENDER_BUNDLE_VERSION = "extender.bundle.version";
+
+ /**
+ * The filters identifying the missing dependencies that caused this event
+ * for a {@link BlueprintEvent#FAILURE FAILURE},
+ * {@link BlueprintEvent#GRACE_PERIOD GRACE_PERIOD}, or
+ * {@link BlueprintEvent#WAITING WAITING} event. This property type is an
+ * array of <code>String</code>.
+ */
+ public static final String DEPENDENCIES = "dependencies";
+
+ /**
+ * The cause for a {@link BlueprintEvent#FAILURE FAILURE} event. This
+ * property is of type <code>Throwable</code>.
+ */
+ public static final String CAUSE = "cause";
+
+ /**
+ * Topic prefix for all events issued by the Blueprint Container
+ */
+ public static final String TOPIC_BLUEPRINT_EVENTS = "org/osgi/service/blueprint/container";
+
+ /**
+ * Topic for Blueprint Container CREATING events
+ */
+ public static final String TOPIC_CREATING = TOPIC_BLUEPRINT_EVENTS
+ + "/CREATING";
+
+ /**
+ * Topic for Blueprint Container CREATED events
+ */
+ public static final String TOPIC_CREATED = TOPIC_BLUEPRINT_EVENTS
+ + "/CREATED";
+
+ /**
+ * Topic for Blueprint Container DESTROYING events
+ */
+ public static final String TOPIC_DESTROYING = TOPIC_BLUEPRINT_EVENTS
+ + "/DESTROYING";
+
+ /**
+ * Topic for Blueprint Container DESTROYED events
+ */
+ public static final String TOPIC_DESTROYED = TOPIC_BLUEPRINT_EVENTS
+ + "/DESTROYED";
+
+ /**
+ * Topic for Blueprint Container FAILURE events
+ */
+ public static final String TOPIC_FAILURE = TOPIC_BLUEPRINT_EVENTS
+ + "/FAILURE";
+
+ /**
+ * Topic for Blueprint Container GRACE_PERIOD events
+ */
+ public static final String TOPIC_GRACE_PERIOD = TOPIC_BLUEPRINT_EVENTS
+ + "/GRACE_PERIOD";
+
+ /**
+ * Topic for Blueprint Container WAITING events
+ */
+ public static final String TOPIC_WAITING = TOPIC_BLUEPRINT_EVENTS
+ + "/WAITING";
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/NoSuchComponentException.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/NoSuchComponentException.java
new file mode 100644
index 0000000..0ee9b30
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/NoSuchComponentException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+/**
+ * A Blueprint exception indicating that a component does not exist in a
+ * Blueprint Container.
+ *
+ * This exception is thrown when an attempt is made to create a component
+ * instance or lookup Component Metadata using a component id that does not
+ * exist in the Blueprint Container.
+ *
+ * @version $Revision: 7556 $
+ */
+public class NoSuchComponentException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ /**
+ * The requested component id that generated the exception.
+ */
+ private final String componentId;
+
+ /**
+ * Create a No Such Component Exception for a non-existent component.
+ *
+ * @param msg The associated message.
+ * @param id The id of the non-existent component.
+ */
+ public NoSuchComponentException(String msg, String id) {
+ super(msg);
+ this.componentId = id;
+ }
+
+ /**
+ * Create a No Such Component Exception for a non-existent component.
+ *
+ * @param id The id of the non-existent component.
+ */
+ public NoSuchComponentException(String id) {
+ super("No component with id '" + (id == null ? "<null>" : id)
+ + "' could be found");
+ this.componentId = id;
+ }
+
+ /**
+ * Returns the id of the non-existent component.
+ *
+ * @return The id of the non-existent component.
+ */
+ public String getComponentId() {
+ return componentId;
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ReifiedType.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ReifiedType.java
new file mode 100644
index 0000000..a923bcd
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ReifiedType.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+/**
+ * Provides access to a concrete type and its optional generic type parameters.
+ *
+ * <p>
+ * Java 5 and later support generic types. These types consist of a raw class
+ * with type parameters. This class models such a <code>Type</code> class but
+ * ensures that the type is <em>reified</em>. Reification means that the Type
+ * graph associated with a Java 5 <code>Type</code> instance is traversed until
+ * the type becomes a concrete class. This class is available with the
+ * {@link #getRawClass()} method. The optional type parameters are recursively
+ * represented as Reified Types.
+ *
+ * <p>
+ * In Java 1.4, a class has by definition no type parameters. This class
+ * implementation provides the Reified Type for Java 1.4 by making the raw class
+ * the Java 1.4 class and using a Reified Type based on the <code>Object</code>
+ * class for any requested type parameter.
+ *
+ * <p>
+ * A Blueprint extender implementations can subclass this class and provide
+ * access to the generic type parameter graph for conversion. Such a subclass
+ * must <em>reify</em> the different Java 5 <code>Type</code> instances into the
+ * reified form. That is, a form where the raw Class is available with its
+ * optional type parameters as Reified Types.
+ *
+ * @Immutable
+ * @version $Revision: 7564 $
+ */
+public class ReifiedType {
+ private final static ReifiedType OBJECT = new ReifiedType(Object.class);
+
+ private final Class clazz;
+
+ /**
+ * Create a Reified Type for a raw Java class without any generic type
+ * parameters. Subclasses can provide the optional generic type parameter
+ * information. Without subclassing, this instance has no type parameters.
+ *
+ * @param clazz The raw class of the Reified Type.
+ */
+ public ReifiedType(Class clazz) {
+ this.clazz = clazz;
+ }
+
+ /**
+ * Return the raw class represented by this type.
+ *
+ * The raw class represents the concrete class that is associated with a
+ * type declaration. This class could have been deduced from the generics
+ * type parameter graph of the declaration. For example, in the following
+ * example:
+ *
+ * <pre>
+ * Map<String, ? extends Metadata>
+ * </pre>
+ *
+ * The raw class is the Map class.
+ *
+ * @return The raw class represented by this type.
+ */
+ public Class getRawClass() {
+ return clazz;
+ }
+
+ /**
+ * Return a type parameter for this type.
+ *
+ * The type parameter refers to a parameter in a generic type declaration
+ * given by the zero-based index <code>i</code>.
+ *
+ * For example, in the following example:
+ *
+ * <pre>
+ * Map<String, ? extends Metadata>
+ * </pre>
+ *
+ * type parameter 0 is <code>String</code>, and type parameter 1 is
+ * <code>Metadata</code>.
+ *
+ * <p>
+ * This implementation returns a Reified Type that has <code>Object</code>
+ * as class. Any object is assignable to Object and therefore no conversion
+ * is then necessary. This is compatible with versions of Java language
+ * prior to Java 5.
+ *
+ * This method should be overridden by a subclass that provides access to
+ * the generic type parameter information for Java 5 and later.
+ *
+ * @param i The zero-based index of the requested type parameter.
+ * @return The <code>ReifiedType</code> for the generic type parameter at
+ * the specified index.
+ */
+ public ReifiedType getActualTypeArgument(int i) {
+ return OBJECT;
+ }
+
+ /**
+ * Return the number of type parameters for this type.
+ *
+ * <p>
+ * This implementation returns <code>0</code>. This method should be
+ * overridden by a subclass that provides access to the generic type
+ * parameter information for Java 5 and later.
+ *
+ * @return The number of type parameters for this type.
+ */
+ public int size() {
+ return 0;
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ServiceUnavailableException.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ServiceUnavailableException.java
new file mode 100644
index 0000000..e0ef284
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ServiceUnavailableException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.container;
+
+import org.osgi.framework.ServiceException;
+
+/**
+ * A Blueprint exception indicating that a service is unavailable.
+ *
+ * This exception is thrown when an invocation is made on a service reference
+ * and a backing service is not available.
+ *
+ * @version $Revision: 7556 $
+ */
+public class ServiceUnavailableException extends ServiceException {
+ private static final long serialVersionUID = 1L;
+ /**
+ * The filter string associated with the exception.
+ */
+ private final String filter;
+
+ /**
+ * Creates a Service Unavailable Exception with the specified message.
+ *
+ * @param message The associated message.
+ * @param filter The filter used for the service lookup.
+ */
+ public ServiceUnavailableException(String message, String filter) {
+ super(message, UNREGISTERED);
+ this.filter = filter;
+ }
+
+ /**
+ * Creates a Service Unavailable Exception with the specified message and
+ * exception cause.
+ *
+ * @param message The associated message.
+ * @param filter The filter used for the service lookup.
+ * @param cause The cause of this exception.
+ */
+ public ServiceUnavailableException(String message, String filter,
+ Throwable cause) {
+ super(message, UNREGISTERED, cause);
+ this.filter = filter;
+ }
+
+ /**
+ * Returns the filter expression that a service would have needed to satisfy
+ * in order for the invocation to proceed.
+ *
+ * @return The failing filter.
+ */
+ public String getFilter() {
+ return this.filter;
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/package.html
new file mode 100644
index 0000000..6b2fc92
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/package.html
@@ -0,0 +1,21 @@
+<!-- $Revision: 7556 $ -->
+<BODY>
+<p>Blueprint Container Package Version 1.0.</p>
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:</p>
+<pre>
+Import-Package: org.osgi.service.blueprint.container; version="[1.0,2.0)"
+</pre>
+<p>
+ This package defines the primary interface to a Blueprint Container,
+ <code>BlueprintContainer</code>. An instance of this type is available
+ inside a Blueprint Container as an implicitly defined component with the name
+ "blueprintContainer".
+</p>
+<p>
+ This package also declares the supporting exception types, listener, and constants for working with a Blueprint
+ Container.
+</p>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanArgument.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanArgument.java
new file mode 100644
index 0000000..9811a42
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanArgument.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a factory method or constructor argument of a bean. The
+ * arguments of a bean are obtained from {@link BeanMetadata#getArguments()}.
+ *
+ * This is specified by the <code>argument</code> elements of a bean.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface BeanArgument {
+
+ /**
+ * Return the Metadata for the argument value.
+ *
+ * This is specified by the <code>value</code> attribute.
+ *
+ * @return The Metadata for the argument value.
+ */
+ Metadata getValue();
+
+ /**
+ * Return the name of the value type to match the argument and convert the
+ * value into when invoking the constructor or factory method.
+ *
+ * This is specified by the <code>type</code> attribute.
+ *
+ * @return The name of the value type to convert the value into, or
+ * <code>null</code> if no type is specified.
+ */
+ String getValueType();
+
+ /**
+ * Return the zero-based index into the parameter list of the factory method
+ * or constructor to be invoked for this argument. This is determined by
+ * specifying the <code>index</code> attribute for the bean. If not
+ * explicitly set, this will return -1 and the initial ordering is defined
+ * by its position in the {@link BeanMetadata#getArguments()} list.
+ *
+ * This is specified by the <code>index</code> attribute.
+ *
+ * @return The zero-based index of the parameter, or -1 if no index is
+ * specified.
+ */
+ int getIndex();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanMetadata.java
new file mode 100644
index 0000000..83e30ee
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanMetadata.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a Bean component.
+ *
+ * <p>
+ * This is specified by the <code>bean</code> element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface BeanMetadata extends Target, ComponentMetadata {
+
+ /**
+ * The bean has <code>singleton</code> scope.
+ *
+ * @see #getScope()
+ */
+ static final String SCOPE_SINGLETON = "singleton";
+
+ /**
+ * The bean has <code>prototype</code> scope.
+ *
+ * @see #getScope()
+ */
+ static final String SCOPE_PROTOTYPE = "prototype";
+
+ /**
+ * Return the name of the class specified for the bean.
+ *
+ * This is specified by the <code>class</code> attribute of the bean
+ * definition.
+ *
+ * @return The name of the class specified for the bean. If no class is
+ * specified in the bean definition, because the a factory component
+ * is used instead, then this method will return <code>null</code>.
+ */
+ String getClassName();
+
+ /**
+ * Return the name of the init method specified for the bean.
+ *
+ * This is specified by the <code>init-method</code> attribute of the bean
+ * definition.
+ *
+ * @return The name of the init method specified for the bean, or
+ * <code>null</code> if no init method is specified.
+ */
+ String getInitMethod();
+
+ /**
+ * Return the name of the destroy method specified for the bean.
+ *
+ * This is specified by the <code>destroy-method</code> attribute of the
+ * bean definition.
+ *
+ * @return The name of the destroy method specified for the bean, or
+ * <code>null</code> if no destroy method is specified.
+ */
+ String getDestroyMethod();
+
+ /**
+ * Return the arguments for the factory method or constructor of the bean.
+ *
+ * This is specified by the child <code>argument<code> elements.
+ *
+ * @return An immutable List of {@link BeanArgument} objects for the factory
+ * method or constructor of the bean. The List is empty if no
+ * arguments are specified for the bean.
+ */
+ List/* <BeanArgument> */getArguments();
+
+ /**
+ * Return the properties for the bean.
+ *
+ * This is specified by the child <code>property</code> elements.
+ *
+ * @return An immutable List of {@link BeanProperty} objects, with one entry
+ * for each property to be injected in the bean. The List is empty
+ * if no property injection is specified for the bean.
+ *
+ */
+ List /* <BeanProperty> */getProperties();
+
+ /**
+ * Return the name of the factory method for the bean.
+ *
+ * This is specified by the <code>factory-method</code> attribute of the
+ * bean.
+ *
+ * @return The name of the factory method of the bean or <code>null</code>
+ * if no factory method is specified for the bean.
+ */
+ String getFactoryMethod();
+
+ /**
+ * Return the Metadata for the factory component on which to invoke the
+ * factory method for the bean.
+ *
+ * This is specified by the <code>factory-ref</code> attribute of the bean.
+ *
+ * <p>
+ * When a factory method and factory component have been specified for the
+ * bean, this method returns the factory component on which to invoke the
+ * factory method for the bean. When no factory component has been specified
+ * this method will return <code>null</code>.
+ *
+ * When a factory method has been specified for the bean but a factory
+ * component has not been specified, the factory method must be invoked as a
+ * static method on the bean's class.
+ *
+ * @return The Metadata for the factory component on which to invoke the
+ * factory method for the bean or <code>null</code> if no factory
+ * component is specified.
+ */
+ Target getFactoryComponent();
+
+ /**
+ * Return the scope for the bean.
+ *
+ * @return The scope for the bean.
+ * @see #SCOPE_SINGLETON
+ * @see #SCOPE_PROTOTYPE
+ */
+ String getScope();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanProperty.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanProperty.java
new file mode 100644
index 0000000..c65077d
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanProperty.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a property to be injected into a bean. The properties of a bean
+ * are obtained from {@link BeanMetadata#getProperties()}.
+ *
+ * This is specified by the <code>property</code> elements of a bean. Properties
+ * are defined according to the Java Beans conventions.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface BeanProperty {
+
+ /**
+ * Return the name of the property to be injected. The name follows Java
+ * Beans conventions.
+ *
+ * This is specified by the <code>name</code> attribute.
+ *
+ * @return The name of the property to be injected.
+ */
+ String getName();
+
+ /**
+ * Return the Metadata for the value to be injected into a bean.
+ *
+ * This is specified by the <code>value</code> attribute or in inlined text.
+ *
+ * @return The Metadata for the value to be injected into a bean.
+ */
+ Metadata getValue();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/CollectionMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/CollectionMetadata.java
new file mode 100644
index 0000000..ff493ca
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/CollectionMetadata.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a collection based value. Values of the collection are defined
+ * by Metadata objects. This Collection Metadata can constrain the values of the
+ * collection to a specific type.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+
+public interface CollectionMetadata extends NonNullMetadata {
+
+ /**
+ * Return the type of the collection.
+ *
+ * The possible types are: array (<code>Object[]</code>), <code>Set</code>,
+ * and <code>List</code>. This information is specified in the element name.
+ *
+ * @return The type of the collection. <code>Object[]</code> is returned to
+ * indicate an array.
+ */
+ Class/* <?> */getCollectionClass();
+
+ /**
+ * Return the type specified for the values of the collection.
+ *
+ * The <code>value-type</code> attribute specified this information.
+ *
+ * @return The type specified for the values of the collection.
+ */
+ String getValueType();
+
+ /**
+ * Return Metadata for the values of the collection.
+ *
+ * @return A List of Metadata for the values of the collection.
+ */
+ List /* <Metadata> */getValues();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ComponentMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ComponentMetadata.java
new file mode 100644
index 0000000..ddfb3a6
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ComponentMetadata.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for managed components. This is the base type for
+ * {@link BeanMetadata}, {@link ServiceMetadata} and
+ * {@link ServiceReferenceMetadata}.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ComponentMetadata extends NonNullMetadata {
+
+ /**
+ * The component's manager must eagerly activate the component.
+ *
+ * @see #getActivation()
+ */
+ static final int ACTIVATION_EAGER = 1;
+
+ /**
+ * The component's manager must lazily activate the component.
+ *
+ * @see #getActivation()
+ */
+ static final int ACTIVATION_LAZY = 2;
+
+ /**
+ * Return the id of the component.
+ *
+ * @return The id of the component. The component id can be
+ * <code>null</code> if this is an anonymously defined and/or
+ * inlined component.
+ */
+ String getId();
+
+ /**
+ * Return the activation strategy for the component.
+ *
+ * This is specified by the <code>activation</code> attribute of a component
+ * definition. If this is not set, then the <code>default-activation</code>
+ * in the <code>blueprint</code> element is used. If that is also not set,
+ * then the activation strategy is {@link #ACTIVATION_EAGER}.
+ *
+ * @return The activation strategy for the component.
+ * @see #ACTIVATION_EAGER
+ * @see #ACTIVATION_LAZY
+ */
+ int getActivation();
+
+ /**
+ * Return the ids of any components listed in a <code>depends-on</code>
+ * attribute for the component.
+ *
+ * @return An immutable List of component ids that are explicitly declared
+ * as a dependency, or an empty List if none.
+ */
+ List/* <String> */getDependsOn();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/IdRefMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/IdRefMetadata.java
new file mode 100644
index 0000000..d362873
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/IdRefMetadata.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for the verified id of another component managed by the Blueprint
+ * Container. The id itself will be injected, not the component to which the id
+ * refers. No implicit dependency is created.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface IdRefMetadata extends NonNullMetadata {
+ /**
+ * Return the id of the referenced component.
+ *
+ * This is specified by the <code>component-id</code> attribute of a
+ * component.
+ *
+ * @return The id of the referenced component.
+ */
+ String getComponentId();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapEntry.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapEntry.java
new file mode 100644
index 0000000..0635a74
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapEntry.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a map entry.
+ *
+ * This type is used by {@link MapMetadata}, {@link PropsMetadata} and
+ * {@link ServiceMetadata}.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface MapEntry {
+ /**
+ * Return the Metadata for the key of the map entry.
+ *
+ * This is specified by the <code>key</code> attribute or element.
+ *
+ * @return The Metadata for the key of the map entry. This must not be
+ * <code>null</code>.
+ */
+ NonNullMetadata getKey();
+
+ /**
+ * Return the Metadata for the value of the map entry.
+ *
+ * This is specified by the <code>value</code> attribute or element.
+ *
+ * @return The Metadata for the value of the map entry. This must not be
+ * <code>null</code>.
+ */
+ Metadata getValue();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapMetadata.java
new file mode 100644
index 0000000..d6819ea
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapMetadata.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a Map based value.
+ *
+ * <p>
+ * This is specified by the <code>map</code> element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface MapMetadata extends NonNullMetadata {
+ /**
+ * Return the name of the type of the map keys.
+ *
+ * This is specified by the <code>key-type</code> attribute of the map.
+ *
+ * @return The name of the type of the map keys, or <code>null</code> if
+ * none is specified.
+ */
+ String getKeyType();
+
+ /**
+ * Return the name of the type of the map values.
+ *
+ * This is specified by the <code>value-type</code> attribute of the map.
+ *
+ * @return The name of the type of the map values, or <code>null</code> if
+ * none is specified.
+ */
+ String getValueType();
+
+ /**
+ * Return the entries for the map.
+ *
+ * @return An immutable List of {@link MapEntry} objects for each entry in
+ * the map. The List is empty if no entries are specified for the
+ * map.
+ */
+ List /* <MapEntry> */getEntries();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Metadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Metadata.java
new file mode 100644
index 0000000..b078993
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Metadata.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) OSGi Alliance (2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Top level Metadata type. All Metdata types extends this base type.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface Metadata {
+ // marker interface
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NonNullMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NonNullMetadata.java
new file mode 100644
index 0000000..ea926e9
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NonNullMetadata.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a value that cannot <code>null</code>. All Metadata subtypes
+ * extend this type except for {@link NullMetadata}.
+ *
+ * <p>
+ * This Metadata type is used for keys in Maps because they cannot be
+ * <code>null</code>.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface NonNullMetadata extends Metadata {
+ // marker interface
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NullMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NullMetadata.java
new file mode 100644
index 0000000..2a26dcc
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NullMetadata.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a value specified to be <code>null</code> via the <null>
+ * element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface NullMetadata extends Metadata {
+
+ /**
+ * Singleton instance of <code>NullMetadata</code>.
+ */
+ static final NullMetadata NULL = new NullMetadata() {
+ // empty body
+ };
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/PropsMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/PropsMetadata.java
new file mode 100644
index 0000000..7edb347
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/PropsMetadata.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a <code>java.util.Properties</code> based value.
+ *
+ * <p>
+ * The {@link MapEntry} objects of properties are defined with keys and values
+ * of type <code>String</code>.
+ *
+ * <p>
+ * This is specified by the <code>props</code> element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7564 $
+ */
+public interface PropsMetadata extends NonNullMetadata {
+
+ /**
+ * Return the entries for the properties.
+ *
+ * @return An immutable List of {@link MapEntry} objects for each entry in
+ * the properties. The List is empty if no entries are specified for
+ * the properties.
+ */
+ List/* <MapEntry> */getEntries();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RefMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RefMetadata.java
new file mode 100644
index 0000000..8746b0f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RefMetadata.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a reference to another component managed by the Blueprint
+ * Container.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface RefMetadata extends Target, NonNullMetadata {
+ /**
+ * Return the id of the referenced component.
+ *
+ * This is specified by the <code>component-id</code> attribute of a
+ * component.
+ *
+ * @return The id of the referenced component.
+ */
+ String getComponentId();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java
new file mode 100644
index 0000000..a03618e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a list of service references.
+ *
+ * <p>
+ * This is specified by the <code>reference-list</code> element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ReferenceListMetadata extends ServiceReferenceMetadata {
+
+ /**
+ * Reference list values must be proxies to the actual service objects.
+ *
+ * @see #getMemberType()
+ */
+ static final int USE_SERVICE_OBJECT = 1;
+
+ /**
+ * Reference list values must be <code>ServiceReference</code> objects.
+ *
+ * @see #getMemberType()
+ */
+ static final int USE_SERVICE_REFERENCE = 2;
+
+ /**
+ * Return whether the List will contain service object proxies or
+ * <code>ServiceReference</code> objects.
+ *
+ * This is specified by the <code>member-type</code> attribute of the
+ * reference list.
+ *
+ * @return Whether the List will contain service object proxies or
+ * <code>ServiceReference</code> objects.
+ * @see #USE_SERVICE_OBJECT
+ * @see #USE_SERVICE_REFERENCE
+ */
+ int getMemberType();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListener.java
new file mode 100644
index 0000000..fa24577
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListener.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a reference listener interested in the reference bind and unbind
+ * events for a service reference.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ReferenceListener {
+
+ /**
+ * Return the Metadata for the component that will receive bind and unbind
+ * events.
+ *
+ * This is specified by the <code>ref</code> attribute or via an inlined
+ * component.
+ *
+ * @return The Metadata for the component that will receive bind and unbind
+ * events.
+ */
+ Target getListenerComponent();
+
+ /**
+ * Return the name of the bind method. The bind method will be invoked when
+ * a matching service is bound to the reference.
+ *
+ * This is specified by the <code>bind-method</code> attribute of the
+ * reference listener.
+ *
+ * @return The name of the bind method.
+ */
+ String getBindMethod();
+
+ /**
+ * Return the name of the unbind method. The unbind method will be invoked
+ * when a matching service is unbound from the reference.
+ *
+ * This is specified by the <code>unbind-method</code> attribute of the
+ * reference listener.
+ *
+ * @return The name of the unbind method.
+ */
+ String getUnbindMethod();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceMetadata.java
new file mode 100644
index 0000000..55f2db7
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceMetadata.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a reference that will bind to a single matching service in the
+ * service registry.
+ *
+ * <p>
+ * This is specified by the <code>reference</code> element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ReferenceMetadata extends Target, ServiceReferenceMetadata {
+
+ /**
+ * Return the timeout for service invocations when a backing service is is
+ * unavailable.
+ *
+ * This is specified by the <code>timeout</code> attribute of the reference.
+ *
+ * @return The timeout, in milliseconds, for service invocations when a
+ * backing service is is unavailable.
+ */
+ long getTimeout();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RegistrationListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RegistrationListener.java
new file mode 100644
index 0000000..77dc5fc
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RegistrationListener.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a registration listener interested in service registration and
+ * unregistration events for a service.
+ *
+ * <p>
+ * The registration listener is called with the initial state of the service
+ * when the registration listener is actuated.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface RegistrationListener {
+
+ /**
+ * Return the Metadata for the component that will receive registration and
+ * unregistration events.
+ *
+ * This is specified by the <code>ref</code> attribute or via an inlined
+ * component.
+ *
+ * @return The Metadata for the component that will receive registration and
+ * unregistration events.
+ */
+ Target getListenerComponent();
+
+ /**
+ * Return the name of the registration method. The registration method will
+ * be invoked when the associated service is registered with the service
+ * registry.
+ *
+ * This is specified by the <code>registration-method</code> attribute of
+ * the registration listener.
+ *
+ * @return The name of the registration method.
+ */
+ String getRegistrationMethod();
+
+ /**
+ * Return the name of the unregistration method. The unregistration method
+ * will be invoked when the associated service is unregistered from the
+ * service registry.
+ *
+ * This is specified by the <code>unregistration-method</code> attribute of
+ * the registration listener.
+ *
+ * @return The name of the unregistration method.
+ */
+ String getUnregistrationMethod();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceMetadata.java
new file mode 100644
index 0000000..86728b1
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceMetadata.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Metadata for a service to be registered by the Blueprint Container when
+ * enabled.
+ *
+ * <p>
+ * This is specified by the <code>service</code> element.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ServiceMetadata extends ComponentMetadata {
+
+ /**
+ * Do not auto-detect types for advertised service interfaces
+ *
+ * @see #getAutoExport()
+ */
+ static final int AUTO_EXPORT_DISABLED = 1;
+
+ /**
+ * Advertise all Java interfaces implemented by the component instance type
+ * as service interfaces.
+ *
+ * @see #getAutoExport()
+ */
+ static final int AUTO_EXPORT_INTERFACES = 2;
+
+ /**
+ * Advertise all Java classes in the hierarchy of the component instance
+ * type as service interfaces.
+ *
+ * @see #getAutoExport()
+ */
+ static final int AUTO_EXPORT_CLASS_HIERARCHY = 3;
+
+ /**
+ * Advertise all Java classes and interfaces in the component instance type
+ * as service interfaces.
+ *
+ * @see #getAutoExport()
+ */
+ static final int AUTO_EXPORT_ALL_CLASSES = 4;
+
+ /**
+ * Return the Metadata for the component to be exported as a service.
+ *
+ * This is specified inline or via the <code>ref</code> attribute of the
+ * service.
+ *
+ * @return The Metadata for the component to be exported as a service.
+ */
+ Target getServiceComponent();
+
+ /**
+ * Return the type names of the interfaces that the service should be
+ * advertised as supporting.
+ *
+ * This is specified in the <code>interface</code> attribute or child
+ * <code>interfaces</code> element of the service.
+ *
+ * @return An immutable List of <code>String</code> for the type names of
+ * the interfaces that the service should be advertised as
+ * supporting. The List is empty if using <code>auto-export</code>
+ * or no interface names are specified for the service.
+ */
+ List/* <String> */getInterfaces();
+
+ /**
+ * Return the auto-export mode for the service.
+ *
+ * This is specified by the <code>auto-export</code> attribute of the
+ * service.
+ *
+ * @return The auto-export mode for the service.
+ * @see #AUTO_EXPORT_DISABLED
+ * @see #AUTO_EXPORT_INTERFACES
+ * @see #AUTO_EXPORT_CLASS_HIERARCHY
+ * @see #AUTO_EXPORT_ALL_CLASSES
+ */
+ int getAutoExport();
+
+ /**
+ * Return the user declared properties to be advertised with the service.
+ *
+ * This is specified by the <code>service-properties</code> element of the
+ * service.
+ *
+ * @return An immutable List of {@link MapEntry} objects for the user
+ * declared properties to be advertised with the service. The List
+ * is empty if no service properties are specified for the service.
+ */
+ List/* <MapEntry> */getServiceProperties();
+
+ /**
+ * Return the ranking value to use when advertising the service. If the
+ * ranking value is zero, the service must be registered without a
+ * <code>service.ranking</code> service property.
+ *
+ * This is specified by the <code>ranking</code> attribute of the service.
+ *
+ * @return The ranking value to use when advertising the service.
+ */
+ int getRanking();
+
+ /**
+ * Return the registration listeners to be notified when the service is
+ * registered and unregistered with the framework.
+ *
+ * This is specified by the <code>registration-listener</code> elements of
+ * the service.
+ *
+ * @return An immutable Collection of {@link RegistrationListener} objects
+ * to be notified when the service is registered and unregistered
+ * with the framework. The Collection is empty if no registration
+ * listeners are specified for the service.
+ */
+ Collection /* <RegistrationListener> */getRegistrationListeners();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java
new file mode 100644
index 0000000..e57577e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+import java.util.Collection;
+
+/**
+ * Metadata for a reference to an OSGi service. This is the base type for
+ * {@link ReferenceListMetadata} and {@link ReferenceMetadata}.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ServiceReferenceMetadata extends ComponentMetadata {
+
+ /**
+ * A matching service is required at all times.
+ *
+ * @see #getAvailability()
+ */
+ static final int AVAILABILITY_MANDATORY = 1;
+
+ /**
+ * A matching service is not required to be present.
+ *
+ * @see #getAvailability()
+ */
+ static final int AVAILABILITY_OPTIONAL = 2;
+
+ /**
+ * Return whether or not a matching service is required at all times.
+ *
+ * This is specified in the <code>availability</code> attribute of the
+ * service reference.
+ *
+ * @return Whether or not a matching service is required at all times.
+ * @see #AVAILABILITY_MANDATORY
+ * @see #AVAILABILITY_OPTIONAL
+ */
+ int getAvailability();
+
+ /**
+ * Return the name of the interface type that a matching service must
+ * support.
+ *
+ * This is specified in the <code>interface</code> attribute of the service
+ * reference.
+ *
+ * @return The name of the interface type that a matching service must
+ * support or <code>null</code> when no interface name is specified.
+ */
+ String getInterface();
+
+ /**
+ * Return the value of the <code>component-name</code> attribute of the
+ * service reference. This specifies the id of a component that is
+ * registered in the service registry. This will create an automatic filter,
+ * appended with the filter if set, to select this component based on its
+ * automatic <code>id</code> attribute.
+ *
+ * @return The value of the <code>component-name</code> attribute of the
+ * service reference or <code>null</code> if the attribute is not
+ * specified.
+ */
+ String getComponentName();
+
+ /**
+ * Return the filter expression that a matching service must match.
+ *
+ * This is specified by the <code>filter</code> attribute of the service
+ * reference.
+ *
+ * @return The filter expression that a matching service must match or
+ * <code>null</code> if a filter is not specified.
+ */
+ String getFilter();
+
+ /**
+ * Return the reference listeners to receive bind and unbind events.
+ *
+ * This is specified by the <code>reference-listener</code> elements of the
+ * service reference.
+ *
+ * @return An immutable Collection of {@link ReferenceListener} objects to
+ * receive bind and unbind events. The Collection is empty if no
+ * reference listeners are specified for the service reference.
+ */
+ Collection /* <ReferenceListener> */getReferenceListeners();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Target.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Target.java
new file mode 100644
index 0000000..a96a4b0
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Target.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * A common interface for managed components that can be used as a direct target
+ * for method calls. These are <code>bean</code>, <code>reference</code>, and
+ * <code>ref</code>, where the <code>ref</code> must refer to a bean or
+ * reference component.
+ *
+ * @see BeanMetadata
+ * @see ReferenceMetadata
+ * @see RefMetadata
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface Target extends NonNullMetadata {
+ // marker interface
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ValueMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ValueMetadata.java
new file mode 100644
index 0000000..7609234
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ValueMetadata.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.blueprint.reflect;
+
+/**
+ * Metadata for a simple <code>String</code> value that will be type-converted
+ * if necessary before injecting.
+ *
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ValueMetadata extends NonNullMetadata {
+ /**
+ * Return the unconverted string representation of the value.
+ *
+ * This is specified by the <code>value</code> attribute or text part of the
+ * <code>value</code> element.
+ *
+ * @return The unconverted string representation of the value.
+ */
+ String getStringValue();
+
+ /**
+ * Return the name of the type to which the value should be converted.
+ *
+ * This is specified by the <code>type</code> attribute.
+ *
+ * @return The name of the type to which the value should be converted or
+ * <code>null</code> if no type is specified.
+ */
+ String getType();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/package.html
new file mode 100644
index 0000000..534999d
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/package.html
@@ -0,0 +1,14 @@
+<!-- $Revision: 7556 $ -->
+<BODY>
+<p>Blueprint Reflection Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.blueprint.reflect; version="[1.0,2.0)"
+</pre>
+<p> This package provides a reflection-based view of the configuration information for a
+ Blueprint Container.
+</p>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java
index af6d739..7c17cf1 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/Configuration.java,v 1.17 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +58,7 @@
* Managed Service Factory and a Managed Service. When it is important to
* differentiate between these two the term "factory configuration" is used.
*
- * @version $Revision: 1.17 $
+ * @version $Revision: 5673 $
*/
public interface Configuration {
/**
@@ -109,7 +107,7 @@
* callback is delayed until aforementioned registration occurs.
*
* <p>
- * Also intiates an asynchronous call to all
+ * Also initiates an asynchronous call to all
* <code>ConfigurationListener</code>s with a
* <code>ConfigurationEvent.CM_UPDATED</code> event.
*
@@ -133,7 +131,7 @@
* call to its <code>deleted</code> method.
*
* <p>
- * Also intiates an asynchronous call to all
+ * Also initiates an asynchronous call to all
* <code>ConfigurationListener</code>s with a
* <code>ConfigurationEvent.CM_DELETED</code> event.
*
@@ -160,7 +158,7 @@
*
* <p>
* This is the only way for a bundle that uses a Configuration Plugin
- * service to initate a callback. For example, when that bundle detects a
+ * service to initiate a callback. For example, when that bundle detects a
* change that requires an update of the Managed Service or Managed Service
* Factory via its <code>ConfigurationPlugin</code> object.
*
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
index 131f863..066548f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationAdmin.java,v 1.17 2006/09/26 13:33:09 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,27 +48,28 @@
* <p>
* Bundles that require configuration should register a Managed Service or a
* Managed Service Factory in the service registry. A registration property
- * named <code>service.pid</code> (persistent identifier or PID) must be used
- * to identify this Managed Service or Managed Service Factory to the
- * Configuration Admin service.
+ * named <code>service.pid</code> (persistent identifier or PID) must be used to
+ * identify this Managed Service or Managed Service Factory to the Configuration
+ * Admin service.
*
* <p>
* When the ConfigurationAdmin detects the registration of a Managed Service, it
- * checks its persistent storage for a configuration object whose PID matches
- * the PID registration property (<code>service.pid</code>) of the Managed
- * Service. If found, it calls {@link ManagedService#updated} method with the
- * new properties. The implementation of a Configuration Admin service must run
- * these call-backs asynchronously to allow proper synchronization.
+ * checks its persistent storage for a configuration object whose
+ * <code>service.pid</code> property matches the PID service property (
+ * <code>service.pid</code>) of the Managed Service. If found, it calls
+ * {@link ManagedService#updated} method with the new properties. The
+ * implementation of a Configuration Admin service must run these call-backs
+ * asynchronously to allow proper synchronization.
*
* <p>
* When the Configuration Admin service detects a Managed Service Factory
* registration, it checks its storage for configuration objects whose
- * <code>factoryPid</code> matches the PID of the Managed Service Factory. For
- * each such <code>Configuration</code> objects, it calls the
- * <code>ManagedServiceFactory.updated</code> method asynchronously with the
- * new properties. The calls to the <code>updated</code> method of a
- * <code>ManagedServiceFactory</code> must be executed sequentially and not
- * overlap in time.
+ * <code>service.factoryPid</code> property matches the PID service property of
+ * the Managed Service Factory. For each such <code>Configuration</code>
+ * objects, it calls the <code>ManagedServiceFactory.updated</code> method
+ * asynchronously with the new properties. The calls to the <code>updated</code>
+ * method of a <code>ManagedServiceFactory</code> must be executed sequentially
+ * and not overlap in time.
*
* <p>
* In general, bundles having permission to use the Configuration Admin service
@@ -79,16 +78,16 @@
* <code>ConfigurationPermission[*,CONFIGURE]</code>.
*
* <p>
- * <code>Configuration</code> objects can be <i>bound </i> to a specified
- * bundle location. In this case, if a matching Managed Service or Managed
- * Service Factory is registered by a bundle with a different location, then the
+ * <code>Configuration</code> objects can be <i>bound </i> to a specified bundle
+ * location. In this case, if a matching Managed Service or Managed Service
+ * Factory is registered by a bundle with a different location, then the
* Configuration Admin service must not do the normal callback, and it should
* log an error. In the case where a <code>Configuration</code> object is not
* bound, its location field is <code>null</code>, the Configuration Admin
* service will bind it to the location of the bundle that registers the first
* Managed Service or Managed Service Factory that has a corresponding PID
* property. When a <code>Configuration</code> object is bound to a bundle
- * location in this manner, the Confguration Admin service must detect if the
+ * location in this manner, the Configuration Admin service must detect if the
* bundle corresponding to the location is uninstalled. If this occurs, the
* <code>Configuration</code> object is unbound, that is its location field is
* set back to <code>null</code>.
@@ -100,20 +99,20 @@
* <code>ConfigurationAdmin</code> must use a
* {@link org.osgi.framework.ServiceFactory} to support this concept.
*
- * @version $Revision: 1.17 $
+ * @version $Revision: 7356 $
*/
public interface ConfigurationAdmin {
/**
- * Service property naming the Factory PID in the configuration dictionary.
- * The property's value is of type <code>String</code>.
+ * Configuration property naming the Factory PID in the configuration
+ * dictionary. The property's value is of type <code>String</code>.
*
* @since 1.1
*/
public final static String SERVICE_FACTORYPID = "service.factoryPid";
/**
- * Service property naming the location of the bundle that is associated
- * with a a <code>Configuration</code> object. This property can be
- * searched for but must not appear in the configuration dictionary for
+ * Configuration property naming the location of the bundle that is
+ * associated with a a <code>Configuration</code> object. This property can
+ * be searched for but must not appear in the configuration dictionary for
* security reason. The property's value is of type <code>String</code>.
*
* @since 1.1
@@ -226,26 +225,26 @@
*
* <p>
* Normally only <code>Configuration</code> objects that are bound to the
- * location of the calling bundle are returned, or all if the caller has
+ * location of the calling bundle are returned, or all if the caller has
* <code>ConfigurationPermission[*,CONFIGURE]</code>.
*
* <p>
- * The syntax of the filter string is as defined in the {@link org.osgi.framework.Filter}
- * class. The filter can test any configuration parameters including the
- * following system properties:
+ * The syntax of the filter string is as defined in the
+ * {@link org.osgi.framework.Filter} class. The filter can test any
+ * configuration properties including the following:
* <ul>
- * <li><code>service.pid</code>-<code>String</code>- the PID under
- * which this is registered</li>
- * <li><code>service.factoryPid</code>-<code>String</code>- the
- * factory if applicable</li>
- * <li><code>service.bundleLocation</code>-<code>String</code>- the
- * bundle location</li>
+ * <li><code>service.pid</code>-<code>String</code>- the PID under which
+ * this is registered</li>
+ * <li><code>service.factoryPid</code>-<code>String</code>- the factory if
+ * applicable</li>
+ * <li><code>service.bundleLocation</code>-<code>String</code>- the bundle
+ * location</li>
* </ul>
* The filter can also be <code>null</code>, meaning that all
* <code>Configuration</code> objects should be returned.
*
- * @param filter A filter string, or <code>null</code> to
- * retrieve all <code>Configuration</code> objects.
+ * @param filter A filter string, or <code>null</code> to retrieve all
+ * <code>Configuration</code> objects.
* @return All matching <code>Configuration</code> objects, or
* <code>null</code> if there aren't any.
* @throws IOException if access to persistent storage fails
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
index 3e1b776..f17007f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationEvent.java,v 1.9 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +15,8 @@
*/
package org.osgi.service.cm;
+import java.util.Dictionary;
+
import org.osgi.framework.ServiceReference;
/**
@@ -46,7 +46,7 @@
*
* @see ConfigurationListener
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 6180 $
* @since 1.2
*/
public class ConfigurationEvent {
@@ -57,7 +57,7 @@
* This <code>ConfigurationEvent</code> type that indicates that a
* <code>Configuration</code> object has been updated with new properties.
*
- * An event is fired when a call to <code>Configuration.update</code>
+ * An event is fired when a call to {@link Configuration#update(Dictionary)}
* successfully changes a configuration.
*
* <p>
@@ -71,7 +71,7 @@
* This <code>ConfigurationEvent</code> type that indicates that a
* <code>Configuration</code> object has been deleted.
*
- * An event is fired when a call to <code>Configuration.delete</code>
+ * An event is fired when a call to {@link Configuration#delete()}
* successfully deletes a configuration.
*
* <p>
@@ -116,6 +116,9 @@
this.type = type;
this.factoryPid = factoryPid;
this.pid = pid;
+ if ((reference == null) || (pid == null)) {
+ throw new NullPointerException("reference and pid must not be null");
+ }
}
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java
index dbbf216..300f5c8 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationException.java,v 1.13 2006/07/11 13:15:52 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +19,7 @@
* An <code>Exception</code> class to inform the Configuration Admin service
* of problems with configuration data.
*
- * @version $Revision: 1.13 $
+ * @version $Revision: 6083 $
*/
public class ConfigurationException extends Exception {
static final long serialVersionUID = -1690090413441769377L;
@@ -30,11 +28,6 @@
private final String reason;
/**
- * Nested exception.
- */
- private final Throwable cause;
-
- /**
* Create a <code>ConfigurationException</code> object.
*
* @param property name of the property that caused the problem,
@@ -45,7 +38,6 @@
super(property + " : " + reason);
this.property = property;
this.reason = reason;
- this.cause = null;
}
/**
@@ -59,10 +51,9 @@
*/
public ConfigurationException(String property, String reason,
Throwable cause) {
- super(property + " : " + reason);
+ super(property + " : " + reason, cause);
this.property = property;
this.reason = reason;
- this.cause = cause;
}
/**
@@ -83,30 +74,31 @@
public String getReason() {
return reason;
}
-
+
/**
- * Returns the cause of this exception or <code>null</code> if no cause
- * was specified when this exception was created.
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
*
- * @return The cause of this exception or <code>null</code> if no cause
- * was specified.
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
* @since 1.2
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
}
/**
- * The cause of this exception can only be set when constructed.
+ * Initializes the cause of this exception to the specified value.
*
- * @param cause Cause of the exception.
- * @return This object.
- * @throws java.lang.IllegalStateException This method will always throw an
- * <code>IllegalStateException</code> since the cause of this
- * exception can only be set when constructed.
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
* @since 1.2
*/
public Throwable initCause(Throwable cause) {
- throw new IllegalStateException();
+ return super.initCause(cause);
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java
index a171f90..5d7793d 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationListener.java,v 1.10 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +35,7 @@
* require <code>ServicePermission[ConfigurationListener,REGISTER]</code> to
* register a <code>ConfigurationListener</code> service.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
* @since 1.2
*/
public interface ConfigurationListener {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
index f4901b8..3af9088 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPermission.java,v 1.22 2006/07/08 00:42:00 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +16,9 @@
package org.osgi.service.cm;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
import java.util.Enumeration;
import java.util.NoSuchElementException;
@@ -27,7 +27,8 @@
*
* This permission has only a single action: CONFIGURE.
*
- * @version $Revision: 1.22 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
* @since 1.2
*/
@@ -92,7 +93,9 @@
*/
public int hashCode() {
- return getName().hashCode() ^ getActions().hashCode();
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
}
/**
@@ -135,7 +138,7 @@
*
* @serial
*/
- private boolean hasElement;
+ private volatile boolean hasElement;
/**
* Creates an empty <tt>ConfigurationPermissionCollection</tt> object.
@@ -214,5 +217,4 @@
}
};
}
-
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
index d3206f8..574466e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPlugin.java,v 1.11 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +32,7 @@
* <code>ManagedServiceFactory</code>
* <code>updated</code> method. The
* Configuration Plugin service thus has the opportunity to view and modify the
- * properties before they are passed to the ManagedS ervice or Managed Service
+ * properties before they are passed to the Managed Service or Managed Service
* Factory.
*
* <p>
@@ -71,12 +69,12 @@
* A plugin may optionally specify a <code>cm.target</code> registration
* property whose value is the PID of the Managed Service or Managed Service
* Factory whose configuration updates the plugin is intended to intercept. The
- * plugin will then only be called with configuration updates that are targetted
+ * plugin will then only be called with configuration updates that are targeted
* at the Managed Service or Managed Service Factory with the specified PID.
* Omitting the <code>cm.target</code> registration property means that the
* plugin is called for all configuration updates.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
*/
public interface ConfigurationPlugin {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java
index d4e30a2..6812434 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ManagedService.java,v 1.12 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +24,7 @@
* <p>
* A Managed Service is a service that needs configuration data. Such an object
* should be registered with the Framework registry with the
- * <code>service.pid</code> property set to some unique identitifier called a
+ * <code>service.pid</code> property set to some unique identifier called a
* PID.
*
* <p>
@@ -107,7 +105,7 @@
* registration properties. This will allow the Configuration Admin service to
* set properties on services which can then be used by other applications.
*
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
*/
public interface ManagedService {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
index 838df68..8c334c0 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ManagedServiceFactory.java,v 1.12 2006/07/11 00:54:03 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,7 +92,7 @@
*
* </pre>
*
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
*/
public interface ManagedServiceFactory {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/cm/package.html
new file mode 100644
index 0000000..0234320
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 7356 $ -->
+<BODY>
+<p>Configuration Admin Package Version 1.3.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.cm; version="[1.3,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/cm/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java
index 34b0388..2f9d089 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentConstants.java,v 1.14 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,13 +19,12 @@
/**
* Defines standard names for Service Component constants.
*
- * @version $Revision: 1.14 $
+ * @version $Revision: 6454 $
*/
public interface ComponentConstants {
/**
- * Manifest header (named "Service-Component") specifying the XML
- * documents within a bundle that contain the bundle's Service Component
- * descriptions.
+ * Manifest header specifying the XML documents within a bundle that contain
+ * the bundle's Service Component descriptions.
* <p>
* The attribute value may be retrieved from the <code>Dictionary</code>
* object returned by the <code>Bundle.getHeaders</code> method.
@@ -37,14 +34,15 @@
/**
* A component property for a component configuration that contains the name
* of the component as specified in the <code>name</code> attribute of the
- * <code>component</code> element. The type of this property must be
- * <code>String</code>.
+ * <code>component</code> element. The value of this property must be of
+ * type <code>String</code>.
*/
public final static String COMPONENT_NAME = "component.name";
/**
* A component property that contains the generated id for a component
- * configuration. The type of this property must be <code>Long</code>.
+ * configuration. The value of this property must be of type
+ * <code>Long</code>.
*
* <p>
* The value of this property is assigned by the Service Component Runtime
@@ -57,15 +55,64 @@
/**
* A service registration property for a Component Factory that contains the
- * value of the <code>factory</code> attribute. The type of this property
- * must be <code>String</code>.
+ * value of the <code>factory</code> attribute. The value of this property
+ * must be of type <code>String</code>.
*/
public final static String COMPONENT_FACTORY = "component.factory";
/**
* The suffix for reference target properties. These properties contain the
- * filter to select the target services for a reference. The type of this
- * property must be <code>String</code>.
+ * filter to select the target services for a reference. The value of this
+ * property must be of type <code>String</code>.
*/
public final static String REFERENCE_TARGET_SUFFIX = ".target";
+
+ /**
+ * The reason the component configuration was deactivated is unspecified.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_UNSPECIFIED = 0;
+
+ /**
+ * The component configuration was deactivated because the component was disabled.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_DISABLED = 1;
+
+ /**
+ * The component configuration was deactivated because a reference became unsatisfied.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_REFERENCE = 2;
+
+ /**
+ * The component configuration was deactivated because its configuration was changed.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_CONFIGURATION_MODIFIED = 3;
+
+ /**
+ * The component configuration was deactivated because its configuration was deleted.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_CONFIGURATION_DELETED = 4;
+
+ /**
+ * The component configuration was deactivated because the component was disposed.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_DISPOSED = 5;
+
+ /**
+ * The component configuration was deactivated because the bundle was stopped.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_BUNDLE_STOPPED = 6;
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java
index c763293..aad348c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentContext.java,v 1.20 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +18,9 @@
import java.util.Dictionary;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
/**
* A Component Context object is used by a component instance to interact with
@@ -28,38 +28,31 @@
* component instance has a unique Component Context.
*
* <p>
- * A component's implementation class may optionaly implement an activate
- * method:
- *
- * <pre>
- * protected void activate(ComponentContext context);
- * </pre>
- *
- * If a component implements this method, this method will be called when a
- * component configuration is activated to provide the component instance's
- * Component Context object.
+ * A component instance may have an activate method. If a component instance has
+ * a suitable and accessible activate method, this method will be called when a
+ * component configuration is activated. If the activate method takes a
+ * <code>ComponentContext</code> argument, it will be passed the component
+ * instance's Component Context object. If the activate method takes a
+ * <code>BundleContext</code> argument, it will be passed the component
+ * instance's Bundle Context object. If the activate method takes a
+ * <code>Map</code> argument, it will be passed an unmodifiable Map containing
+ * the component properties.
*
* <p>
- * A component's implementation class may optionaly implement a deactivate
- * method:
+ * A component instance may have a deactivate method. If a component instance
+ * has a suitable and accessible deactivate method, this method will be called
+ * when the component configuration is deactivated. If the deactivate method
+ * takes a <code>ComponentContext</code> argument, it will be passed the
+ * component instance's Component Context object. If the deactivate method takes
+ * a <code>BundleContext</code> argument, it will be passed the component
+ * instance's Bundle Context object. If the deactivate method takes a
+ * <code>Map</code> argument, it will be passed an unmodifiable Map containing
+ * the component properties. If the deactivate method takes an <code>int</code>
+ * or <code>Integer</code> argument, it will be passed the reason code for the
+ * component instance's deactivation.
*
- * <pre>
- * protected void deactivate(ComponentContext context);
- * </pre>
- *
- * If a component implements this method, this method will be called when the
- * component configuration is deactivated.
- *
- * <p>
- * The activate and deactivate methods will be called using reflection and must
- * be protected or public accessible. These methods should not be public methods
- * so that they do not appear as public methods on the component instance when
- * used as a service object. These methods will be located by looking through
- * the component's implementation class hierarchy for the first declaration of
- * the method. If the method is found, if it is declared protected or public,
- * the method will be called. Otherwise, the method will not be called.
- *
- * @version $Revision: 1.20 $
+ * @ThreadSafe
+ * @version $Revision: 6462 $
*/
public interface ComponentContext {
/**
@@ -77,10 +70,10 @@
* If the cardinality of the reference is <code>0..n</code> or
* <code>1..n</code> and multiple services are bound to the reference, the
* service with the highest ranking (as specified in its
- * <code>Constants.SERVICE_RANKING</code> 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</code> property); that is, the
- * service that was registered first is returned.
+ * <code>Constants.SERVICE_RANKING</code> 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</code> property); that is, the service
+ * that was registered first is returned.
*
* @param name The name of a reference as specified in a
* <code>reference</code> element in this component's description.
@@ -117,16 +110,18 @@
* <code>reference</code> element in this component's description.
* @return An array of service objects for the referenced service or
* <code>null</code> if the reference cardinality is
- * <code>0..1</code> or <code>0..n</code> and no bound service
- * is available.
+ * <code>0..1</code> or <code>0..n</code> and no bound service is
+ * available. If the reference cardinality is <code>0..1</code> or
+ * <code>1..1</code> and a bound service is available, the array
+ * will have exactly one element.
* @throws ComponentException If the Service Component Runtime catches an
* exception while activating a bound service.
*/
public Object[] locateServices(String name);
/**
- * Returns the <code>BundleContext</code> of the bundle which contains
- * this component.
+ * Returns the <code>BundleContext</code> of the bundle which contains this
+ * component.
*
* @return The <code>BundleContext</code> of the bundle containing this
* component.
@@ -135,20 +130,19 @@
/**
* If the component instance is registered as a service using the
- * <code>servicefactory="true"</code> attribute, then this
- * method returns the bundle using the service provided by the component
- * instance.
+ * <code>servicefactory="true"</code> attribute, then this method
+ * returns the bundle using the service provided by the component instance.
* <p>
* This method will return <code>null</code> if:
* <ul>
* <li>The component instance is not a service, then no bundle can be using
* it as a service.
* <li>The component instance is a service but did not specify the
- * <code>servicefactory="true"</code> attribute, then all
- * bundles using the service provided by the component instance will share
- * the same component instance.
- * <li>The service provided by the component instance is not currently
- * being used by any bundle.
+ * <code>servicefactory="true"</code> attribute, then all bundles
+ * using the service provided by the component instance will share the same
+ * component instance.
+ * <li>The service provided by the component instance is not currently being
+ * used by any bundle.
* </ul>
*
* @return The bundle using the component instance as a service or
@@ -168,8 +162,8 @@
* Enables the specified component name. The specified component name must
* be in the same bundle as this component.
*
- * @param name The name of a component or <code>null</code> to indicate
- * all components in the bundle.
+ * @param name The name of a component or <code>null</code> to indicate all
+ * components in the bundle.
*/
public void enableComponent(String name);
@@ -194,5 +188,4 @@
* registered as a service.
*/
public ServiceReference getServiceReference();
-
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java
index be539a9..0aee948 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentException.java,v 1.13 2006/07/11 13:15:56 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,14 +19,10 @@
/**
* Unchecked exception which may be thrown by the Service Component Runtime.
*
- * @version $Revision: 1.13 $
+ * @version $Revision: 6083 $
*/
public class ComponentException extends RuntimeException {
static final long serialVersionUID = -7438212656298726924L;
- /**
- * Nested exception.
- */
- private final Throwable cause;
/**
* Construct a new ComponentException with the specified message and cause.
@@ -37,8 +31,7 @@
* @param cause The cause of the exception. May be <code>null</code>.
*/
public ComponentException(String message, Throwable cause) {
- super(message);
- this.cause = cause;
+ super(message, cause);
}
/**
@@ -48,7 +41,6 @@
*/
public ComponentException(String message) {
super(message);
- this.cause = null;
}
/**
@@ -57,31 +49,31 @@
* @param cause The cause of the exception. May be <code>null</code>.
*/
public ComponentException(Throwable cause) {
- super();
- this.cause = cause;
+ super(cause);
}
-
+
/**
- * Returns the cause of this exception or <code>null</code> if no cause
- * was specified when this exception was created.
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
*
- * @return The cause of this exception or <code>null</code> if no cause
- * was specified.
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
}
/**
- * The cause of this exception can only be set when constructed.
+ * Initializes the cause of this exception to the specified value.
*
- * @param cause Cause of the exception.
- * @return This object.
- * @throws java.lang.IllegalStateException This method will always throw an
- * <code>IllegalStateException</code> since the cause of this
- * exception can only be set when constructed.
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
*/
public Throwable initCause(Throwable cause) {
- throw new IllegalStateException();
+ return super.initCause(cause);
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java
index 8dc522a..1c77177 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentFactory.java,v 1.19 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +25,8 @@
* created and activated rather than automatically creating and activating
* component configuration as necessary.
*
- * @version $Revision: 1.19 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
*/
public interface ComponentFactory {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java
index 9f2d9f5..f2bd2cb 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentInstance.java,v 1.13 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +25,8 @@
* ComponentInstances are never reused. A new ComponentInstance object will be
* created when the component configuration is activated again.
*
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
*/
public interface ComponentInstance {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/component/package.html
new file mode 100644
index 0000000..2e7717e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Service Component Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.component; version="[1.1,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/component/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
index 9bd31fb..f945e6a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/BundleInfo.java,v 1.3 2006/06/16 16:31:39 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
index 9376d14..0415c68 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentAdmin.java,v 1.28 2007/02/07 18:53:07 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
index 34509cf..f329e77 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java,v 1.40 2006/07/12 21:22:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +19,10 @@
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.security.*;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
import org.osgi.framework.Bundle;
@@ -191,7 +192,7 @@
return c.getConstructor(new Class[] {String.class, String.class});
}
catch (Exception e) {
- throw new RuntimeException(e.getMessage());
+ throw new RuntimeException(e);
}
}});
}
@@ -224,7 +225,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
index bf5c6e6..4cda326 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentException.java,v 1.20 2006/07/12 21:22:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -203,8 +201,6 @@
public static final int CODE_TIMEOUT = 465;
private final int code;
- private final String message;
- private final Throwable cause;
/**
* Create an instance of the exception.
@@ -215,9 +211,8 @@
* @param cause the originating exception
*/
public DeploymentException(int code, String message, Throwable cause) {
+ super(message, cause);
this.code = code;
- this.message = message;
- this.cause = cause;
}
/**
@@ -229,7 +224,8 @@
* @param message Message associated with the exception
*/
public DeploymentException(int code, String message) {
- this(code, message, null);
+ super(message);
+ this.code = code;
}
/**
@@ -240,14 +236,34 @@
* predefined integer values (<code>CODE_X</code>).
*/
public DeploymentException(int code) {
- this(code, null, null);
+ super();
+ this.code = code;
}
/**
- * @return Returns the cause.
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
+ *
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
+ }
+
+ /**
+ * Initializes the cause of this exception to the specified value.
+ *
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ * @since 1.1
+ */
+ public Throwable initCause(Throwable cause) {
+ return super.initCause(cause);
}
/**
@@ -256,11 +272,4 @@
public int getCode() {
return code;
}
-
- /**
- * @return Returns the message.
- */
- public String getMessage() {
- return message;
- }
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
index 0155771..6b3e54f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentPackage.java,v 1.26 2006/07/12 21:22:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,223 +16,347 @@
package org.osgi.service.deploymentadmin;
-import org.osgi.framework.*;
+import java.net.URL;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
/**
- * The <code>DeploymentPackage</code> object represents a deployment package (already installed
- * or being currently processed). A Deployment Package groups resources as a unit
- * of management. A deployment package is something that can be installed, updated,
- * and uninstalled as a unit. A deployment package is a reified concept, like a bundle,
- * in an OSGi Service Platform. It is not known by the OSGi Framework, but it is managed
- * by the Deployment Admin service. A deployment package is a stream of resources
- * (including bundles) which, once processed, will result in new artifacts (effects on
- * the system) being added to the OSGi platform. These new artifacts can include
- * installed Bundles, new configuration objects added to the Configuration Admin service,
- * new Wire objects added to the Wire Admin service, or changed system properties, etc. All
- * the changes caused by the processing of a deployment package are persistently
- * associated with the deployment package, so that they can be appropriately cleaned
- * up when the deployment package is uninstalled. There is a strict no overlap rule
- * imposed on deployment packages. Two deployment packages are not allowed to create or
- * manipulate the same artifact. Obviously, this means that a bundle cannot be in two
- * different deployment packagess. Any violation of this no overlap rule is considered
- * an error and the install or update of the offending deployment package must be aborted.<p>
- *
- * The Deployment Admin service should do as much as possible to ensure transactionality.
- * It means that if a deployment package installation, update or removal (uninstall) fails
- * all the side effects caused by the process should be disappeared and the system
- * should be in the state in which it was before the process.<p>
- *
- * If a deployment package is being updated the old version is visible through the
- * <code>DeploymentPackage</code> interface until the update process ends. After the
- * package is updated the updated version is visible and the old one is not accessible
- * any more.
- */
+ * The <code>DeploymentPackage</code> object represents a deployment package
+ * (already installed or being currently processed). A Deployment Package groups
+ * resources as a unit of management. A deployment package is something that can
+ * be installed, updated, and uninstalled as a unit. A deployment package is a
+ * reified concept, like a bundle, in an OSGi Service Platform. It is not known
+ * by the OSGi Framework, but it is managed by the Deployment Admin service. A
+ * deployment package is a stream of resources (including bundles) which, once
+ * processed, will result in new artifacts (effects on the system) being added
+ * to the OSGi platform. These new artifacts can include installed Bundles, new
+ * configuration objects added to the Configuration Admin service, new Wire
+ * objects added to the Wire Admin service, or changed system properties, etc.
+ * All the changes caused by the processing of a deployment package are
+ * persistently associated with the deployment package, so that they can be
+ * appropriately cleaned up when the deployment package is uninstalled. There is
+ * a strict no overlap rule imposed on deployment packages. Two deployment
+ * packages are not allowed to create or manipulate the same artifact.
+ * Obviously, this means that a bundle cannot be in two different deployment
+ * packages. Any violation of this no overlap rule is considered an error and
+ * the install or update of the offending deployment package must be aborted.
+ * <p>
+ *
+ * The Deployment Admin service should do as much as possible to ensure
+ * transactionality. It means that if a deployment package installation, update
+ * or removal (uninstall) fails all the side effects caused by the process
+ * should be disappeared and the system should be in the state in which it was
+ * before the process.
+ * <p>
+ *
+ * If a deployment package is being updated the old version is visible through
+ * the <code>DeploymentPackage</code> interface until the update process ends.
+ * After the package is updated the updated version is visible and the old one
+ * is not accessible any more.
+ */
public interface DeploymentPackage {
-
/**
- * Gives back the state of the deployment package whether it is stale or not).
- * After uninstall of a deployment package it becomes stale. Any active method calls to a
- * stale deployment package raise {@link IllegalStateException}.
- * Active methods are the following:<p>
- *
- * <ul>
- * <li>{@link #getBundle(String)}</li>
- * <li>{@link #getResourceProcessor(String)}</li>
- * <li>{@link #uninstall()}</li>
- * <li>{@link #uninstallForced()}</li>
- * </ul>
- *
- * @return <code>true</code> if the deployment package is stale. <code>false</code>
- * otherwise
- * @see #uninstall
- * @see #uninstallForced
+ * The name of the Deployment Package. This name is the same name as that
+ * specified in the DeploymentPackage-SymbolicName Manifest header.
+ *
+ * @since 1.1
*/
- boolean isStale();
-
+ String EVENT_DEPLOYMENTPACKAGE_NAME = "deploymentpackage.name";
+
/**
- * Returns the Deployment Pacakage Symbolic Name of the package.
+ * The human readable name of the DP localized to the default locale.
+ *
+ * @since 1.1
+ */
+ String EVENT_DEPLOYMENTPACKAGE_READABLENAME = "deploymentpackage.readablename";
+
+ /**
+ * The currently installed version of the Deployment Package. The attribute
+ * is not present, if no version is installed:
+ * <ul>
+ * <li>in the INSTALL event, when an installDeploymentPackage was called and
+ * no earlier version is present
+ * <li>in the COMPLETE event after the _successfully_ completing an
+ * uninstallDeploymentPackage call
+ * </ul>
+ * The value for this event must be a Version object.
+ *
+ * @since 1.1
+ */
+ String EVENT_DEPLOYMENTPACKAGE_CURRENTVERSION = "deploymentpackage.currentversion";
+
+ /**
+ * The version of DP after the successful completion of the install
+ * operation (used in INSTALL event only).
+ *
+ * The value for this event must be a Version object.
+ *
+ * @since 1.1
+ */
+ String EVENT_DEPLOYMENTPACKAGE_NEXTVERSION = "deploymentpackage.nextversion";
+
+ /**
+ * Gives back the state of the deployment package whether it is stale or
+ * not). After uninstall of a deployment package it becomes stale. Any
+ * active method calls to a stale deployment package raise
+ * {@link IllegalStateException}. Active methods are the following:
+ * <p>
+ *
+ * <ul>
+ * <li>{@link #getBundle(String)}</li>
+ * <li>{@link #getResourceProcessor(String)}</li>
+ * <li>{@link #uninstall()}</li>
+ * <li>{@link #uninstallForced()}</li>
+ * </ul>
+ *
+ * @return <code>true</code> if the deployment package is stale.
+ * <code>false</code> otherwise
+ * @see #uninstall
+ * @see #uninstallForced
+ */
+ boolean isStale();
+
+ /**
+ * Returns the Deployment Package Symbolic Name of the package.
*
* @return The name of the deployment package. It cannot be null.
*/
String getName();
-
+
+ /**
+ * Returns the Deployment Package human readable name.
+ *
+ * This method returns the localized human readable name as set with the
+ * <code>DeploymentPackage-Name</code> manifest header using the default
+ * locale. If no header is set, this method will return <code>null</code>.
+ *
+ * @return The human readable name of the deployment package or
+ * <code>null</code> if header is not set.
+ * @since 1.1
+ */
+ String getDisplayName();
+
/**
* Returns the version of the deployment package.
+ *
* @return version of the deployment package. It cannot be null.
*/
Version getVersion();
-
+
/**
- * Returns an array of {@link BundleInfo} objects representing the bundles specified in the manifest
- * of this deployment package. Its size is equal to the number of the bundles in the deployment package.
+ * Returns an array of {@link BundleInfo} objects representing the bundles
+ * specified in the manifest of this deployment package. Its size is equal
+ * to the number of the bundles in the deployment package.
*
- * @return array of <code>BundleInfo</code> objects
- * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
- * with "metadata" action
+ * @return array of <code>BundleInfo</code> objects
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission} with "metadata" action
*/
- BundleInfo[] getBundleInfos();
-
- /**
- * Returns the bundle instance, which is part of this deployment package, that corresponds
- * to the bundle's symbolic name passed in the <code>symbolicName</code> parameter.
- * This method will return null for request for bundles that are not part
- * of this deployment package.<p>
- *
- * As this instance is transient (i.e. a bundle can be removed at any time because of the
- * dynamic nature of the OSGi platform), this method may also return null if the bundle
- * is part of this deployment package, but is not currently defined to the framework.
- *
- * @param symbolicName the symbolic name of the requested bundle
- * @return The <code>Bundle</code> instance for a given bundle symbolic name.
- * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
- * with "metadata" action
- * @throws IllegalStateException if the package is stale
- */
- Bundle getBundle(String symbolicName);
-
- /**
- * Returns an array of strings representing the resources (including bundles) that
- * are specified in the manifest of this deployment package. A string element of the
- * array is the same as the value of the "Name" attribute in the manifest. The array
- * contains the bundles as well.<p>
- *
- * E.g. if the "Name" section of the resource (or individual-section as the
- * <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Manifest%20Specification">Manifest Specification</a>
- * calls it) in the manifest is the following
+ BundleInfo[] getBundleInfos();
- * <pre>
- * Name: foo/readme.txt
- * Resource-Processor: foo.rp
- * </pre>
- *
- * then the corresponding array element is the "foo/readme.txt" string.<p>
- *
- * @return The string array corresponding to resources. It cannot be null but its
- * length can be zero.
- * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
- * with "metadata" action
- */
- String[] getResources();
-
- /**
- * At the time of deployment, resource processor service instances are located to
- * resources contained in a deployment package.<p>
- *
- * This call returns a service reference to the corresponding service instance.
- * If the resource is not part of the deployment package or this call is made during
- * deployment, prior to the locating of the service to process a given resource, null will
- * be returned. Services can be updated after a deployment package has been deployed.
- * In this event, this call will return a reference to the updated service, not to the
- * instance that was used at deployment time.
- *
- * @param resource the name of the resource (it is the same as the value of the "Name"
- * attribute in the deployment package's manifest)
- * @return resource processor for the resource or <code>null</cpde>.
- * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
- * with "metadata" action
- * @throws IllegalStateException if the package is stale
- */
- ServiceReference getResourceProcessor(String resource);
-
- /**
- * Returns the requested deployment package manifest header from the main section.
- * Header names are case insensitive. If the header doesn't exist it returns null.<p>
- *
- * If the header is localized then the localized value is returned (see OSGi Service Platform,
- * Mobile Specification Release 4 - Localization related chapters).
- *
- * @param header the requested header
- * @return the value of the header or <code>null</code> if the header does not exist
- * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
- * with "metadata" action
- */
- String getHeader(String header);
-
- /**
- * Returns the requested deployment package manifest header from the name
- * section determined by the resource parameter. Header names are case insensitive.
- * If the resource or the header doesn't exist it returns null.<p>
- *
- * If the header is localized then the localized value is returned (see OSGi Service Platform,
- * Mobile Specification Release 4 - Localization related chapters).
-
- * @param resource the name of the resource (it is the same as the value of the "Name"
- * attribute in the deployment package's manifest)
- * @param header the requested header
- * @return the value of the header or <code>null</code> if the resource or the header doesn't exist
- * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
- * with "metadata" action
- */
- String getResourceHeader(String resource, String header);
-
/**
- * Uninstalls the deployment package. After uninstallation, the deployment package
- * object becomes stale. This can be checked by using {@link #isStale()},
- * which will return <code>true</code> when stale.<p>
- *
- * @throws DeploymentException if the deployment package could not be successfully uninstalled.
- * For detailed error code description see {@link DeploymentException}.
- * @throws SecurityException if the caller doesn't have the appropriate
- * {@link DeploymentAdminPermission}("<filter>", "uninstall") permission.
- * @throws IllegalStateException if the package is stale
- */
- void uninstall() throws DeploymentException;
-
- /**
- * This method is called to completely uninstall a deployment package, which couldn't be uninstalled
- * using traditional means ({@link #uninstall()}) due to exceptions. After uninstallation, the deployment
- * package object becomes stale. This can be checked by using {@link #isStale()},
- * which will return <code>true</code> when stale.<p>
- *
- * The method forces removal of the Deployment Package from the repository maintained by the
- * Deployment Admin service. This method follows the same steps as {@link #uninstall}. However,
- * any errors or the absence of Resource Processor services are ignored, they must not cause a roll back.
- * These errors should be logged.
- *
- * @return true if the operation was successful
- * @throws DeploymentException only {@link DeploymentException#CODE_TIMEOUT} and
- * {@link DeploymentException#CODE_CANCELLED} can be thrown. For detailed error code description
- * see {@link DeploymentException}.
- * @throws SecurityException if the caller doesn't have the appropriate
- * {@link DeploymentAdminPermission}("<filter>", "uninstall_forced") permission.
- * @throws IllegalStateException if the package is stale
- */
- boolean uninstallForced() throws DeploymentException;
-
- /**
- * Returns a hash code value for the object.
- *
- * @return a hash code value for this object
- */
- int hashCode();
-
- /**
- * Indicates whether some other object is "equal to" this one. Two deployment packages
- * are equal if they have the same deployment package symbolicname and version.
- *
- * @param other the reference object with which to compare.
- * @return true if this object is the same as the obj argument; false otherwise.
- */
- boolean equals(Object other);
-
+ * Returns a URL pointing to an image that represents the icon for this
+ * Deployment Package.
+ *
+ * The <code>DeploymentPackage-Icon</code> header can set an icon for the
+ * the deployment package. This method returns an absolute URL that is
+ * defined by this header. The Deployment Admin service must provide this
+ * icon as a local resource. That is, the Deployment Admin must make a local
+ * copy of the specified icon. The returned <code>URL</code>'s must point to
+ * a local resource.
+ *
+ * @return An absolute URL to a local (device resident) image resource or
+ * <code>null</code> if not found
+ * @since 1.1
+ */
+ URL getIcon();
+
+ /**
+ * Returns the bundle instance, which is part of this deployment package,
+ * that corresponds to the bundle's symbolic name passed in the
+ * <code>symbolicName</code> parameter. This method will return null for
+ * request for bundles that are not part of this deployment package.
+ * <p>
+ *
+ * As this instance is transient (i.e. a bundle can be removed at any time
+ * because of the dynamic nature of the OSGi platform), this method may also
+ * return null if the bundle is part of this deployment package, but is not
+ * currently defined to the framework.
+ *
+ * @param symbolicName
+ * the symbolic name of the requested bundle
+ * @return The <code>Bundle</code> instance for a given bundle symbolic
+ * name.
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission} with "metadata" action
+ * @throws IllegalStateException
+ * if the package is stale
+ */
+ Bundle getBundle(String symbolicName);
+
+ /**
+ * Returns an array of strings representing the resources (including
+ * bundles) that are specified in the manifest of this deployment package. A
+ * string element of the array is the same as the value of the "Name"
+ * attribute in the manifest. The array contains the bundles as well.
+ * <p>
+ *
+ * E.g. if the "Name" section of the resource (or individual-section as the
+ * <a
+ * href="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Manifest%20Specification">Manifest
+ * Specification</a> calls it) in the manifest is the following
+ *
+ * <pre>
+ * Name: foo/readme.txt
+ * Resource-Processor: foo.rp
+ * </pre>
+ *
+ * then the corresponding array element is the "foo/readme.txt" string.
+ * <p>
+ *
+ * @return The string array corresponding to resources. It cannot be null
+ * but its length can be zero.
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission} with "metadata" action
+ */
+ String[] getResources();
+
+ /**
+ * At the time of deployment, resource processor service instances are
+ * located to resources contained in a deployment package.
+ * <p>
+ *
+ * This call returns a service reference to the corresponding service
+ * instance. If the resource is not part of the deployment package or this
+ * call is made during deployment, prior to the locating of the service to
+ * process a given resource, null will be returned. Services can be updated
+ * after a deployment package has been deployed. In this event, this call
+ * will return a reference to the updated service, not to the instance that
+ * was used at deployment time.
+ *
+ * @param resource
+ * the name of the resource (it is the same as the value of the
+ * "Name" attribute in the deployment package's manifest)
+ * @return resource processor for the resource or <code>null</cpde>.
+ * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission}
+ * with "metadata" action
+ * @throws IllegalStateException if the package is stale
+ */
+ ServiceReference getResourceProcessor(String resource);
+
+ /**
+ * Returns the requested deployment package manifest header from the main
+ * section. Header names are case insensitive. If the header doesn't exist
+ * it returns null.
+ * <p>
+ *
+ * If the header is localized then the localized value is returned (see OSGi
+ * Service Platform, Mobile Specification Release 4 - Localization related
+ * chapters).
+ *
+ * @param header
+ * the requested header
+ * @return the value of the header or <code>null</code> if the header does
+ * not exist
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission} with "metadata" action
+ */
+ String getHeader(String header);
+
+ /**
+ * Returns the requested deployment package manifest header from the name
+ * section determined by the resource parameter. Header names are case
+ * insensitive. If the resource or the header doesn't exist it returns null.
+ * <p>
+ *
+ * If the header is localized then the localized value is returned (see OSGi
+ * Service Platform, Mobile Specification Release 4 - Localization related
+ * chapters).
+ *
+ * @param resource
+ * the name of the resource (it is the same as the value of the
+ * "Name" attribute in the deployment package's manifest)
+ * @param header
+ * the requested header
+ * @return the value of the header or <code>null</code> if the resource or
+ * the header doesn't exist
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission} with "metadata" action
+ */
+ String getResourceHeader(String resource, String header);
+
+ /**
+ * Uninstalls the deployment package. After uninstallation, the deployment
+ * package object becomes stale. This can be checked by using
+ * {@link #isStale()}, which will return <code>true</code> when stale.
+ * <p>
+ *
+ * @throws DeploymentException
+ * if the deployment package could not be successfully
+ * uninstalled. For detailed error code description see
+ * {@link DeploymentException}.
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission}("<filter>",
+ * "uninstall") permission.
+ * @throws IllegalStateException
+ * if the package is stale
+ */
+ void uninstall() throws DeploymentException;
+
+ /**
+ * This method is called to completely uninstall a deployment package, which
+ * couldn't be uninstalled using traditional means ({@link #uninstall()})
+ * due to exceptions. After uninstallation, the deployment package object
+ * becomes stale. This can be checked by using {@link #isStale()}, which
+ * will return <code>true</code> when stale.
+ * <p>
+ *
+ * The method forces removal of the Deployment Package from the repository
+ * maintained by the Deployment Admin service. This method follows the same
+ * steps as {@link #uninstall}. However, any errors or the absence of
+ * Resource Processor services are ignored, they must not cause a roll back.
+ * These errors should be logged.
+ *
+ * @return true if the operation was successful
+ * @throws DeploymentException
+ * only {@link DeploymentException#CODE_TIMEOUT} and
+ * {@link DeploymentException#CODE_CANCELLED} can be thrown. For
+ * detailed error code description see
+ * {@link DeploymentException}.
+ * @throws SecurityException
+ * if the caller doesn't have the appropriate
+ * {@link DeploymentAdminPermission}("<filter>",
+ * "uninstall_forced") permission.
+ * @throws IllegalStateException
+ * if the package is stale
+ */
+ boolean uninstallForced() throws DeploymentException;
+
+ /**
+ * Returns a hash code value for the object.
+ *
+ * @return a hash code value for this object
+ */
+ int hashCode();
+
+ /**
+ * Indicates whether some other object is "equal to" this one. Two
+ * deployment packages are equal if they have the same deployment package
+ * symbolicname and version.
+ *
+ * @param other
+ * the reference object with which to compare.
+ * @return true if this object is the same as the obj argument; false
+ * otherwise.
+ */
+ boolean equals(Object other);
+
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/package.html
new file mode 100644
index 0000000..5ba69e3
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Deployment Admin Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.deploymentadmin; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
index 681329e..fa4534f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
@@ -1,8 +1,6 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java,v 1.6 2006/06/21 15:16:13 hargrave Exp $
*
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +19,10 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.security.*;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
import org.osgi.service.deploymentadmin.DeploymentAdminPermission;
@@ -65,7 +66,7 @@
return c.getConstructor(new Class[] {String.class, String.class});
}
catch (Exception e) {
- throw new RuntimeException(e.getMessage());
+ throw new RuntimeException(e);
}
}});
}
@@ -112,7 +113,7 @@
throw e;
}
catch (Throwable e) {
- throw new RuntimeException(e.toString());
+ throw new RuntimeException(e);
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
index 87a5b1f..be2877c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/DeploymentSession.java,v 1.6 2006/06/16 16:31:39 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
index ec5a5fd..9951c13 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java,v 1.6 2006/07/11 13:19:02 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
index eb9c3dc..f677801 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java,v 1.7 2006/07/12 21:22:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,8 +58,6 @@
public static final int CODE_OTHER_ERROR = 463;
private final int code;
- private final String message;
- private final Throwable cause;
/**
* Create an instance of the exception.
@@ -72,9 +68,8 @@
* @param cause the originating exception
*/
public ResourceProcessorException(int code, String message, Throwable cause) {
+ super(message, cause);
this.code = code;
- this.message = message;
- this.cause = cause;
}
/**
@@ -86,7 +81,8 @@
* @param message Message associated with the exception
*/
public ResourceProcessorException(int code, String message) {
- this(code, message, null);
+ super(message);
+ this.code = code;
}
/**
@@ -97,14 +93,34 @@
* predefined integer values (<code>CODE_X</code>).
*/
public ResourceProcessorException(int code) {
- this(code, null, null);
+ super();
+ this.code = code;
}
/**
- * @return Returns the cause.
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
+ *
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
+ }
+
+ /**
+ * Initializes the cause of this exception to the specified value.
+ *
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ * @since 1.0.1
+ */
+ public Throwable initCause(Throwable cause) {
+ return super.initCause(cause);
}
/**
@@ -113,11 +129,4 @@
public int getCode() {
return code;
}
-
- /**
- * @return Returns the message.
- */
- public String getMessage() {
- return message;
- }
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/package.html
new file mode 100644
index 0000000..cfa5e3f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/package.html
@@ -0,0 +1,12 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Deployment Admin SPI Package Version 1.0.
+The SPI is used by Resource Processors.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.deploymentadmin.spi; version="[1.0,2.0)"
+</pre>
+</BODY>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo
new file mode 100644
index 0000000..b3d1f97
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java
index 6c108dd..8787256 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Constants.java,v 1.9 2006/07/11 00:54:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +23,7 @@
* The values associated with these keys are of type <code>java.lang.String</code>,
* unless otherwise stated.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
* @since 1.1
* @see Device
* @see Driver
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java
index 80e7d3f..2af0330 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Device.java,v 1.10 2006/07/11 00:54:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +23,8 @@
* A service must implement this interface or use the
* {@link Constants#DEVICE_CATEGORY} registration property to indicate that it
* is a device. Any services implementing this interface or registered with the
- * <code>DEVICE_CATEGORY</code> property will be discovered by the device manager.
+ * <code>DEVICE_CATEGORY</code> property will be discovered by the device
+ * manager.
*
* <p>
* Device services implementing this interface give the device manager the
@@ -37,8 +36,9 @@
* Specialized device implementations will extend this interface by adding
* methods appropriate to their device category to it.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5654 $
* @see Driver
+ * @ThreadSafe
*/
public interface Device {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java
index 9d19a6a..98e3617 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Driver.java,v 1.11 2006/07/11 00:54:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,9 +25,10 @@
* highest for a particular <code>Device</code> object will be instructed by the
* device manager to attach to the <code>Device</code> object.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5654 $
* @see Device
* @see DriverLocator
+ * @ThreadSafe
*/
public interface Driver {
/**
@@ -43,8 +42,8 @@
* <p>
* The return value must be one of the possible match values defined in the
* device category definition for the given Device service, or
- * <code>Device.MATCH_NONE</code> if the category of the Device service is not
- * recognized.
+ * <code>Device.MATCH_NONE</code> if the category of the Device service is
+ * not recognized.
*
* <p>
* In order to make its decision, this Driver service may examine the
@@ -61,15 +60,15 @@
* The match function is called by the device manager during the matching
* process.
*
- * @param reference the <code>ServiceReference</code> object of the device to
- * match
+ * @param reference the <code>ServiceReference</code> object of the device
+ * to match
*
* @return value indicating how well this driver can support the given
* Device service, or <code>Device.MATCH_NONE</code> if it cannot
* support the Device service at all
*
* @throws java.lang.Exception if this Driver service cannot examine the
- * Device service
+ * Device service
*/
public int match(ServiceReference reference) throws Exception;
@@ -78,13 +77,13 @@
* given <code>ServiceReference</code> object.
*
* <p>
- * A return value of <code>null</code> indicates that this Driver service has
- * successfully attached to the given Device service. If this Driver service
- * is unable to attach to the given Device service, but knows of a more
- * suitable Driver service, it must return the <code>DRIVER_ID</code> of that
- * Driver service. This allows for the implementation of referring drivers
- * whose only purpose is to refer to other drivers capable of handling a
- * given Device service.
+ * A return value of <code>null</code> indicates that this Driver service
+ * has successfully attached to the given Device service. If this Driver
+ * service is unable to attach to the given Device service, but knows of a
+ * more suitable Driver service, it must return the <code>DRIVER_ID</code>
+ * of that Driver service. This allows for the implementation of referring
+ * drivers whose only purpose is to refer to other drivers capable of
+ * handling a given Device service.
*
* <p>
* After having attached to the Device service, this driver may register the
@@ -94,15 +93,15 @@
* <p>
* This method is called by the device manager.
*
- * @param reference the <code>ServiceReference</code> object of the device to
- * attach to
+ * @param reference the <code>ServiceReference</code> object of the device
+ * to attach to
*
- * @return <code>null</code> if this Driver service has successfully attached
- * to the given Device service, or the <code>DRIVER_ID</code> of a
- * more suitable driver
+ * @return <code>null</code> if this Driver service has successfully
+ * attached to the given Device service, or the
+ * <code>DRIVER_ID</code> of a more suitable driver
*
* @throws java.lang.Exception if the driver cannot attach to the given
- * device and does not know of a more suitable driver
+ * device and does not know of a more suitable driver
*/
public String attach(ServiceReference reference) throws Exception;
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java
index ec1a3d9..2726b99 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/DriverLocator.java,v 1.10 2006/07/12 21:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,8 +28,9 @@
* providers and encapsulate all provider-specific details related to the
* location and acquisition of driver bundles.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5654 $
* @see Driver
+ * @ThreadSafe
*/
public interface DriverLocator {
/**
@@ -56,9 +55,9 @@
*
* @param id the <code>DRIVER_ID</code> of the driver that needs to be
* installed.
- * @return An <code>InputStream</code> object from which the driver bundle can
- * be installed or <code>null</code> if the driver with the given ID
- * cannot be located
+ * @return An <code>InputStream</code> object from which the driver bundle
+ * can be installed or <code>null</code> if the driver with the
+ * given ID cannot be located
* @throws java.io.IOException the input stream for the bundle cannot be
* created
*/
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java
index dcda453..59fd0b9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/DriverSelector.java,v 1.9 2006/06/16 16:31:29 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,16 +23,18 @@
* least one Driver service matches, the device manager must choose one. If
* there is a Driver Selector service registered with the Framework, the device
* manager will ask it to make the selection. If there is no Driver Selector
- * service, or if it returns an invalid result, or throws an <code>Exception</code>,
- * the device manager uses the default selection strategy.
+ * service, or if it returns an invalid result, or throws an
+ * <code>Exception</code>, the device manager uses the default selection
+ * strategy.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5654 $
* @since 1.1
+ * @ThreadSafe
*/
public interface DriverSelector {
/**
- * Return value from <code>DriverSelector.select</code>, if no Driver service
- * should be attached to the Device service. The value is -1.
+ * Return value from <code>DriverSelector.select</code>, if no Driver
+ * service should be attached to the Device service. The value is -1.
*/
public static final int SELECT_NONE = -1;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java
index e666cda..6410659 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Match.java,v 1.9 2006/06/16 16:31:29 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +21,10 @@
* Instances of <code>Match</code> are used in the {@link DriverSelector#select}
* method to identify Driver services matching a Device service.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5654 $
* @since 1.1
* @see DriverSelector
+ * @ThreadSafe
*/
public interface Match {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/device/package.html
new file mode 100644
index 0000000..7647c20
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Device Access Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.device; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/device/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java
index b0df6ee..42cdb1b 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/Event.java,v 1.8 2006/07/12 13:17:04 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +16,12 @@
package org.osgi.service.event;
-import java.util.*;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import org.osgi.framework.Filter;
@@ -26,48 +29,81 @@
* An event.
*
* <code>Event</code> objects are delivered to <code>EventHandler</code>
- * services which subsrcibe to the topic of the event.
+ * services which subscribe to the topic of the event.
*
- * @version $Revision: 1.8 $
+ * @Immutable
+ * @version $Revision: 7003 $
*/
public class Event {
/**
* The topic of this event.
*/
- String topic;
+ private final String topic;
/**
* The properties carried by this event. Keys are strings and values are
* objects
*/
- Hashtable properties;
+ private final Map /* <String,Object> */properties;
/**
* Constructs an event.
*
* @param topic The topic of the event.
- * @param properties The event's properties (may be <code>null</code>).
- *
+ * @param properties The event's properties (may be <code>null</code>). A
+ * property whose key is not of type <code>String</code> will be
+ * ignored.
* @throws IllegalArgumentException If topic is not a valid topic name.
+ * @since 1.2
*/
- public Event(String topic, Dictionary properties) {
+ public Event(String topic, Map/* <String,Object> */properties) {
+ validateTopicName(topic);
this.topic = topic;
- validateTopicName();
- this.properties = new Hashtable();
+ int size = (properties == null) ? 1 : (properties.size() + 1);
+ Map p = new HashMap(size);
if (properties != null) {
- for (Enumeration e = properties.keys(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- Object value = properties.get(key);
- this.properties.put(key, value);
+ for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) {
+ Object key = iter.next();
+ if (key instanceof String) {
+ Object value = properties.get(key);
+ p.put(key, value);
+ }
}
}
- this.properties.put(EventConstants.EVENT_TOPIC, topic);
+ p.put(EventConstants.EVENT_TOPIC, topic);
+ this.properties = p; // safely publish the map
+ }
+
+ /**
+ * Constructs an event.
+ *
+ * @param topic The topic of the event.
+ * @param properties The event's properties (may be <code>null</code>). A
+ * property whose key is not of type <code>String</code> will be
+ * ignored.
+ * @throws IllegalArgumentException If topic is not a valid topic name.
+ */
+ public Event(String topic, Dictionary/* <String,Object> */properties) {
+ validateTopicName(topic);
+ this.topic = topic;
+ int size = (properties == null) ? 1 : (properties.size() + 1);
+ Map p = new HashMap(size);
+ if (properties != null) {
+ for (Enumeration e = properties.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ if (key instanceof String) {
+ Object value = properties.get(key);
+ p.put(key, value);
+ }
+ }
+ }
+ p.put(EventConstants.EVENT_TOPIC, topic);
+ this.properties = p; // safely publish the map
}
/**
* Retrieves a property.
*
* @param name the name of the property to retrieve
- *
* @return The value of the property, or <code>null</code> if not found.
*/
public final Object getProperty(String name) {
@@ -80,12 +116,8 @@
* @return A non-empty array with one element per property.
*/
public final String[] getPropertyNames() {
- String[] names = new String[properties.size()];
- Enumeration keys = properties.keys();
- for (int i = 0; keys.hasMoreElements(); i++) {
- names[i] = (String) keys.nextElement();
- }
- return names;
+ return (String[]) properties.keySet().toArray(
+ new String[properties.size()]);
}
/**
@@ -98,31 +130,30 @@
}
/**
- * Tests this event's properties against the given filter.
+ * Tests this event's properties against the given filter using a case
+ * sensitive match.
*
* @param filter The filter to test.
- *
* @return true If this event's properties match the filter, false
* otherwise.
*/
public final boolean matches(Filter filter) {
- return filter.matchCase(properties);
+ return filter.matchCase(new UnmodifiableDictionary(properties));
}
/**
* Compares this <code>Event</code> object to another object.
*
* <p>
- * An event is considered to be <b>equal to </b> another
- * event if the topic is equal and the properties are equal.
+ * An event is considered to be <b>equal to</b> another event if the topic
+ * is equal and the properties are equal.
*
* @param object The <code>Event</code> object to be compared.
- * @return <code>true</code> if <code>object</code> is a
- * <code>Event</code> and is equal to this object;
- * <code>false</code> otherwise.
+ * @return <code>true</code> if <code>object</code> is a <code>Event</code>
+ * and is equal to this object; <code>false</code> otherwise.
*/
public boolean equals(Object object) {
- if (object == this) { // quicktest
+ if (object == this) { // quick test
return true;
}
@@ -140,7 +171,9 @@
* @return An integer which is a hash code value for this object.
*/
public int hashCode() {
- return topic.hashCode() ^ properties.hashCode();
+ int h = 31 * 17 + topic.hashCode();
+ h = 31 * h + properties.hashCode();
+ return h;
}
/**
@@ -149,47 +182,82 @@
* @return The string representation of this event.
*/
public String toString() {
- return getClass().getName() + " [topic=" + topic + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ return getClass().getName() + " [topic=" + topic + "]";
}
- private static final String SEPARATOR = "/"; //$NON-NLS-1$
-
/**
* Called by the constructor to validate the topic name.
*
+ * @param topic The topic name to validate.
* @throws IllegalArgumentException If the topic name is invalid.
*/
- private void validateTopicName() {
- try {
- StringTokenizer st = new StringTokenizer(topic, SEPARATOR, true);
- validateToken(st.nextToken());
-
- while (st.hasMoreTokens()) {
- st.nextToken(); // consume delimiter
- validateToken(st.nextToken());
- }
+ private static void validateTopicName(String topic) {
+ char[] chars = topic.toCharArray();
+ int length = chars.length;
+ if (length == 0) {
+ throw new IllegalArgumentException("empty topic");
}
- catch (NoSuchElementException e) {
- throw new IllegalArgumentException("invalid topic"); //$NON-NLS-1$
- }
+ for (int i = 0; i < length; i++) {
+ char ch = chars[i];
+ if (ch == '/') {
+ // Can't start or end with a '/' but anywhere else is okay
+ if (i == 0 || (i == length - 1)) {
+ throw new IllegalArgumentException(
+ "invalid topic: "
+ + topic);
+ }
+ // Can't have "//" as that implies empty token
+ if (chars[i-1] == '/') {
+ throw new IllegalArgumentException(
+ "invalid topic: "
+ + topic);
+ }
+ continue;
+ }
+ if (('A' <= ch) && (ch <= 'Z')) {
+ continue;
+ }
+ if (('a' <= ch) && (ch <= 'z')) {
+ continue;
+ }
+ if (('0' <= ch) && (ch <= '9')) {
+ continue;
+ }
+ if ((ch == '_') || (ch == '-')) {
+ continue;
+ }
+ throw new IllegalArgumentException("invalid topic: " + topic);
+ }
}
-
- private static final String tokenAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"; //$NON-NLS-1$
-
+
/**
- * Validate a token.
- *
- * @throws IllegalArgumentException If the token is invalid.
+ * Unmodifiable wrapper for Dictionary.
*/
- private void validateToken(String token) {
- int length = token.length();
- if (length < 1) { // token must contain at least one character
- throw new IllegalArgumentException("invalid topic"); //$NON-NLS-1$
+ private static class UnmodifiableDictionary extends Dictionary {
+ private final Map wrapped;
+ UnmodifiableDictionary(Map wrapped) {
+ this.wrapped = wrapped;
}
- for (int i = 0; i < length; i++) { // each character in the token must be from the token alphabet
- if (tokenAlphabet.indexOf(token.charAt(i)) == -1) { //$NON-NLS-1$
- throw new IllegalArgumentException("invalid topic"); //$NON-NLS-1$
- }
+ public Enumeration elements() {
+ return Collections.enumeration(wrapped.values());
+ }
+ public Object get(Object key) {
+ return wrapped.get(key);
+ }
+ public boolean isEmpty() {
+ return wrapped.isEmpty();
+ }
+ public Enumeration keys() {
+ return Collections.enumeration(wrapped.keySet());
+ }
+ public Object put(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ public int size() {
+ return wrapped.size();
}
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java
index 1683e7b..f48a10f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/EventAdmin.java,v 1.6 2006/06/16 16:31:48 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,32 +20,33 @@
* The Event Admin service. Bundles wishing to publish events must obtain the
* Event Admin service and call one of the event delivery methods.
*
- * @version $Revision: 1.6 $
+ * @ThreadSafe
+ * @version $Revision: 5673 $
*/
public interface EventAdmin {
/**
- * Initiate asynchronous delivery of an event. This method returns to
- * the caller before delivery of the event is completed.
+ * Initiate asynchronous delivery of an event. This method returns to the
+ * caller before delivery of the event is completed.
*
- * @param event The event to send to all listeners which subscribe
- * to the topic of the event.
+ * @param event The event to send to all listeners which subscribe to the
+ * topic of the event.
*
* @throws SecurityException If the caller does not have
- * <code>TopicPermission[topic,PUBLISH]</code> for the topic
- * specified in the event.
+ * <code>TopicPermission[topic,PUBLISH]</code> for the topic
+ * specified in the event.
*/
void postEvent(Event event);
/**
- * Initiate synchronous delivery of an event. This method does not
- * return to the caller until delivery of the event is completed.
+ * Initiate synchronous delivery of an event. This method does not return to
+ * the caller until delivery of the event is completed.
*
- * @param event The event to send to all listeners which subscribe
- * to the topic of the event.
+ * @param event The event to send to all listeners which subscribe to the
+ * topic of the event.
*
* @throws SecurityException If the caller does not have
- * <code>TopicPermission[topic,PUBLISH]</code> for the topic
- * specified in the event.
+ * <code>TopicPermission[topic,PUBLISH]</code> for the topic
+ * specified in the event.
*/
void sendEvent(Event event);
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java
index e6768d0..ed3d5d0 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/EventConstants.java,v 1.14 2006/07/12 21:06:18 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,31 +16,34 @@
package org.osgi.service.event;
+import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
/**
- *
* Defines standard names for <code>EventHandler</code> properties.
*
- * @version $Revision: 1.14 $
+ * @version $Revision: 7368 $
*/
public interface EventConstants {
/**
- * Service registration property (named <code>event.topic</code>)
+ * Service registration property (named <code>event.topics</code>)
* specifying the <code>Event</code> topics of interest to a Event Handler
* service.
* <p>
* Event handlers SHOULD be registered with this property. The value of the
- * property is an array of strings that describe the topics in which the
- * handler is interested. An asterisk ('*') may be used as a trailing
- * wildcard. Event Handlers which do not have a value for this property must
- * not receive events. More precisely, the value of each entry in the array
- * must conform to the following grammar:
+ * property is a string or an array of strings that describe the topics in
+ * which the handler is interested. An asterisk ('*') may be used as a
+ * trailing wildcard. Event Handlers which do not have a value for this
+ * property must not receive events. More precisely, the value of each
+ * string must conform to the following grammar:
*
* <pre>
- * topic-description := '*' | topic ( '/*' )?
- * topic := token ( '/' token )*
+ * topic-description := '*' | topic ( '/*' )?
+ * topic := token ( '/' token )*
* </pre>
*
* @see Event
@@ -51,8 +52,8 @@
/**
* Service Registration property (named <code>event.filter</code>)
- * specifying a filter to further select <code>Event</code> s of interest
- * to a Event Handler service.
+ * specifying a filter to further select <code>Event</code> s of interest to
+ * a Event Handler service.
* <p>
* Event handlers MAY be registered with this property. The value of this
* property is a string containing an LDAP-style filter specification. Any
@@ -67,94 +68,116 @@
* and a warning should be logged.
*
* @see Event
- * @see org.osgi.framework.Filter
+ * @see Filter
*/
public static final String EVENT_FILTER = "event.filter";
/**
- * The Distinguished Name of the bundle relevant to the event.
+ * The Distinguished Names of the signers of the bundle relevant to the
+ * event. The type of the value for this event property is
+ * <code>String</code> or <code>Collection</code> of <code>String</code>.
*/
public static final String BUNDLE_SIGNER = "bundle.signer";
/**
- * The Bundle Symbolic Name of the bundle relevant to the event.
+ * The Bundle Symbolic Name of the bundle relevant to the event. The type of
+ * the value for this event property is <code>String</code>.
*/
public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName";
/**
- * The Bundle id of the bundle relevant to the event.
+ * The Bundle id of the bundle relevant to the event. The type of the value
+ * for this event property is <code>Long</code>.
*
* @since 1.1
*/
public static final String BUNDLE_ID = "bundle.id";
/**
- * The Bundle object of the bundle relevant to the event.
+ * The Bundle object of the bundle relevant to the event. The type of the
+ * value for this event property is {@link Bundle}.
*
* @since 1.1
*/
public static final String BUNDLE = "bundle";
/**
- * The actual event object. Used when rebroadcasting an event that was sent
- * via some other event mechanism.
+ * The version of the bundle relevant to the event. The type of the value
+ * for this event property is {@link Version}.
+ *
+ * @since 1.2
+ */
+ public static final String BUNDLE_VERSION = "bundle.version";
+
+ /**
+ * The forwarded event object. Used when rebroadcasting an event that was
+ * sent via some other event mechanism. The type of the value for this event
+ * property is <code>Object</code>.
*/
public static final String EVENT = "event";
/**
- * An exception or error.
+ * An exception or error. The type of the value for this event property is
+ * <code>Throwable</code>.
*/
public static final String EXCEPTION = "exception";
/**
- * Must be equal to the name of the Exception class.
+ * The name of the exception type. Must be equal to the name of the class of
+ * the exception in the event property {@link #EXCEPTION}. The type of the
+ * value for this event property is <code>String</code>.
*
* @since 1.1
*/
public static final String EXCEPTION_CLASS = "exception.class";
/**
- * Must be equal to exception.getMessage()
+ * The exception message. Must be equal to the result of calling
+ * <code>getMessage()</code> on the exception in the event property
+ * {@link #EXCEPTION}. The type of the value for this event property is
+ * <code>String</code>.
*/
public static final String EXCEPTION_MESSAGE = "exception.message";
/**
- * A human-readable message that is usually not localized.
+ * A human-readable message that is usually not localized. The type of the
+ * value for this event property is <code>String</code>.
*/
public static final String MESSAGE = "message";
/**
- * A service
+ * A service reference. The type of the value for this event property is
+ * {@link ServiceReference}.
*/
-
public static final String SERVICE = "service";
/**
- * A service's id.
+ * A service's id. The type of the value for this event property is
+ * <code>Long</code>.
*/
public static final String SERVICE_ID = Constants.SERVICE_ID;
/**
- *
- * A service's objectClass
+ * A service's objectClass. The type of the value for this event property is
+ * <code>String[]</code>.
*/
public static final String SERVICE_OBJECTCLASS = "service.objectClass";
/**
- *
- * A service's persistent identity.
+ * A service's persistent identity. The type of the value for this event
+ * property is <code>String</code>.
*/
public static final String SERVICE_PID = Constants.SERVICE_PID;
/**
- *
* The time when the event occurred, as reported by
- * System.currentTimeMillis()
+ * <code>System.currentTimeMillis()</code>. The type of the value for this
+ * event property is <code>Long</code>.
*/
public static final String TIMESTAMP = "timestamp";
/**
- * This constant was released with an incorrect spelling. It has been
+ * This constant was released with an incorrectly spelled name. It has been
* replaced by {@link #EXCEPTION_CLASS}
*
* @deprecated As of 1.1, replaced by EXCEPTION_CLASS
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java
index 8073796..d25782f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/EventHandler.java,v 1.10 2006/07/11 16:43:59 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,43 +21,47 @@
*
* <p>
* <code>EventHandler</code> objects are registered with the Framework service
- * registry and are notified with an <code>Event</code> object when an
- * event is sent or posted.
+ * registry and are notified with an <code>Event</code> object when an event
+ * is sent or posted.
* <p>
* <code>EventHandler</code> objects can inspect the received
* <code>Event</code> object to determine its topic and properties.
*
* <p>
* <code>EventHandler</code> objects must be registered with a service
- * property {@link EventConstants#EVENT_TOPIC} whose value is the list of
- * topics in which the event handler is interesed.
+ * property {@link EventConstants#EVENT_TOPIC} whose value is the list of topics
+ * in which the event handler is interested.
* <p>
* For example:
*
* <pre>
- * String[] topics = new String[] {EventConstants.EVENT_TOPIC, "com/isv/*"};
+ * String[] topics = new String[] {"com/isv/*"};
* Hashtable ht = new Hashtable();
- * ht.put(EVENT_TOPIC, topics);
+ * ht.put(EventConstants.EVENT_TOPIC, topics);
* context.registerService(EventHandler.class.getName(), this, ht);
* </pre>
- * Event Handler services can also be registered with an {@link EventConstants#EVENT_FILTER}
- * service propery to further filter the events. If the syntax of this filter is invalid,
- * then the Event Handler must be ignored by the Event Admin service. The Event Admin
- * service should log a warning.
+ *
+ * Event Handler services can also be registered with an
+ * {@link EventConstants#EVENT_FILTER} service property to further filter the
+ * events. If the syntax of this filter is invalid, then the Event Handler must
+ * be ignored by the Event Admin service. The Event Admin service should log a
+ * warning.
* <p>
* Security Considerations. Bundles wishing to monitor <code>Event</code>
* objects will require <code>ServicePermission[EventHandler,REGISTER]</code>
* to register an <code>EventHandler</code> service. The bundle must also have
- * <code>TopicPermission[topic,SUBSCRIBE]</code> for the topic specified in the
- * event in order to receive the event.
+ * <code>TopicPermission[topic,SUBSCRIBE]</code> for the topic specified in
+ * the event in order to receive the event.
*
* @see Event
*
- * @version $Revision: 1.10 $
+ * @ThreadSafe
+ * @version $Revision: 5673 $
*/
public interface EventHandler {
/**
- * Called by the {@link EventAdmin} service to notify the listener of an event.
+ * Called by the {@link EventAdmin} service to notify the listener of an
+ * event.
*
* @param event The event that occurred.
*/
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java
index 89591b6..ae0d190 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/TopicPermission.java,v 1.11 2006/06/16 16:31:48 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,25 +31,26 @@
* For example:
*
* <pre>
- * org/osgi/service/foo/FooEvent/ACTION
+ * org / osgi / service / foo / FooEvent / ACTION
* </pre>
*
* <p>
* <code>TopicPermission</code> has two actions: <code>publish</code> and
* <code>subscribe</code>.
*
- * @version $Revision: 1.11 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
*/
public final class TopicPermission extends Permission {
static final long serialVersionUID = -5855563886961618300L;
/**
* The action string <code>publish</code>.
*/
- public final static String PUBLISH = "publish"; //$NON-NLS-1$
+ public final static String PUBLISH = "publish";
/**
* The action string <code>subscribe</code>.
*/
- public final static String SUBSCRIBE = "subscribe"; //$NON-NLS-1$
+ public final static String SUBSCRIBE = "subscribe";
private final static int ACTION_PUBLISH = 0x00000001;
private final static int ACTION_SUBSCRIBE = 0x00000002;
private final static int ACTION_ALL = ACTION_PUBLISH
@@ -60,19 +59,19 @@
/**
* The actions mask.
*/
- private transient int action_mask = ACTION_NONE;
+ private transient int action_mask;
/**
* prefix if the name is wildcarded.
*/
- private transient String prefix;
+ private transient volatile String prefix;
/**
* The actions in canonical form.
*
* @serial
*/
- private String actions = null;
+ private volatile String actions = null;
/**
* Defines the authority to publich and/or subscribe to a topic within the
@@ -95,11 +94,11 @@
* <p>
*
* @param name Topic name.
- * @param actions <code>publish</code>,<code>subscribe</code>
- * (canonical order).
+ * @param actions <code>publish</code>,<code>subscribe</code> (canonical
+ * order).
*/
public TopicPermission(String name, String actions) {
- this(name, getMask(actions));
+ this(name, parseActions(actions));
}
/**
@@ -110,7 +109,7 @@
*/
TopicPermission(String name, int mask) {
super(name);
- init(name, mask);
+ setTransients(mask);
}
/**
@@ -119,26 +118,39 @@
* @param name topic name
* @param mask action mask
*/
- private void init(String name, int mask) {
+ private synchronized void setTransients(final int mask) {
+ final String name = getName();
if ((name == null) || name.length() == 0) {
- throw new IllegalArgumentException("invalid name"); //$NON-NLS-1$
+ throw new IllegalArgumentException("invalid name");
}
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+ action_mask = mask;
+
if (name.equals("*")) {
prefix = "";
}
- else
+ else {
if (name.endsWith("/*")) {
prefix = name.substring(0, name.length() - 1);
}
else {
prefix = null;
}
-
- if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
- throw new IllegalArgumentException("invalid action string"); //$NON-NLS-1$
}
- action_mask = mask;
+ }
+
+ /**
+ * Returns the current action mask.
+ * <p>
+ * Used by the TopicPermissionCollection class.
+ *
+ * @return Current action mask.
+ */
+ synchronized int getActionsMask() {
+ return action_mask;
}
/**
@@ -147,7 +159,7 @@
* @param actions Action string.
* @return action mask.
*/
- private static int getMask(String actions) {
+ private static int parseActions(final String actions) {
boolean seencomma = false;
int mask = ACTION_NONE;
if (actions == null) {
@@ -191,7 +203,7 @@
}
else {
// parse error
- throw new IllegalArgumentException("invalid permission: " //$NON-NLS-1$
+ throw new IllegalArgumentException("invalid permission: "
+ actions);
}
// make sure we didn't just match the tail of a word
@@ -201,7 +213,7 @@
switch (a[i - matchlen]) {
case ',' :
seencomma = true;
- /* FALLTHROUGH */
+ /* FALLTHROUGH */
case ' ' :
case '\r' :
case '\n' :
@@ -210,7 +222,7 @@
break;
default :
throw new IllegalArgumentException(
- "invalid permission: " + actions); //$NON-NLS-1$
+ "invalid permission: " + actions);
}
i--;
}
@@ -218,7 +230,7 @@
i -= matchlen;
}
if (seencomma) {
- throw new IllegalArgumentException("invalid permission: " + actions); //$NON-NLS-1$
+ throw new IllegalArgumentException("invalid permission: " + actions);
}
return mask;
}
@@ -245,13 +257,16 @@
*/
public boolean implies(Permission p) {
if (p instanceof TopicPermission) {
- TopicPermission target = (TopicPermission) p;
- if ((action_mask & target.action_mask) == target.action_mask) {
- if (prefix != null) {
- return target.getName().startsWith(prefix);
+ TopicPermission requested = (TopicPermission) p;
+ int requestedMask = requested.getActionsMask();
+ if ((getActionsMask() & requestedMask) == requestedMask) {
+ String requestedName = requested.getName();
+ String pre = prefix;
+ if (pre != null) {
+ return requestedName.startsWith(pre);
}
- return target.getName().equals(getName());
+ return requestedName.equals(getName());
}
}
return false;
@@ -269,21 +284,23 @@
* <code>TopicPermission</code> actions.
*/
public String getActions() {
- if (actions == null) {
+ String result = actions;
+ if (result == null) {
StringBuffer sb = new StringBuffer();
boolean comma = false;
- if ((action_mask & ACTION_PUBLISH) == ACTION_PUBLISH) {
+ int mask = getActionsMask();
+ if ((mask & ACTION_PUBLISH) == ACTION_PUBLISH) {
sb.append(PUBLISH);
comma = true;
}
- if ((action_mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) {
+ if ((mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) {
if (comma)
sb.append(',');
sb.append(SUBSCRIBE);
}
- actions = sb.toString();
+ actions = result = sb.toString();
}
- return actions;
+ return result;
}
/**
@@ -299,9 +316,8 @@
/**
* Determines the equality of two <code>TopicPermission</code> objects.
*
- * This method checks that specified <code>TopicPermission</code> has the same topic name and
- * actions as this
- * <code>TopicPermission</code> object.
+ * This method checks that specified <code>TopicPermission</code> has the
+ * same topic name and actions as this <code>TopicPermission</code> object.
*
* @param obj The object to test for equality with this
* <code>TopicPermission</code> object.
@@ -317,8 +333,9 @@
if (!(obj instanceof TopicPermission)) {
return false;
}
- TopicPermission p = (TopicPermission) obj;
- return (action_mask == p.action_mask) && getName().equals(p.getName());
+ TopicPermission tp = (TopicPermission) obj;
+ return (getActionsMask() == tp.getActionsMask())
+ && getName().equals(tp.getName());
}
/**
@@ -327,18 +344,9 @@
* @return A hash code value for this object.
*/
public int hashCode() {
- return getName().hashCode() ^ getActions().hashCode();
- }
-
- /**
- * Returns the current action mask.
- * <p>
- * Used by the TopicPermissionCollection class.
- *
- * @return Current action mask.
- */
- int getMask() {
- return action_mask;
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
}
/**
@@ -363,7 +371,7 @@
throws IOException, ClassNotFoundException {
// Read in the action, then initialize the rest
s.defaultReadObject();
- init(getName(), getMask(actions));
+ setTransients(parseActions(actions));
}
}
@@ -375,19 +383,21 @@
* @see java.security.PermissionCollection
*/
final class TopicPermissionCollection extends PermissionCollection {
- static final long serialVersionUID = -614647783533924048L;
+ static final long serialVersionUID = -614647783533924048L;
/**
* Table of permissions.
*
* @serial
+ * @GuardedBy this
*/
- private Hashtable permissions;
+ private final Hashtable permissions;
/**
* Boolean saying if "*" is in the collection.
*
* @serial
+ * @GuardedBy this
*/
- private boolean all_allowed;
+ private boolean all_allowed;
/**
* Create an empty TopicPermissions object.
@@ -405,36 +415,41 @@
* @param permission The <code>TopicPermission</code> object to add.
*
* @throws IllegalArgumentException If the permission is not a
- * <code>TopicPermission</code> instance.
+ * <code>TopicPermission</code> instance.
*
- * @throws SecurityException If this
- * <code>TopicPermissionCollection</code> object has been
- * marked read-only.
+ * @throws SecurityException If this <code>TopicPermissionCollection</code>
+ * object has been marked read-only.
*/
- public void add(Permission permission) {
- if (!(permission instanceof TopicPermission))
- throw new IllegalArgumentException("invalid permission: " //$NON-NLS-1$
+ public void add(final Permission permission) {
+ if (!(permission instanceof TopicPermission)) {
+ throw new IllegalArgumentException("invalid permission: "
+ permission);
- if (isReadOnly())
- throw new SecurityException("attempt to add a Permission to a " //$NON-NLS-1$
- + "readonly PermissionCollection"); //$NON-NLS-1$
- TopicPermission pp = (TopicPermission) permission;
- String name = pp.getName();
- TopicPermission existing = (TopicPermission) permissions.get(name);
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = pp.getMask();
- if (oldMask != newMask) {
- permissions.put(name, new TopicPermission(name, oldMask
- | newMask));
+ }
+ if (isReadOnly()) {
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+ }
+ final TopicPermission tp = (TopicPermission) permission;
+ final String name = tp.getName();
+ final int newMask = tp.getActionsMask();
+
+ synchronized (this) {
+ final TopicPermission existing = (TopicPermission) permissions
+ .get(name);
+ if (existing != null) {
+ final int oldMask = existing.getActionsMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new TopicPermission(name, oldMask
+ | newMask));
+ }
}
- }
- else {
- permissions.put(name, permission);
- }
- if (!all_allowed) {
- if (name.equals("*")) //$NON-NLS-1$
- all_allowed = true;
+ else {
+ permissions.put(name, tp);
+ }
+ if (!all_allowed) {
+ if (name.equals("*"))
+ all_allowed = true;
+ }
}
}
@@ -445,47 +460,55 @@
* @param permission The Permission object to compare with this
* <code>TopicPermission</code> object.
*
- * @return <code>true</code> if <code>permission</code> is a proper
- * subset of a permission in the set; <code>false</code>
- * otherwise.
+ * @return <code>true</code> if <code>permission</code> is a proper subset
+ * of a permission in the set; <code>false</code> otherwise.
*/
- public boolean implies(Permission permission) {
- if (!(permission instanceof TopicPermission))
+ public boolean implies(final Permission permission) {
+ if (!(permission instanceof TopicPermission)) {
return false;
- TopicPermission pp = (TopicPermission) permission;
- TopicPermission x;
- int desired = pp.getMask();
+ }
+ final TopicPermission requested = (TopicPermission) permission;
+ String name = requested.getName();
+ final int desired = requested.getActionsMask();
int effective = 0;
+
+ TopicPermission x;
// short circuit if the "*" Permission was added
- if (all_allowed) {
- x = (TopicPermission) permissions.get("*"); //$NON-NLS-1$
- if (x != null) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
+ synchronized (this) {
+ if (all_allowed) {
+ x = (TopicPermission) permissions.get("*");
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
}
+ x = (TopicPermission) permissions.get(name);
}
// strategy:
// Check for full match first. Then work our way up the
// name looking for matches on a/b/*
- String name = pp.getName();
- x = (TopicPermission) permissions.get(name);
if (x != null) {
// we have a direct hit!
- effective |= x.getMask();
- if ((effective & desired) == desired)
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
return true;
+ }
}
// work our way up the tree...
- int last, offset;
- offset = name.length() - 1;
- while ((last = name.lastIndexOf("/", offset)) != -1) { //$NON-NLS-1$
- name = name.substring(0, last + 1) + "*"; //$NON-NLS-1$
- x = (TopicPermission) permissions.get(name);
+ int last;
+ int offset = name.length() - 1;
+ while ((last = name.lastIndexOf("/", offset)) != -1) {
+ name = name.substring(0, last + 1) + "*";
+ synchronized (this) {
+ x = (TopicPermission) permissions.get(name);
+ }
if (x != null) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
return true;
+ }
}
offset = last - 1;
}
@@ -495,8 +518,8 @@
}
/**
- * Returns an enumeration of all <code>TopicPermission</code> objects in
- * the container.
+ * Returns an enumeration of all <code>TopicPermission</code> objects in the
+ * container.
*
* @return Enumeration of all <code>TopicPermission</code> objects.
*/
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/event/package.html
new file mode 100644
index 0000000..0d9d0bf
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Event Admin Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.event; version="[1.2,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/event/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java
index abeb95b..e39cd17 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.http/src/org/osgi/service/http/HttpContext.java,v 1.12 2006/07/12 21:22:13 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +35,7 @@
* <p>
* This interface is implemented by users of the <code>HttpService</code>.
*
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
*/
public interface HttpContext {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java
index 2047328..c578a93 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.http/src/org/osgi/service/http/HttpService.java,v 1.13 2006/07/12 21:22:13 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +25,7 @@
* register resources and servlets into the URI namespace of Http Service. A
* bundle may later unregister its resources or servlets.
*
- * @version $Revision: 1.13 $
+ * @version $Revision: 5673 $
* @see HttpContext
*/
public interface HttpService {
@@ -90,9 +88,10 @@
* the registration will be mapped. An alias must begin with slash ('/') and
* must not end with slash ('/'), with the exception that an alias of the
* form "/" is used to denote the root alias. The name parameter
- * must also not end with slash ('/'). See the specification text for
- * details on how HTTP requests are mapped to servlet and resource
- * registrations.
+ * must also not end with slash ('/') with the exception that a name of the
+ * form "/" is used to denote the root of the bundle. See the
+ * specification text for details on how HTTP requests are mapped to servlet
+ * and resource registrations.
* <p>
* For example, suppose the resource name /tmp is registered to the alias
* /files. A request for /files/foo.txt will map to the resource name
@@ -104,20 +103,20 @@
*
* The Http Service will call the <code>HttpContext</code> argument to map
* resource names to URLs and MIME types and to handle security for
- * requests. If the <code>HttpContext</code> argument is <code>null</code>, a
- * default <code>HttpContext</code> is used (see
+ * requests. If the <code>HttpContext</code> argument is <code>null</code>,
+ * a default <code>HttpContext</code> is used (see
* {@link #createDefaultHttpContext}).
*
* @param alias name in the URI namespace at which the resources are
* registered
* @param name the base name of the resources that will be registered
* @param context the <code>HttpContext</code> object for the registered
- * resources, or <code>null</code> if a default <code>HttpContext</code>
- * is to be created and used.
- * @throws NamespaceException if the registration fails because the alias
- * is already in use.
- * @throws java.lang.IllegalArgumentException if any of the parameters
- * are invalid
+ * resources, or <code>null</code> if a default
+ * <code>HttpContext</code> is to be created and used.
+ * @throws NamespaceException if the registration fails because the alias is
+ * already in use.
+ * @throws java.lang.IllegalArgumentException if any of the parameters are
+ * invalid
*/
public void registerResources(String alias, String name,
HttpContext context) throws NamespaceException;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java b/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java
index 478d2ea..dce2ba8 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.http/src/org/osgi/service/http/NamespaceException.java,v 1.11 2006/07/11 13:15:56 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,15 +20,11 @@
* to register a servlet or resources into the URI namespace of the Http
* Service. This exception indicates that the requested alias already is in use.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 6083 $
*/
public class NamespaceException extends Exception {
static final long serialVersionUID = 7235606031147877747L;
- /**
- * Nested exception.
- */
- private final Throwable cause;
-
+
/**
* Construct a <code>NamespaceException</code> object with a detail message.
*
@@ -38,7 +32,6 @@
*/
public NamespaceException(String message) {
super(message);
- cause = null;
}
/**
@@ -49,47 +42,47 @@
* @param cause The nested exception.
*/
public NamespaceException(String message, Throwable cause) {
- super(message);
- this.cause = cause;
+ super(message, cause);
}
/**
* Returns the nested exception.
- *
- * <p>This method predates the general purpose exception chaining mechanism.
- * The {@link #getCause()} method is now the preferred means of
- * obtaining this information.
*
- * @return the nested exception or <code>null</code> if there is no nested
- * exception.
+ * <p>
+ * This method predates the general purpose exception chaining mechanism.
+ * The <code>getCause()</code> method is now the preferred means of
+ * obtaining this information.
+ *
+ * @return The result of calling <code>getCause()</code>.
*/
public Throwable getException() {
- return cause;
+ return getCause();
}
-
+
/**
- * Returns the cause of this exception or <code>null</code> if no
- * cause was specified when this exception was created.
- *
- * @return The cause of this exception or <code>null</code> if no
- * cause was specified.
- * @since 1.2
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
+ *
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
+ * @since 1.2
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
}
/**
- * The cause of this exception can only be set when constructed.
- *
- * @param cause Cause of the exception.
- * @return This object.
- * @throws java.lang.IllegalStateException
- * This method will always throw an <code>IllegalStateException</code>
- * since the cause of this exception can only be set when constructed.
- * @since 1.2
+ * Initializes the cause of this exception to the specified value.
+ *
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ * @since 1.2
*/
public Throwable initCause(Throwable cause) {
- throw new IllegalStateException();
+ return super.initCause(cause);
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/http/package.html
new file mode 100644
index 0000000..21f5fed
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Http Service Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.http; version="[1.2,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/http/packageinfo
new file mode 100644
index 0000000..6ebb891
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/packageinfo
@@ -0,0 +1 @@
+version 1.2.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java
index 03f812e..3939512 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.io/src/org/osgi/service/io/ConnectionFactory.java,v 1.9 2006/07/12 21:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +32,7 @@
* Factory will then be called to create the actual <code>Connection</code>
* object.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 7337 $
*/
public interface ConnectionFactory {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java
index 45d1f87..dbfc04a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.io/src/org/osgi/service/io/ConnectorService.java,v 1.9 2006/07/12 21:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +40,7 @@
* first, is called. This is the same algorithm used by
* <code>BundleContext.getServiceReference</code>.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
*/
public interface ConnectorService {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/io/package.html
new file mode 100644
index 0000000..cecc3c3
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>IO Connector Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.io; version="[1.0,2.0)", javax.microedition.io
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/io/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java
index 12e6c8d..8130cf8 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogEntry.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +27,8 @@
* <code>LogReaderService.getLog</code> method or by registering a
* <code>LogListener</code> object.
*
- * @version $Revision: 1.9 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
* @see LogReaderService#getLog
* @see LogListener
*/
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java
index 3731c28..de29a56 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogListener.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +28,8 @@
* unregistered by calling the <code>LogReaderService.removeLogListener</code>
* method.
*
- * @version $Revision: 1.9 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
* @see LogReaderService
* @see LogEntry
* @see LogReaderService#addLogListener(LogListener)
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java
index 4176ebc..b3753e4 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogReaderService.java,v 1.10 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +29,8 @@
* method can be called which will return an <code>Enumeration</code> of all
* <code>LogEntry</code> objects in the log.
*
- * @version $Revision: 1.10 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
* @see LogEntry
* @see LogListener
* @see LogListener#logged(LogEntry)
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java
index 4858c58..1889355 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogService.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +34,8 @@
* <li>{@link #LOG_DEBUG}
* </ol>
*
- * @version $Revision: 1.9 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
*/
public interface LogService {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/log/package.html
new file mode 100644
index 0000000..02312bb
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Log Service Package Version 1.3.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.log; version="[1.3,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/log/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
index 3f3f053..d427163 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/AttributeDefinition.java,v 1.13 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +22,7 @@
* An <code>AttributeDefinition</code> object defines a description of the data
* type of a property/attribute.
*
- * @version $Revision: 1.13 $
+ * @version $Revision: 5673 $
*/
public interface AttributeDefinition {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
index ce544e3..8b336dc 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/MetaTypeInformation.java,v 1.8 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +21,7 @@
* A MetaType Information object is created by the MetaTypeService to return
* meta type information for a specific bundle.
*
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
* @since 1.1
*/
public interface MetaTypeInformation extends MetaTypeProvider {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
index a21f617..b2385b2 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/MetaTypeProvider.java,v 1.11 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +18,7 @@
/**
* Provides access to metatypes.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
*/
public interface MetaTypeProvider {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java
index ea1b1b2..d8f77a3 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/MetaTypeService.java,v 1.10 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +31,7 @@
* retrieve meta type information for bundles which contain a meta type
* documents or which provide their own <code>MetaTypeProvider</code> objects.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
* @since 1.1
*/
public interface MetaTypeService {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
index 754b636..5c6687e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/ObjectClassDefinition.java,v 1.11 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +21,7 @@
/**
* Description for the data type information of an objectclass.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
*/
public interface ObjectClassDefinition {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/package.html
new file mode 100644
index 0000000..0b2b533
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Metatype Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.metatype; version="[1.1,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
index c9377c8..6ab860e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitorAdmin.java,v 1.25 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,14 +27,14 @@
* <code>Monitorable</code> services from the service registry and then query
* the list of <code>StatusVariable</code> names from the
* <code>Monitorable</code> services. This way all services which publish
- * <code>StatusVariable</code>s will be returned regardless of whether they
- * do or do not hold the necessary <code>MonitorPermission</code> for
- * publishing <code>StatusVariable</code>s. By using the
- * <code>MonitorAdmin</code> to obtain the <code>StatusVariable</code>s it
- * is guaranteed that only those <code>Monitorable</code> services will be
- * accessed who are authorized to publish <code>StatusVariable</code>s. It is
- * the responsibility of the <code>MonitorAdmin</code> implementation to check
- * the required permissions and show only those variables which pass this check.
+ * <code>StatusVariable</code>s will be returned regardless of whether they do
+ * or do not hold the necessary <code>MonitorPermission</code> for publishing
+ * <code>StatusVariable</code>s. By using the <code>MonitorAdmin</code> to
+ * obtain the <code>StatusVariable</code>s it is guaranteed that only those
+ * <code>Monitorable</code> services will be accessed who are authorized to
+ * publish <code>StatusVariable</code>s. It is the responsibility of the
+ * <code>MonitorAdmin</code> implementation to check the required permissions
+ * and show only those variables which pass this check.
* <p>
* The events posted by <code>MonitorAdmin</code> contain the following
* properties:
@@ -53,11 +51,13 @@
* </ul>
* <p>
* Most of the methods require either a Monitorable ID or a Status Variable path
- * parameter, the latter in [Monitorable_ID]/[StatusVariable_ID] format. These
+ * parameter, the latter in [Monitorable_ID]/[StatusVariable_ID] format. These
* parameters must not be <code>null</code>, and the IDs they contain must
* conform to their respective definitions in {@link Monitorable} and
- * {@link StatusVariable}. If any of the restrictions are violated, the method
+ * {@link StatusVariable}. If any of the restrictions are violated, the method
* must throw an <code>IllegalArgumentException</code>.
+ *
+ * @version $Revision: 5673 $
*/
public interface MonitorAdmin {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java
index 44fa845..694bcd7 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitorListener.java,v 1.11 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +17,13 @@
package org.osgi.service.monitor;
/**
- * The <code>MonitorListener</code> is used by <code>Monitorable</code>
- * services to send notifications when a <code>StatusVariable</code> value is
- * changed. The <code>MonitorListener</code> should register itself as a
- * service at the OSGi Service Registry. This interface must (only) be
- * implemented by the Monitor Admin component.
+ * The <code>MonitorListener</code> is used by <code>Monitorable</code> services
+ * to send notifications when a <code>StatusVariable</code> value is changed.
+ * The <code>MonitorListener</code> should register itself as a service at the
+ * OSGi Service Registry. This interface must (only) be implemented by the
+ * Monitor Admin component.
+ *
+ * @version $Revision: 5673 $
*/
public interface MonitorListener {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java
index b0ca12d..c02797e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitorPermission.java,v 1.17 2006/06/21 15:17:16 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,18 +22,20 @@
/**
* Indicates the callers authority to publish, read or reset
- * <code>StatusVariable</code>s, to switch event sending on or off or to
- * start monitoring jobs. The target of the permission is the identifier of the
+ * <code>StatusVariable</code>s, to switch event sending on or off or to start
+ * monitoring jobs. The target of the permission is the identifier of the
* <code>StatusVariable</code>, the action can be <code>read</code>,
* <code>publish</code>, <code>reset</code>, <code>startjob</code>,
- * <code>switchevents</code>, or the combination of these separated by
- * commas. Action names are interpreted case-insensitively, but the canonical
- * action string returned by {@link #getActions} uses the forms defined by the
- * action constants.
+ * <code>switchevents</code>, or the combination of these separated by commas.
+ * Action names are interpreted case-insensitively, but the canonical action
+ * string returned by {@link #getActions} uses the forms defined by the action
+ * constants.
* <p>
- * If the wildcard <code>*</code> appears in the actions field, all legal
- * monitoring commands are allowed on the designated target(s) by the owner of
+ * If the wildcard <code>*</code> appears in the actions field, all legal
+ * monitoring commands are allowed on the designated target(s) by the owner of
* the permission.
+ *
+ * @version $Revision: 5673 $
*/
public class MonitorPermission extends Permission {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java
index 8203ddd..5fceb98 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/Monitorable.java,v 1.17 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +18,11 @@
/**
* A <code>Monitorable</code> can provide information about itself in the form
- * of <code>StatusVariables</code>. Instances of this interface should
- * register themselves at the OSGi Service Registry. The
- * <code>MonitorAdmin</code> listens to the registration of
- * <code>Monitorable</code> services, and makes the information they provide
- * available also through the Device Management Tree (DMT) for remote access.
+ * of <code>StatusVariables</code>. Instances of this interface should register
+ * themselves at the OSGi Service Registry. The <code>MonitorAdmin</code>
+ * listens to the registration of <code>Monitorable</code> services, and makes
+ * the information they provide available also through the Device Management
+ * Tree (DMT) for remote access.
* <p>
* The monitorable service is identified by its PID string which must be a non-
* <code>null</code>, non-empty string that conforms to the "symbolic-name"
@@ -32,17 +30,19 @@
* characters [-_.a-zA-Z0-9] may be used. The length of the PID must not exceed
* 20 characters.
* <p>
- * A <code>Monitorable</code> may optionally support sending notifications
- * when the status of its <code>StatusVariables</code> change. Support for
- * change notifications can be defined per <code>StatusVariable</code>.
+ * A <code>Monitorable</code> may optionally support sending notifications when
+ * the status of its <code>StatusVariables</code> change. Support for change
+ * notifications can be defined per <code>StatusVariable</code>.
* <p>
* Publishing <code>StatusVariables</code> requires the presence of the
- * <code>MonitorPermission</code> with the <code>publish</code> action
- * string. This permission, however, is not checked during registration of the
+ * <code>MonitorPermission</code> with the <code>publish</code> action string.
+ * This permission, however, is not checked during registration of the
* <code>Monitorable</code> service. Instead, the <code>MonitorAdmin</code>
* implemenatation must make sure that when a <code>StatusVariable</code> is
* queried, it is shown only if the <code>Monitorable</code> is authorized to
* publish the given <code>StatusVariable</code>.
+ *
+ * @version $Revision: 5673 $
*/
public interface Monitorable {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java
index 75b9d2e..43d3bf2 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitoringJob.java,v 1.14 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,28 +18,29 @@
/**
* A Monitoring Job is a request for scheduled or event based notifications on
- * update of a set of <code>StatusVariable</code>s. The job is a data
- * structure that holds a non-empty list of <code>StatusVariable</code> names,
- * an identification of the initiator of the job, and the sampling parameters.
+ * update of a set of <code>StatusVariable</code>s. The job is a data structure
+ * that holds a non-empty list of <code>StatusVariable</code> names, an
+ * identification of the initiator of the job, and the sampling parameters.
* There are two kinds of monitoring jobs: time based and change based. Time
- * based jobs take samples of all <code>StatusVariable</code>s with a
- * specified frequency. The number of samples to be taken before the job
- * finishes may be specified. Change based jobs are only interested in the
- * changes of the monitored <code>StatusVariable</code>s. In this case, the
- * number of changes that must take place between two notifications can be
- * specified.
+ * based jobs take samples of all <code>StatusVariable</code>s with a specified
+ * frequency. The number of samples to be taken before the job finishes may be
+ * specified. Change based jobs are only interested in the changes of the
+ * monitored <code>StatusVariable</code>s. In this case, the number of changes
+ * that must take place between two notifications can be specified.
* <p>
* The job can be started on the <code>MonitorAdmin</code> interface. Running
- * the job (querying the <code>StatusVariable</code>s, listening to changes,
- * and sending out notifications on updates) is the task of the
+ * the job (querying the <code>StatusVariable</code>s, listening to changes, and
+ * sending out notifications on updates) is the task of the
* <code>MonitorAdmin</code> implementation.
* <p>
* Whether a monitoring job keeps track dynamically of the
- * <code>StatusVariable</code>s it monitors is not specified. This means that
- * if we monitor a <code>StatusVariable</code> of a <code>Monitorable</code>
+ * <code>StatusVariable</code>s it monitors is not specified. This means that if
+ * we monitor a <code>StatusVariable</code> of a <code>Monitorable</code>
* service which disappears and later reappears then it is implementation
* specific whether we still receive updates of the <code>StatusVariable</code>
* changes or not.
+ *
+ * @version $Revision: 5673 $
*/
public interface MonitoringJob {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java
index 74ff9df..927e7ec 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/StatusVariable.java,v 1.14 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,6 +31,8 @@
* definition in the OSGi core specification. This means that only the
* characters [-_.a-zA-Z0-9] may be used. The length of the ID must not exceed
* 32 bytes when UTF-8 encoded.
+ *
+ * @version $Revision: 5673 $
*/
public final class StatusVariable {
//----- Public constants -----//
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/package.html
new file mode 100644
index 0000000..5350310
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Monitor Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.monitor; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java
index 7a182d7..0f15919 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/BackingStoreException.java,v 1.12 2006/07/11 13:15:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,63 +19,57 @@
* Thrown to indicate that a preferences operation could not complete because of
* a failure in the backing store, or a failure to contact the backing store.
*
- * @version $Revision: 1.12 $
+ * @version $Revision: 6083 $
*/
public class BackingStoreException extends Exception {
static final long serialVersionUID = -1415637364122829574L;
- /**
- * Nested exception.
- */
- private final Throwable cause;
/**
* Constructs a <code>BackingStoreException</code> with the specified detail
* message.
*
- * @param s The detail message.
+ * @param message The detail message.
*/
- public BackingStoreException(String s) {
- super(s);
- this.cause = null;
+ public BackingStoreException(String message) {
+ super(message);
}
/**
* Constructs a <code>BackingStoreException</code> with the specified detail
* message.
*
- * @param s The detail message.
+ * @param message The detail message.
* @param cause The cause of the exception. May be <code>null</code>.
* @since 1.1
*/
- public BackingStoreException(String s, Throwable cause) {
- super(s);
- this.cause = cause;
+ public BackingStoreException(String message, Throwable cause) {
+ super(message, cause);
}
-
+
/**
* Returns the cause of this exception or <code>null</code> if no cause was
- * specified when this exception was created.
+ * set.
*
* @return The cause of this exception or <code>null</code> if no cause was
- * specified.
- * @since 1.1
+ * set.
+ * @since 1.1
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
}
/**
- * The cause of this exception can only be set when constructed.
+ * Initializes the cause of this exception to the specified value.
*
- * @param cause Cause of the exception.
- * @return This object.
- * @throws java.lang.IllegalStateException This method will always throw an
- * <code>IllegalStateException</code> since the cause of this
- * exception can only be set when constructed.
- * @since 1.1
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ * @since 1.1
*/
public Throwable initCause(Throwable cause) {
- throw new IllegalStateException();
+ return super.initCause(cause);
}
-
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java
index c3a6cd0..8ffad3f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/Preferences.java,v 1.11 2006/07/11 00:54:04 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -110,7 +108,7 @@
* preference data.
*
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
*/
public interface Preferences {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java
index 19c1e34..a9d99a4 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/PreferencesService.java,v 1.10 2006/06/16 16:31:30 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/package.html
new file mode 100644
index 0000000..9bbffe2
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Preferences Service Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.prefs; version="[1.1,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/packageinfo
new file mode 100644
index 0000000..bb27c60
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/packageinfo
@@ -0,0 +1 @@
+version 1.1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java
index 00ec9e0..5ca31a5 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.provisioning/src/org/osgi/service/provisioning/ProvisioningService.java,v 1.11 2006/07/12 21:21:31 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,14 +29,15 @@
* these bundles to exchange information. It also provides a means for the
* initial Management Bundle to get its initial configuration information.
* <p>
- * The provisioning information is collected in a <code>Dictionary</code> object,
- * called the Provisioning Dictionary. Any bundle that can access the service
- * can get a reference to this object and read and update provisioning
- * information. The key of the dictionary is a <code>String</code> object and the
- * value is a <code>String</code> or <code>byte[]</code> object. The single
- * exception is the PROVISIONING_UPDATE_COUNT value which is an Integer. The
- * <code>provisioning</code> prefix is reserved for keys defined by OSGi, other
- * key names may be used for implementation dependent provisioning systems.
+ * The provisioning information is collected in a <code>Dictionary</code>
+ * object, called the Provisioning Dictionary. Any bundle that can access the
+ * service can get a reference to this object and read and update provisioning
+ * information. The key of the dictionary is a <code>String</code> object and
+ * the value is a <code>String</code> or <code>byte[]</code> object. The
+ * single exception is the PROVISIONING_UPDATE_COUNT value which is an Integer.
+ * The <code>provisioning</code> prefix is reserved for keys defined by OSGi,
+ * other key names may be used for implementation dependent provisioning
+ * systems.
* <p>
* Any changes to the provisioning information will be reflected immediately in
* all the dictionary objects obtained from the Provisioning Service.
@@ -54,11 +53,11 @@
* drastic consequences. Thus, only trusted bundles should be allowed to
* register and get the Provisioning Service. The <code>ServicePermission</code>
* is used to limit the bundles that can gain access to the Provisioning
- * Service. There is no check of <code>Permission</code> objects to read or modify
- * the provisioning information, so care must be taken not to leak the
+ * Service. There is no check of <code>Permission</code> objects to read or
+ * modify the provisioning information, so care must be taken not to leak the
* Provisioning Dictionary received from <code>getInformation</code> method.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 7347 $
*/
public interface ProvisioningService {
/**
@@ -66,17 +65,20 @@
* Service Platform. The value must be of type <code>String</code>.
*/
public final static String PROVISIONING_SPID = "provisioning.spid";
+
/**
* The key to the provisioning information that contains the location of the
* provision data provider. The value must be of type <code>String</code>.
*/
public final static String PROVISIONING_REFERENCE = "provisioning.reference";
+
/**
* The key to the provisioning information that contains the initial
* configuration information of the initial Management Agent. The value will
* be of type <code>byte[]</code>.
*/
public final static String PROVISIONING_AGENT_CONFIG = "provisioning.agent.config";
+
/**
* The key to the provisioning information that contains the update count of
* the info data. Each set of changes to the provisioning information must
@@ -85,39 +87,59 @@
* properties of the ProvisioningService in the service registry.
*/
public final static String PROVISIONING_UPDATE_COUNT = "provisioning.update.count";
+
/**
* The key to the provisioning information that contains the location of the
- * bundle to start with <code>AllPermission</code>. The bundle must have be
- * previously installed for this entry to have any effect.
+ * bundle to start with <code>AllPermission</code>. The bundle must have
+ * be previously installed for this entry to have any effect.
*/
public final static String PROVISIONING_START_BUNDLE = "provisioning.start.bundle";
+
/**
* The key to the provisioning information that contains the root X509
- * certificate used to esatblish trust with operator when using HTTPS.
+ * certificate used to establish trust with operator when using HTTPS.
*/
public final static String PROVISIONING_ROOTX509 = "provisioning.rootx509";
+
/**
* The key to the provisioning information that contains the shared secret
* used in conjunction with the RSH protocol.
*/
public final static String PROVISIONING_RSH_SECRET = "provisioning.rsh.secret";
+
/**
- * MIME type to be stored in the extra field of a <code>ZipEntry</code> object
- * for String data.
+ * MIME type to be stored in the extra field of a <code>ZipEntry</code>
+ * object for String data.
*/
public final static String MIME_STRING = "text/plain;charset=utf-8";
+
/**
- * MIME type to be stored in the extra field of a <code>ZipEntry</code> object
- * for <code>byte[]</code> data.
+ * MIME type to be stored stored in the extra field of a
+ * <code>ZipEntry</code> object for <code>byte[]</code> data.
*/
public final static String MIME_BYTE_ARRAY = "application/octet-stream";
+
/**
- * MIME type to be stored in the extra field of a <code>ZipEntry</code> object
- * for an installable bundle file. Zip entries of this type will be
+ * MIME type to be stored in the extra field of a <code>ZipEntry</code>
+ * object for an installable bundle file. Zip entries of this type will be
* installed in the framework, but not started. The entry will also not be
* put into the information dictionary.
*/
- public final static String MIME_BUNDLE = "application/x-osgi-bundle";
+ public final static String MIME_BUNDLE = "application/vnd.osgi.bundle";
+
+ /**
+ * Alternative MIME type to be stored in the extra field of a
+ * <code>ZipEntry</code> object for an installable bundle file. Zip entries
+ * of this type will be installed in the framework, but not started. The
+ * entry will also not be put into the information dictionary. This
+ * alternative entry is only for backward compatibility, new applications
+ * are recommended to use <code>MIME_BUNDLE</code>, which is an official
+ * IANA MIME type.
+ *
+ * @since 1.2
+ */
+ public final static String MIME_BUNDLE_ALT = "application/x-osgi-bundle";
+
/**
* MIME type to be stored in the extra field of a ZipEntry for a String that
* represents a URL for a bundle. Zip entries of this type will be used to
@@ -127,20 +149,30 @@
public final static String MIME_BUNDLE_URL = "text/x-osgi-bundle-url";
/**
+ * Name of the header that specifies the type information for the ZIP file
+ * entries.
+ *
+ * @since 1.2
+ */
+ public final static String INITIALPROVISIONING_ENTRIES = "InitialProvisioning-Entries";
+
+ /**
* Returns a reference to the Provisioning Dictionary. Any change operations
* (put and remove) to the dictionary will cause an
- * <code>UnsupportedOperationException</code> to be thrown. Changes must be
- * done using the <code>setInformation</code> and <code>addInformation</code>
- * methods of this service.
+ * <code>UnsupportedOperationException</code> to be thrown. Changes must
+ * be done using the <code>setInformation</code> and
+ * <code>addInformation</code> methods of this service.
+ *
* @return A reference to the Provisioning Dictionary.
*/
public Dictionary getInformation();
/**
* Replaces the Provisioning Information dictionary with the key/value pairs
- * contained in <code>info</code>. Any key/value pairs not in <code>info</code>
- * will be removed from the Provisioning Information dictionary. This method
- * causes the <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
+ * contained in <code>info</code>. Any key/value pairs not in
+ * <code>info</code> will be removed from the Provisioning Information
+ * dictionary. This method causes the <code>PROVISIONING_UPDATE_COUNT</code>
+ * to be incremented.
*
* @param info the new set of Provisioning Information key/value pairs. Any
* keys are values that are of an invalid type will be silently
@@ -149,8 +181,8 @@
public void setInformation(Dictionary info);
/**
- * Adds the key/value pairs contained in <code>info</code> to the Provisioning
- * Information dictionary. This method causes the
+ * Adds the key/value pairs contained in <code>info</code> to the
+ * Provisioning Information dictionary. This method causes the
* <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
*
* @param info the set of Provisioning Information key/value pairs to add to
@@ -160,22 +192,22 @@
public void addInformation(Dictionary info);
/**
- * Processes the <code>ZipInputStream</code> and extracts information to add
- * to the Provisioning Information dictionary, as well as, install/update
- * and start bundles. This method causes the
+ * Processes the <code>ZipInputStream</code> and extracts information to
+ * add to the Provisioning Information dictionary, as well as,
+ * install/update and start bundles. This method causes the
* <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
*
* @param zis the <code>ZipInputStream</code> that will be used to add
* key/value pairs to the Provisioning Information dictionary and
- * install and start bundles. If a <code>ZipEntry</code> does not have
- * an <code>Extra</code> field that corresponds to one of the four
- * defined MIME types (<code>MIME_STRING</code>,
+ * install and start bundles. If a <code>ZipEntry</code> does not
+ * have an <code>Extra</code> field that corresponds to one of the
+ * four defined MIME types (<code>MIME_STRING</code>,
* <code>MIME_BYTE_ARRAY</code>,<code>MIME_BUNDLE</code>, and
* <code>MIME_BUNDLE_URL</code>) in will be silently ignored.
* @throws IOException if an error occurs while processing the
- * ZipInputStream. No additions will be made to the Provisioning
- * Information dictionary and no bundles must be started or
- * installed.
+ * ZipInputStream. No additions will be made to the Provisioning
+ * Information dictionary and no bundles must be started or
+ * installed.
*/
public void addInformation(ZipInputStream zis) throws IOException;
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/package.html
new file mode 100644
index 0000000..8c28950
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Provisioning Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.provisioning; version="[1.2,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java
index 2d16666..742673f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPAction.java,v 1.10 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +22,8 @@
*
* Each UPnP service contains zero or more actions. Each action may have zero or
* more UPnP state variables as arguments.
- *
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPAction {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java
index 72f017b..24ce178 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPDevice.java,v 1.9 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +34,8 @@
* <p>
* If an application wants to query for a set of localized property values, it
* has to use the method <code>UPnPDevice.getDescriptions(String locale)</code>.
- *
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPDevice {
/*
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java
index 4c1641c..80d4455 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPEventListener.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,9 +23,9 @@
* generated by a particular UPnP Device registers a service extending this
* interface.
* <p>
- * The notification call from the UPnP Service to any <code>UPnPEventListener</code>
- * object must be done asynchronous with respect to the originator (in a
- * separate thread).
+ * The notification call from the UPnP Service to any
+ * <code>UPnPEventListener</code> object must be done asynchronous with respect
+ * to the originator (in a separate thread).
* <p>
* Upon registration of the UPnP Event Listener service with the Framework, the
* service is notified for each variable which it listens for with an initial
@@ -56,6 +54,8 @@
* <li><code>UPnPService.ID</code>-- The ID of a specific service to listen for
* events.</li>
* </ul>
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPEventListener {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java
index 61dc481..172c995 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPException.java,v 1.14 2006/07/12 21:21:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +15,12 @@
*/
package org.osgi.service.upnp;
-
/**
* There are several defined error situations describing UPnP problems while a
* control point invokes actions to UPnPDevices.
*
* @since 1.1
+ * @version $Revision: 5673 $
*/
public class UPnPException extends Exception {
static final long serialVersionUID = -262013318122195146L;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java
index 36a3db7..8b99be9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPIcon.java,v 1.12 2006/07/12 21:21:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +22,8 @@
* A UPnP icon representation.
*
* Each UPnP device can contain zero or more icons.
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPIcon {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java
index bdc0b8a..241fb8a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPLocalStateVariable.java,v 1.12 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +27,8 @@
* be queried.
*
* @since 1.1
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPLocalStateVariable extends UPnPStateVariable {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
index 4eafb32..64b5894 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPService.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +20,8 @@
*
* Each UPnP device contains zero or more services. The UPnP description for a
* service defines actions, their arguments, and event characteristics.
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPService {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
index c758c88..27b7241 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPStateVariable.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,13 +19,15 @@
* The meta-information of a UPnP state variable as declared in the device's
* service state table (SST).
* <p>
- * Method calls to interact with a device (e.g. <code>UPnPAction.invoke(...);</code>)
- * use this class to encapsulate meta information about the input and output
- * arguments.
+ * Method calls to interact with a device (e.g.
+ * <code>UPnPAction.invoke(...);</code>) use this class to encapsulate meta
+ * information about the input and output arguments.
* <p>
* The actual values of the arguments are passed as Java objects. The mapping of
* types from UPnP data types to Java data types is described with the field
* definitions.
+ *
+ * @version $Revision: 5673 $
*/
public interface UPnPStateVariable {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
new file mode 100644
index 0000000..5422e04
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>UPnP Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.upnp; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
index 618a0f1..94289f7 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Authorization.java,v 1.11 2007/02/07 18:53:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +58,7 @@
* <code>Authorization</code> object), the service explicitly checks that the
* calling bundle has permission to make the call.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
*/
public interface Authorization {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
index 92671ca..4016a43 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Group.java,v 1.8 2006/06/16 16:31:41 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -87,7 +85,7 @@
*
* </pre>
*
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
*/
public interface Group extends User {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
index 72b021b..e33d559 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Role.java,v 1.10 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +45,7 @@
* <code>UserAdminPermission</code> in the same way that properties for other
* <code>Role</code> objects are.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
*/
public interface Role {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
index 9baa0b3..b9103fd 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/User.java,v 1.9 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +37,7 @@
* Credentials are <code>Dictionary</code> objects and have semantics that are
* similar to the properties in the <code>Role</code> class.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
*/
public interface User extends Role {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
index 49248bc..2e4b096 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdmin.java,v 1.12 2006/07/12 21:21:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +43,7 @@
* <code>Role</code> objects, in which each <code>Role</code> object has a unique
* name.
*
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
*/
public interface UserAdmin {
/**
@@ -74,7 +72,7 @@
/**
* Removes the <code>Role</code> object with the given name from this User
- * Admin service.
+ * Admin service and all groups it is a member of.
*
* <p>
* If the <code>Role</code> object was removed, a <code>UserAdminEvent</code>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
index 0cb16a7..88ef8fb 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java,v 1.9 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +33,7 @@
* @see UserAdmin
* @see UserAdminListener
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
*/
public class UserAdminEvent {
private ServiceReference ref;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
index d0ab85e..a301b92 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminListener.java,v 1.8 2006/06/16 16:31:41 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +30,7 @@
* @see UserAdmin
* @see UserAdminEvent
*
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
*/
public interface UserAdminListener {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
index a281a13..52be194 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java,v 1.13 2006/07/12 21:21:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +16,9 @@
package org.osgi.service.useradmin;
import java.io.IOException;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
import java.util.Enumeration;
import java.util.Hashtable;
@@ -27,8 +27,8 @@
* Admin service.
*
* <p>
- * This class represents access to the <code>Role</code> objects managed by a User
- * Admin service and their properties and credentials (in the case of
+ * This class represents access to the <code>Role</code> objects managed by a
+ * User Admin service and their properties and credentials (in the case of
* {@link User} objects).
* <p>
* The permission name is the name (or name prefix) of a property or credential.
@@ -40,10 +40,11 @@
*
* <p>
* The <code>UserAdminPermission</code> with the reserved name "admin"
- * represents the permission required for creating and removing <code>Role</code>
- * objects in the User Admin service, as well as adding and removing members in
- * a <code>Group</code> object. This <code>UserAdminPermission</code> does not have
- * any actions associated with it.
+ * represents the permission required for creating and removing
+ * <code>Role</code> objects in the User Admin service, as well as adding and
+ * removing members in a <code>Group</code> object. This
+ * <code>UserAdminPermission</code> does not have any actions associated with
+ * it.
*
* <p>
* The actions to be granted are passed to the constructor in a string
@@ -64,7 +65,7 @@
* existence of User object credentials whose names
* start with the name argument specified in the
* constructor.
- *
+ *
* </pre>
*
* The action string is converted to lowercase before processing.
@@ -78,7 +79,7 @@
* (org.osgi.service.useradmin.UserAdminPermission "admin")
* (org.osgi.service.useradmin.UserAdminPermission "com.foo.*" "changeProperty,getCredential,changeCredential")
* (org.osgi.service.useradmin.UserAdminPermission "user.*", "changeProperty,changeCredential")
- *
+ *
* </pre>
*
* The first permission statement grants the bundle the permission to perform
@@ -106,7 +107,7 @@
* permission org.osgi.service.useradmin.UserAdminPermission
* "user.password", "getCredential";
* };
- *
+ *
* </pre>
*
* <p>
@@ -114,10 +115,11 @@
* validate any password credentials (for authentication purposes), but the
* bundle is not allowed to change any properties or credentials.
*
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
*/
public final class UserAdminPermission extends BasicPermission {
- static final long serialVersionUID = -1179971692401603789L;
+ static final long serialVersionUID = -1179971692401603789L;
/**
* The permission name "admin".
*/
@@ -146,30 +148,26 @@
/**
* No actions.
*/
- static final int ACTION_NONE = 0x0;
+ static final int ACTION_NONE = 0;
/**
* The actions in canonical form.
*
* @serial
*/
- private String actions = null;
+ private volatile String actions = null;
/**
* The actions mask.
*/
- private transient int action_mask = ACTION_NONE;
- /*
- * Description of this <code> UserAdminPermission </code> (returned by <code>
- * toString </code> )
- */
- private transient String description;
+ private transient int action_mask;
/**
- * Creates a new <code>UserAdminPermission</code> with the specified name and
- * actions. <code>name</code> is either the reserved string "admin"
- * or the name of a credential or property, and <code>actions</code> contains
- * a comma-separated list of the actions granted on the specified name.
- * Valid actions are <code>changeProperty</code>,<code>changeCredential</code>,
- * and getCredential.
+ * Creates a new <code>UserAdminPermission</code> with the specified name
+ * and actions. <code>name</code> is either the reserved string
+ * "admin" or the name of a credential or property, and
+ * <code>actions</code> contains a comma-separated list of the actions
+ * granted on the specified name. Valid actions are
+ * <code>changeProperty</code>,<code>changeCredential</code>, and
+ * getCredential.
*
* @param name the name of this <code>UserAdminPermission</code>
* @param actions the action string.
@@ -178,7 +176,7 @@
* "admin" and <code>actions</code> are specified.
*/
public UserAdminPermission(String name, String actions) {
- this(name, getMask(actions));
+ this(name, parseActions(actions));
}
/**
@@ -190,7 +188,7 @@
*/
UserAdminPermission(String name, int mask) {
super(name);
- init(mask);
+ setTransients(mask);
}
/**
@@ -198,7 +196,7 @@
*
* @param mask action mask
*/
- private void init(int mask) {
+ private synchronized void setTransients(int mask) {
if (getName().equals(ADMIN)) {
if (mask != ACTION_NONE) {
throw new IllegalArgumentException("Actions specified for "
@@ -214,21 +212,32 @@
}
/**
- * Parses the action string into the action mask.
+ * Returns the current action mask.
+ * <p>
+ * Used by the UserAdminPermissionCollection class.
+ *
+ * @return Current action mask.
+ */
+ synchronized int getActionsMask() {
+ return action_mask;
+ }
+
+ /**
+ * Parse action string into action mask.
*
* @param actions Action string.
* @return action mask.
*/
- private static int getMask(String actions) {
+ private static int parseActions(String actions) {
boolean seencomma = false;
int mask = ACTION_NONE;
if (actions == null) {
- return (mask);
+ return mask;
}
char[] a = actions.toCharArray();
int i = a.length - 1;
if (i < 0)
- return (mask);
+ return mask;
while (i != -1) {
char c;
// skip whitespace
@@ -265,7 +274,7 @@
switch (a[i - matchlen]) {
case ',' :
seencomma = true;
- /* FALLTHROUGH */
+ /* FALLTHROUGH */
case ' ' :
case '\r' :
case '\n' :
@@ -284,7 +293,7 @@
if (seencomma) {
throw new IllegalArgumentException("invalid permission: " + actions);
}
- return (mask);
+ return mask;
}
private static boolean match_change(char[] a, int i) {
@@ -323,15 +332,14 @@
}
/**
- * Checks if this <code>UserAdminPermission</code> object "implies"
- * the specified permission.
+ * Checks if this <code>UserAdminPermission</code> object
+ * "implies" the specified permission.
* <P>
* More specifically, this method returns <code>true</code> if:
* <p>
* <ul>
* <li><i>p </i> is an instanceof <code>UserAdminPermission</code>,
- * <li><i>p </i>'s actions are a proper subset of this object's actions,
- * and
+ * <li><i>p </i>'s actions are a proper subset of this object's actions, and
* <li><i>p </i>'s name is implied by this object's name. For example,
* "java.*" implies "java.home".
* </ul>
@@ -343,19 +351,18 @@
*/
public boolean implies(Permission p) {
if (p instanceof UserAdminPermission) {
- UserAdminPermission target = (UserAdminPermission) p;
- return (// Check that the we have the requested action
- ((target.action_mask & action_mask) == target.action_mask)
- &&
- // If the target action mask is ACTION_NONE, it must be an
+ UserAdminPermission requested = (UserAdminPermission) p;
+ int mask = getActionsMask();
+ int targetMask = requested.getActionsMask();
+ return // Check that the we have the requested action
+ ((targetMask & mask) == targetMask) &&
+ // If the target action mask is ACTION_NONE, it must be an
// admin permission, and then we must be that too
- (target.action_mask != ACTION_NONE || action_mask == ACTION_NONE) &&
- // Check that name name matches
- super.implies(p));
+ (targetMask != ACTION_NONE || mask == ACTION_NONE) &&
+ // Check that name name matches
+ super.implies(p);
}
- else {
- return (false);
- }
+ return false;
}
/**
@@ -365,38 +372,40 @@
* @return the canonical string representation of the actions.
*/
public String getActions() {
- if (actions == null) {
+ String result = actions;
+ if (result == null) {
StringBuffer sb = new StringBuffer();
boolean comma = false;
- if ((action_mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
+ int mask = getActionsMask();
+ if ((mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
sb.append(CHANGE_CREDENTIAL);
comma = true;
}
- if ((action_mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
+ if ((mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
if (comma)
sb.append(',');
sb.append(CHANGE_PROPERTY);
comma = true;
}
- if ((action_mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
+ if ((mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
if (comma)
sb.append(',');
sb.append(GET_CREDENTIAL);
}
- actions = sb.toString();
+ actions = result = sb.toString();
}
- return (actions);
+ return result;
}
/**
* Returns a new <code>PermissionCollection</code> object for storing
* <code>UserAdminPermission</code> objects.
*
- * @return a new <code>PermissionCollection</code> object suitable for storing
- * <code>UserAdminPermission</code> objects.
+ * @return a new <code>PermissionCollection</code> object suitable for
+ * storing <code>UserAdminPermission</code> objects.
*/
public PermissionCollection newPermissionCollection() {
- return (new UserAdminPermissionCollection());
+ return new UserAdminPermissionCollection();
}
/**
@@ -407,38 +416,32 @@
* @param obj the object to be compared for equality with this object.
*
* @return <code>true</code> if <code>obj</code> is a
- * <code>UserAdminPermission</code> object, and has the same name and
- * actions as this <code>UserAdminPermission</code> object.
+ * <code>UserAdminPermission</code> object, and has the same name
+ * and actions as this <code>UserAdminPermission</code> object.
*/
public boolean equals(Object obj) {
if (obj == this) {
- return (true);
+ return true;
}
- if (obj instanceof UserAdminPermission) {
- UserAdminPermission uap = (UserAdminPermission) obj;
- return ((action_mask == uap.action_mask) && getName().equals(
- uap.getName()));
+ if (!(obj instanceof UserAdminPermission)) {
+ return false;
}
- else {
- return (false);
- }
+
+ UserAdminPermission uap = (UserAdminPermission) obj;
+
+ return (getActionsMask() == uap.getActionsMask())
+ && getName().equals(uap.getName());
}
/**
- * Returns the hash code of this <code>UserAdminPermission</code> object.
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
*/
public int hashCode() {
- return (getName().hashCode() ^ getActions().hashCode());
- }
-
- /**
- * Returns the current action mask. Used by the
- * <code>UserAdminPermissionCollection</code> class.
- *
- * @return the actions mask.
- */
- int getMask() {
- return (action_mask);
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
}
/**
@@ -457,10 +460,11 @@
/*
* Restores this object from a stream (i.e., deserializes it).
*/
- private synchronized void readObject(java.io.ObjectInputStream ois)
+ private synchronized void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- init(getMask(actions));
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ setTransients(parseActions(actions));
}
/**
@@ -472,42 +476,42 @@
* @see "<code>org.osgi.service.permissionadmin.PermissionInfo.getEncoded</code>"
*/
public String toString() {
- if (description == null) {
- StringBuffer sb = new StringBuffer();
- sb.append('(');
- sb.append(getClass().getName());
- sb.append(" \"");
- sb.append(getName());
- String actions = getActions();
- if (actions.length() > 0) {
- sb.append("\" \"");
- sb.append(actions);
- }
- sb.append("\")");
- description = sb.toString();
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ sb.append(getClass().getName());
+ sb.append(" \"");
+ sb.append(getName());
+ String a = getActions();
+ if (a.length() > 0) {
+ sb.append("\" \"");
+ sb.append(a);
}
- return (description);
+ sb.append("\")");
+ return sb.toString();
}
}
+
/**
* A <code>UserAdminPermissionCollection</code> stores a set of
* <code>UserAdminPermission</code> permissions.
*/
final class UserAdminPermissionCollection extends PermissionCollection {
- static final long serialVersionUID = -7222111885230120581L;
+ static final long serialVersionUID = -7222111885230120581L;
/**
* Table of permissions.
*
* @serial
+ * @GuardedBy this
*/
- private Hashtable permissions;
+ private final Hashtable permissions;
/**
* Boolean saying if "*" is in the collection.
*
* @serial
+ * @GuardedBy this
*/
- private boolean all_allowed;
+ private boolean all_allowed;
/**
* Creates an empty <code>UserAdminPermissionCollection</code> object.
@@ -518,15 +522,17 @@
}
/**
- * Adds the given permission to this <code>UserAdminPermissionCollection</code>.
- * The key for the hash is the name.
+ * Adds the given permission to this
+ * <code>UserAdminPermissionCollection</code>. The key for the hash is the
+ * name.
*
* @param permission the <code>Permission</code> object to add.
*
* @throws IllegalArgumentException If the given permission is not a
* <code>UserAdminPermission</code>
- * @throws SecurityException If this <code>UserAdminPermissionCollection</code>
- * object has been marked readonly
+ * @throws SecurityException If this
+ * <code>UserAdminPermissionCollection</code> object has been marked
+ * readonly
*/
public void add(Permission permission) {
if (!(permission instanceof UserAdminPermission))
@@ -536,24 +542,27 @@
throw new SecurityException("Attempt to add a Permission to a "
+ "readonly PermissionCollection");
}
- UserAdminPermission uap = (UserAdminPermission) permission;
- String name = uap.getName();
- UserAdminPermission existing = (UserAdminPermission) permissions
- .get(name);
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = uap.getMask();
- if (oldMask != newMask) {
- permissions.put(name, new UserAdminPermission(name, oldMask
- | newMask));
+ final UserAdminPermission uap = (UserAdminPermission) permission;
+ final String name = uap.getName();
+ synchronized (this) {
+ final UserAdminPermission existing = (UserAdminPermission) permissions
+ .get(name);
+ if (existing != null) {
+ int oldMask = existing.getActionsMask();
+ int newMask = uap.getActionsMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new UserAdminPermission(name, oldMask
+ | newMask));
+ }
}
- }
- else {
- permissions.put(name, permission);
- }
- if (!all_allowed) {
- if (name.equals("*"))
- all_allowed = true;
+ else {
+ permissions.put(name, uap);
+ }
+ if (!all_allowed) {
+ if (name.equals("*")) {
+ all_allowed = true;
+ }
+ }
}
}
@@ -568,33 +577,36 @@
*/
public boolean implies(Permission permission) {
if (!(permission instanceof UserAdminPermission)) {
- return (false);
+ return false;
}
- UserAdminPermission uap = (UserAdminPermission) permission;
+ final UserAdminPermission requested = (UserAdminPermission) permission;
+ String name = requested.getName();
+ final int desired = requested.getActionsMask();
UserAdminPermission x;
- int desired = uap.getMask();
int effective = 0;
- // Short circuit if the "*" Permission was added.
- // desired can only be ACTION_NONE when name is "admin".
- if (all_allowed && desired != UserAdminPermission.ACTION_NONE) {
- x = (UserAdminPermission) permissions.get("*");
- if (x != null) {
- effective |= x.getMask();
- if ((effective & desired) == desired) {
- return (true);
+ synchronized (this) {
+ // Short circuit if the "*" Permission was added.
+ // desired can only be ACTION_NONE when name is "admin".
+ if (all_allowed && (desired != UserAdminPermission.ACTION_NONE)) {
+ x = (UserAdminPermission) permissions.get("*");
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
}
}
+ // strategy:
+ // Check for full match first. Then work our way up the
+ // name looking for matches on a.b.*
+
+ x = (UserAdminPermission) permissions.get(name);
}
- // strategy:
- // Check for full match first. Then work our way up the
- // name looking for matches on a.b.*
- String name = uap.getName();
- x = (UserAdminPermission) permissions.get(name);
if (x != null) {
// we have a direct hit!
- effective |= x.getMask();
+ effective |= x.getActionsMask();
if ((effective & desired) == desired) {
- return (true);
+ return true;
}
}
// work our way up the tree...
@@ -602,27 +614,30 @@
int offset = name.length() - 1;
while ((last = name.lastIndexOf(".", offset)) != -1) {
name = name.substring(0, last + 1) + "*";
- x = (UserAdminPermission) permissions.get(name);
+ synchronized (this) {
+ x = (UserAdminPermission) permissions.get(name);
+ }
if (x != null) {
- effective |= x.getMask();
+ effective |= x.getActionsMask();
if ((effective & desired) == desired) {
- return (true);
+ return true;
}
}
offset = last - 1;
}
// we don't have to check for "*" as it was already checked
// at the top (all_allowed), so we just return false
- return (false);
+ return false;
}
/**
- * Returns an enumeration of all the <code>UserAdminPermission</code> objects
- * in the container.
+ * Returns an enumeration of all the <code>UserAdminPermission</code>
+ * objects in the container.
*
- * @return an enumeration of all the <code>UserAdminPermission</code> objects.
+ * @return an enumeration of all the <code>UserAdminPermission</code>
+ * objects.
*/
public Enumeration elements() {
- return (permissions.elements());
+ return permissions.elements();
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
new file mode 100644
index 0000000..c8c223d
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>User Admin Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.useradmin; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
index 8d7aada..49df68a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/BasicEnvelope.java,v 1.9 2006/06/16 16:31:43 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +19,7 @@
* <code>BasicEnvelope</code> is an implementation of the {@link Envelope}
* interface
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
*/
public class BasicEnvelope implements Envelope {
Object value;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
index 5da384c..cef1c1c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Consumer.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,7 +51,7 @@
* different types of objects from the Producer service. The Consumer service
* should have <code>WirePermission</code> for each of these scope names.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
*/
public interface Consumer {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
index bf3d61a..5f57638 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Envelope.java,v 1.8 2006/06/16 16:31:43 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +43,7 @@
* @see WirePermission
* @see BasicEnvelope
*
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
*/
public interface Envelope {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
index 3657a7a..faf6dfd 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Producer.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,7 +64,7 @@
* different types of objects (composite) to the Consumer service. The Producer
* service should have <code>WirePermission</code> for each of these scope names.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
*/
public interface Producer {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
index b972a35..9e0c1a9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Wire.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,7 +53,7 @@
* is used in communication. The semantics of the names depend on the Producer
* service and must not be interpreted by the Wire Admin service.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
*/
public interface Wire {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
index 98a32b9..578ef4f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdmin.java,v 1.11 2006/07/12 21:22:14 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +36,7 @@
* <code>ServicePermission[WireAdmin,GET]</code> to get the Wire Admin service to
* create, modify, find, and delete <code>Wire</code> objects.
*
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
*/
public interface WireAdmin {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
index e2f3084..bba84ef 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdminEvent.java,v 1.9 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,7 +54,7 @@
*
* @see WireAdminListener
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
*/
public class WireAdminEvent {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
index 9e7b04d..e741dd9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdminListener.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,7 +56,7 @@
*
* @see WireAdminEvent
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
*/
public interface WireAdminListener {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
index 5190b9b..b616a4f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireConstants.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +19,7 @@
* Defines standard names for <code>Wire</code> properties, wire filter
* attributes, Consumer and Producer service properties.
*
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
*/
public interface WireConstants {
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
index b161002..6073466 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WirePermission.java,v 1.13 2006/07/12 21:22:14 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,15 +16,17 @@
package org.osgi.service.wireadmin;
import java.io.IOException;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
import java.util.Enumeration;
import java.util.Hashtable;
/**
* Permission for the scope of a <code>Wire</code> object. When a
- * <code>Envelope</code> object is used for communication with the <code>poll</code>
- * or <code>update</code> method, and the scope is set, then the <code>Wire</code>
- * object must verify that the Consumer service has
+ * <code>Envelope</code> object is used for communication with the
+ * <code>poll</code> or <code>update</code> method, and the scope is set, then
+ * the <code>Wire</code> object must verify that the Consumer service has
* <code>WirePermission[name,CONSUME]</code> and the Producer service has
* <code>WirePermission[name,PRODUCE]</code> for all names in the scope.
* <p>
@@ -35,43 +35,45 @@
* scope names starting with the string "Door". The last period is required due
* to the implementations of the <code>BasicPermission</code> class.
*
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
*/
final public class WirePermission extends BasicPermission {
- static final long serialVersionUID = -5583709391516569321L;
+ static final long serialVersionUID = -5583709391516569321L;
/**
- * The action string for the <code>PRODUCE</code> action: value is "produce".
+ * The action string for the <code>produce</code> action.
*/
- public static final String PRODUCE = "produce";
+ public static final String PRODUCE = "produce";
/**
- * The action string for the <code>CONSUME</code> action: value is "consume".
+ * The action string for the <code>consume</code> action.
*/
- public static final String CONSUME = "consume";
- private final static int ACTION_PRODUCE = 0x00000001;
- private final static int ACTION_CONSUME = 0x00000002;
- private final static int ACTION_ALL = ACTION_PRODUCE
- | ACTION_CONSUME;
- private final static int ACTION_NONE = 0;
+ public static final String CONSUME = "consume";
+ private final static int ACTION_PRODUCE = 0x00000001;
+ private final static int ACTION_CONSUME = 0x00000002;
+ private final static int ACTION_ALL = ACTION_PRODUCE
+ | ACTION_CONSUME;
+ private final static int ACTION_NONE = 0;
/**
* The actions mask.
*/
- private transient int action_mask = ACTION_NONE;
+ private transient int action_mask;
/**
* The actions in canonical form.
*
* @serial
*/
- private String actions = null;
+ private volatile String actions = null;
/**
* Create a new WirePermission with the given name (may be wildcard) and
* actions.
+ *
* @param name Wire name.
- * @param actions <code>produce</code>, <code>consume</code>
- * (canonical order).
+ * @param actions <code>produce</code>, <code>consume</code> (canonical
+ * order).
*/
public WirePermission(String name, String actions) {
- this(name, getMask(actions));
+ this(name, parseActions(actions));
}
/**
@@ -82,7 +84,7 @@
*/
WirePermission(String name, int mask) {
super(name);
- init(mask);
+ setTransients(mask);
}
/**
@@ -90,7 +92,7 @@
*
* @param mask action mask
*/
- private void init(int mask) {
+ private synchronized void setTransients(int mask) {
if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
throw new IllegalArgumentException("invalid action string");
}
@@ -98,12 +100,22 @@
}
/**
+ * Returns the current action mask. Used by the WirePermissionCollection
+ * object.
+ *
+ * @return The actions mask.
+ */
+ synchronized int getActionsMask() {
+ return action_mask;
+ }
+
+ /**
* Parse action string into action mask.
*
* @param actions Action string.
* @return action mask.
*/
- private static int getMask(String actions) {
+ private static int parseActions(String actions) {
boolean seencomma = false;
int mask = ACTION_NONE;
if (actions == null) {
@@ -155,7 +167,7 @@
switch (a[i - matchlen]) {
case ',' :
seencomma = true;
- /* FALLTHROUGH */
+ /* FALLTHROUGH */
case ' ' :
case '\r' :
case '\n' :
@@ -178,15 +190,14 @@
}
/**
- * Checks if this <code>WirePermission</code> object <code>implies</code> the
- * specified permission.
+ * Checks if this <code>WirePermission</code> object <code>implies</code>
+ * the specified permission.
* <P>
* More specifically, this method returns <code>true</code> if:
* <p>
* <ul>
* <li><i>p </i> is an instanceof the <code>WirePermission</code> class,
- * <li><i>p </i>'s actions are a proper subset of this object's actions,
- * and
+ * <li><i>p </i>'s actions are a proper subset of this object's actions, and
* <li><i>p </i>'s name is implied by this object's name. For example,
* <code>java.*</code> implies <code>java.home</code>.
* </ul>
@@ -198,8 +209,9 @@
*/
public boolean implies(Permission p) {
if (p instanceof WirePermission) {
- WirePermission target = (WirePermission) p;
- return ((action_mask & target.action_mask) == target.action_mask)
+ WirePermission requested = (WirePermission) p;
+ int requestedMask = requested.getActionsMask();
+ return ((getActionsMask() & requestedMask) == requestedMask)
&& super.implies(p);
}
return false;
@@ -213,29 +225,31 @@
* @return The canonical string representation of the actions.
*/
public String getActions() {
- if (actions == null) {
+ String result = actions;
+ if (result == null) {
StringBuffer sb = new StringBuffer();
boolean comma = false;
- if ((action_mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
+ int mask = getActionsMask();
+ if ((mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
sb.append(PRODUCE);
comma = true;
}
- if ((action_mask & ACTION_CONSUME) == ACTION_CONSUME) {
+ if ((mask & ACTION_CONSUME) == ACTION_CONSUME) {
if (comma)
sb.append(',');
sb.append(CONSUME);
}
- actions = sb.toString();
+ actions = result = sb.toString();
}
- return actions;
+ return result;
}
/**
* Returns a new <code>PermissionCollection</code> object for storing
* <code>WirePermission</code> objects.
*
- * @return A new <code>PermissionCollection</code> object suitable for storing
- * <code>WirePermission</code> objects.
+ * @return A new <code>PermissionCollection</code> object suitable for
+ * storing <code>WirePermission</code> objects.
*/
public PermissionCollection newPermissionCollection() {
return new WirePermissionCollection();
@@ -248,8 +262,8 @@
* <code>WirePermission</code> object.
*
* @param obj The object to test for equality.
- * @return true if <code>obj</code> is a <code>WirePermission</code>, and has
- * the same name and actions as this <code>WirePermission</code>
+ * @return true if <code>obj</code> is a <code>WirePermission</code>, and
+ * has the same name and actions as this <code>WirePermission</code>
* object; <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
@@ -259,8 +273,9 @@
if (!(obj instanceof WirePermission)) {
return false;
}
- WirePermission p = (WirePermission) obj;
- return (action_mask == p.action_mask) && getName().equals(p.getName());
+ WirePermission wp = (WirePermission) obj;
+ return (getActionsMask() == wp.getActionsMask())
+ && getName().equals(wp.getName());
}
/**
@@ -269,17 +284,9 @@
* @return Hash code value for this object.
*/
public int hashCode() {
- return getName().hashCode() ^ getActions().hashCode();
- }
-
- /**
- * Returns the current action mask. Used by the WirePermissionCollection
- * object.
- *
- * @return The actions mask.
- */
- int getMask() {
- return action_mask;
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
}
/**
@@ -297,8 +304,11 @@
sb.append(getClass().getName());
sb.append(" \"");
sb.append(getName());
- sb.append("\" \"");
- sb.append(getActions());
+ String a = getActions();
+ if (a.length() > 0) {
+ sb.append("\" \"");
+ sb.append(a);
+ }
sb.append("\")");
return sb.toString();
}
@@ -325,32 +335,35 @@
throws IOException, ClassNotFoundException {
// Read in the action, then initialize the rest
s.defaultReadObject();
- init(getMask(actions));
+ setTransients(parseActions(actions));
}
}
+
/**
- * A <code>WirePermissionCollection</code> stores a set of <code>WirePermission</code>
- * permissions.
+ * A <code>WirePermissionCollection</code> stores a set of
+ * <code>WirePermission</code> permissions.
*/
final class WirePermissionCollection extends PermissionCollection {
- static final long serialVersionUID = 2617521094909826016L;
+ static final long serialVersionUID = 2617521094909826016L;
/**
* Table of permissions.
*
+ * @GuardedBy this
* @serial
*/
- private Hashtable permissions;
+ private final Hashtable permissions;
/**
* Boolean saying if "*" is in the collection.
*
+ * @GuardedBy this
* @serial
*/
- private boolean all_allowed;
+ private boolean all_allowed;
/**
* Creates an empty WirePermissionCollection object.
- *
+ *
*/
public WirePermissionCollection() {
permissions = new Hashtable();
@@ -363,35 +376,40 @@
* @param permission The Permission object to add.
*
* @throws IllegalArgumentException If the permission is not a
- * WirePermission object.
+ * WirePermission object.
*
* @throws SecurityException If this PermissionCollection has been marked
- * read-only.
+ * read-only.
*/
public void add(Permission permission) {
- if (!(permission instanceof WirePermission))
+ if (!(permission instanceof WirePermission)) {
throw new IllegalArgumentException("invalid permission: "
+ permission);
- if (isReadOnly())
+ }
+ if (isReadOnly()) {
throw new SecurityException("attempt to add a Permission to a "
+ "readonly PermissionCollection");
- WirePermission p = (WirePermission) permission;
- String name = p.getName();
- WirePermission existing = (WirePermission) permissions.get(name);
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = p.getMask();
- if (oldMask != newMask) {
- permissions.put(name, new WirePermission(name, oldMask
- | newMask));
+ }
+ WirePermission wp = (WirePermission) permission;
+ String name = wp.getName();
+ synchronized (this) {
+ WirePermission existing = (WirePermission) permissions.get(name);
+ if (existing != null) {
+ int oldMask = existing.getActionsMask();
+ int newMask = wp.getActionsMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new WirePermission(name, oldMask
+ | newMask));
+ }
}
- }
- else {
- permissions.put(name, permission);
- }
- if (!all_allowed) {
- if (name.equals("*"))
- all_allowed = true;
+ else {
+ permissions.put(name, wp);
+ }
+ if (!all_allowed) {
+ if (name.equals("*")) {
+ all_allowed = true;
+ }
+ }
}
}
@@ -401,46 +419,53 @@
*
* @param permission The Permission object to compare.
*
- * @return <code>true</code> if <code>permission</code> is a proper subset of a
- * permission in the set; <code>false</code> otherwise.
+ * @return <code>true</code> if <code>permission</code> is a proper subset
+ * of a permission in the set; <code>false</code> otherwise.
*/
public boolean implies(Permission permission) {
- if (!(permission instanceof WirePermission))
+ if (!(permission instanceof WirePermission)) {
return false;
- WirePermission p = (WirePermission) permission;
- WirePermission x;
- int desired = p.getMask();
- int effective = 0;
- // short circuit if the "*" Permission was added
- if (all_allowed) {
- x = (WirePermission) permissions.get("*");
- if (x != null) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
- }
}
- // strategy:
- // Check for full match first. Then work our way up the
- // name looking for matches on a.b.*
- String name = p.getName();
- x = (WirePermission) permissions.get(name);
+ WirePermission requested = (WirePermission) permission;
+ WirePermission x;
+ int desired = requested.getActionsMask();
+ int effective = 0;
+ String name = requested.getName();
+ synchronized (this) {
+ // short circuit if the "*" Permission was added
+ if (all_allowed) {
+ x = (WirePermission) permissions.get("*");
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired)
+ return true;
+ }
+ }
+ // strategy:
+ // Check for full match first. Then work our way up the
+ // name looking for matches on a.b.*
+ x = (WirePermission) permissions.get(name);
+ }
if (x != null) {
// we have a direct hit!
- effective |= x.getMask();
- if ((effective & desired) == desired)
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
return true;
+ }
}
// work our way up the tree...
- int last, offset;
- offset = name.length() - 1;
+ int last;
+ int offset = name.length() - 1;
while ((last = name.lastIndexOf(".", offset)) != -1) {
name = name.substring(0, last + 1) + "*";
- x = (WirePermission) permissions.get(name);
+ synchronized (this) {
+ x = (WirePermission) permissions.get(name);
+ }
if (x != null) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
return (true);
+ }
}
offset = last - 1;
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html
new file mode 100644
index 0000000..36d1d82
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Wire Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.wireadmin; version="[1.0,2.0)"
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java
new file mode 100644
index 0000000..06bd6f8
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.util.cdma;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionInfo;
+
+/**
+ * Class representing an ESN condition. Instances of this class contain a string
+ * value that is matched against the ESN of the device.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6439 $
+ */
+public class ESNCondition {
+ private static final String ORG_OSGI_UTIL_CDMA_ESN = "org.osgi.util.cdma.esn";
+ private static final String ESN;
+ private static final int ESN_LENGTH = 8;
+
+ static {
+ ESN = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String esn = System.getProperty(ORG_OSGI_UTIL_CDMA_ESN);
+ if (esn == null) {
+ return null;
+ }
+ return esn.toUpperCase();
+ }
+ });
+ }
+
+ private ESNCondition() {
+ // prevent instances being constructed
+ }
+
+ /**
+ * Creates an ESNCondition object.
+ *
+ * @param bundle This parameter is ignored, as the ESN number is the
+ * property of the mobile device, and thus the same for all bundles.
+ * @param conditionInfo Contains the ESN value against which to match the
+ * device's ESN. Its {@link ConditionInfo#getArgs()} method should
+ * return a String array with one value, the ESN string. The ESN is 8
+ * hexadecimal digits (32 bits) without hyphens. Limited pattern
+ * matching is allowed: the string is 0 to 7 digits, followed by an
+ * asterisk(<code>*</code>).
+ * @return A Condition object that indicates whether the specified ESN
+ * number matches that of the device. If the number ends with an
+ * asterisk ( <code>*</code>), then the beginning of the ESN is
+ * compared to the pattern.
+ * @throws IllegalArgumentException If the ESN is not a string of 8
+ * hexadecimal digits, or 0 to 7 hexadecimal digits with an
+ * <code>*</code> at the end.
+ */
+ public static Condition getCondition(Bundle bundle,
+ ConditionInfo conditionInfo) {
+ String esn = conditionInfo.getArgs()[0].toUpperCase();
+ int length = esn.length();
+ if (length > ESN_LENGTH) {
+ throw new IllegalArgumentException("ESN too long: " + esn);
+ }
+ if (esn.endsWith("*")) {
+ length--;
+ esn = esn.substring(0, length);
+ }
+ else {
+ if (length < ESN_LENGTH) {
+ throw new IllegalArgumentException("ESN too short: " + esn);
+ }
+ }
+ for (int i = 0; i < length; i++) {
+ char c = esn.charAt(i);
+ if (('0' <= c) && (c <= '9')) {
+ continue;
+ }
+ if (('A' <= c) && (c <= 'F')) {
+ continue;
+ }
+ throw new IllegalArgumentException("not a valid ESN: " + esn);
+ }
+ if (ESN == null) {
+ System.err
+ .println("The OSGi implementation of org.osgi.util.cdma.ESNCondition needs the system property "
+ + ORG_OSGI_UTIL_CDMA_ESN + " set.");
+ return Condition.FALSE;
+ }
+ return ESN.startsWith(esn) ? Condition.TRUE : Condition.FALSE;
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java
new file mode 100644
index 0000000..f5331d0
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2009). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.util.cdma;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionInfo;
+
+/**
+ * Class representing an MEID condition. Instances of this class contain a
+ * string value that is matched against the MEID of the device.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6439 $
+ */
+public class MEIDCondition {
+ private static final String ORG_OSGI_UTIL_CDMA_MEID = "org.osgi.util.cdma.meid";
+ private static final String MEID;
+ private static final int MEID_LENGTH = 14;
+
+ static {
+ MEID = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String meid = System.getProperty(ORG_OSGI_UTIL_CDMA_MEID);
+ if (meid == null) {
+ return null;
+ }
+ return meid.toUpperCase();
+ }
+ });
+ }
+
+ private MEIDCondition() {
+ // prevent instances being constructed
+ }
+
+ /**
+ * Creates a MEIDCondition object.
+ *
+ * @param bundle This parameter is ignored, as the MEID number is the
+ * property of the mobile device, and thus the same for all bundles.
+ * @param conditionInfo Contains the MEID value against which to match the
+ * device's MEID. Its {@link ConditionInfo#getArgs()} method should
+ * return a String array with one value, the MEID string. The MEID is
+ * 14 hexadecimal digits (56 bits) without hyphens. Limited pattern
+ * matching is allowed: the string is 0 to 13 digits, followed by an
+ * asterisk(<code>*</code>).
+ * @return A Condition object that indicates whether the specified MEID
+ * number matches that of the device. If the number ends with an
+ * asterisk ( <code>*</code>), then the beginning of the MEID is
+ * compared to the pattern.
+ * @throws IllegalArgumentException If the MEID is not a string of 14
+ * hexadecimal digits, or 0 to 13 hexadecimal digits with an
+ * <code>*</code> at the end.
+ */
+ public static Condition getCondition(Bundle bundle,
+ ConditionInfo conditionInfo) {
+ String meid = conditionInfo.getArgs()[0].toUpperCase();
+ int length = meid.length();
+ if (length > MEID_LENGTH) {
+ throw new IllegalArgumentException("MEID too long: " + meid);
+ }
+ if (meid.endsWith("*")) {
+ length--;
+ meid = meid.substring(0, length);
+ }
+ else {
+ if (length < MEID_LENGTH) {
+ throw new IllegalArgumentException("MEID too short: " + meid);
+ }
+ }
+ for (int i = 0; i < length; i++) {
+ char c = meid.charAt(i);
+ if (('0' <= c) && (c <= '9')) {
+ continue;
+ }
+ if (('A' <= c) && (c <= 'F')) {
+ continue;
+ }
+ throw new IllegalArgumentException("not a valid MEID: " + meid);
+ }
+ if (MEID == null) {
+ System.err
+ .println("The OSGi implementation of org.osgi.util.cdma.MEIDCondition needs the system property "
+ + ORG_OSGI_UTIL_CDMA_MEID + " set.");
+ return Condition.FALSE;
+ }
+ return MEID.startsWith(meid) ? Condition.TRUE : Condition.FALSE;
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html
new file mode 100644
index 0000000..eaa0953
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>CDMA Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.cdma; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
index 958b55b..79761fa 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMEICondition.java,v 1.21 2007/02/19 21:32:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,59 +25,74 @@
/**
* Class representing an IMEI condition. Instances of this class contain a
* string value that is matched against the IMEI of the device.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6439 $
*/
public class IMEICondition {
- private static final String ORG_OSGI_UTIL_GSM_IMEI = "org.osgi.util.gsm.imei";
- private static final String imei ;
-
+ private static final String ORG_OSGI_UTIL_GSM_IMEI = "org.osgi.util.gsm.imei";
+ private static final String IMEI;
+ private static final int IMEI_LENGTH = 15;
+
static {
- imei = (String)
- AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
- }
- }
- );
+ IMEI = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
+ }
+ });
}
-
+
private IMEICondition() {
+ // prevent instances being constructed
}
/**
- * Creates an IMEICondition object.
+ * Creates an IMEI condition object.
*
- * @param bundle ignored, as the IMEI number is the property of the mobile device,
- * and thus the same for all bundles.
- * @param conditionInfo contains the IMEI value to match the device's IMEI against. Its
- * {@link ConditionInfo#getArgs()} method should return a String array with one value, the
- * IMEI string. The IMEI is 15 digits without hypens. Limited pattern matching is allowed,
- * then the string is 0 to 14 digits, followed by an asterisk(<code>*</code>).
- * @return An IMEICondition object, that can tell whether its IMEI number matches that of the device.
- * If the number contains an asterisk(<code>*</code>), then the beginning
- * of the imei is compared to the pattern.
- * @throws NullPointerException if one of the parameters is <code>null</code>.
- * @throws IllegalArgumentException if the IMEI is not a string of 15 digits, or
- * 0 to 14 digits with an <code>*</code> at the end.
+ * @param bundle This parameter is ignored, as the IMEI number is a property
+ * of the mobile device and thus is the same for all bundles.
+ * @param conditionInfo Contains the IMEI value against which to match the
+ * device's IMEI. Its {@link ConditionInfo#getArgs()} method should
+ * return a String array with one value: the IMEI string. The IMEI is
+ * 15 digits without hyphens. Limited pattern matching is allowed:
+ * the string is 0 to 14 digits, followed by an asterisk (
+ * <code>*</code>).
+ * @return A Condition object that indicates whether the specified IMEI
+ * number matches that of the device. If the number ends with an
+ * asterisk ( <code>*</code>), then the beginning of the IMEI is
+ * compared to the pattern.
+ * @throws IllegalArgumentException If the IMEI is not a string of 15
+ * digits, or 0 to 14 digits with an <code>*</code> at the end.
*/
- public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
- if (bundle==null) throw new NullPointerException("bundle");
+ public static Condition getCondition(Bundle bundle,
+ ConditionInfo conditionInfo) {
String imei = conditionInfo.getArgs()[0];
- if (imei.length()>15) throw new IllegalArgumentException("imei too long: "+imei);
+ int length = imei.length();
+ if (length > IMEI_LENGTH) {
+ throw new IllegalArgumentException("IMEI too long: " + imei);
+ }
if (imei.endsWith("*")) {
- imei = imei.substring(0,imei.length()-1);
- } else {
- if (imei.length()!=15) throw new IllegalArgumentException("not a valid imei: "+imei);
+ length--;
+ imei = imei.substring(0, length);
}
- for(int i=0;i<imei.length();i++) {
- int c = imei.charAt(i);
- if (c<'0'||c>'9') throw new IllegalArgumentException("not a valid imei: "+imei);
+ else {
+ if (length < IMEI_LENGTH) {
+ throw new IllegalArgumentException("IMEI too short: " + imei);
+ }
}
- if (IMEICondition.imei==null) {
- System.err.println("The OSGi Reference Implementation of org.osgi.util.gsm.IMEICondition ");
- System.err.println("needs the system property "+ORG_OSGI_UTIL_GSM_IMEI+" set.");
+ for (int i = 0; i < length; i++) {
+ char c = imei.charAt(i);
+ if (('0' <= c) && (c <= '9')) {
+ continue;
+ }
+ throw new IllegalArgumentException("not a valid IMEI: " + imei);
+ }
+ if (IMEI == null) {
+ System.err
+ .println("The OSGi implementation of org.osgi.util.gsm.IMEICondition needs the system property "
+ + ORG_OSGI_UTIL_GSM_IMEI + " set.");
return Condition.FALSE;
}
- return IMEICondition.imei.startsWith(imei)?Condition.TRUE:Condition.FALSE;
+ return IMEI.startsWith(imei) ? Condition.TRUE : Condition.FALSE;
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
index 740bda1..d772d7a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMSICondition.java,v 1.23 2007/02/19 21:32:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,58 +25,74 @@
/**
* Class representing an IMSI condition. Instances of this class contain a
* string value that is matched against the IMSI of the subscriber.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6439 $
*/
public class IMSICondition {
- private static final String ORG_OSGI_UTIL_GSM_IMSI = "org.osgi.util.gsm.imsi";
- private static final String imsi;
-
+ private static final String ORG_OSGI_UTIL_GSM_IMSI = "org.osgi.util.gsm.imsi";
+ private static final String IMSI;
+ private static final int IMSI_LENGTH = 15;
+
static {
- imsi = (String)
- AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
- }
- }
- );
+ IMSI = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
+ }
+ });
}
- private IMSICondition() {}
+ private IMSICondition() {
+ // prevent instances being constructed
+ }
/**
* Creates an IMSI condition object.
*
- * @param bundle ignored, as the IMSI number is the same for all bundles.
- * @param conditionInfo contains the IMSI value to match the device's IMSI against. Its
- * {@link ConditionInfo#getArgs()} method should return a String array with one value, the
- * IMSI string. The IMSI is 15 digits without hypens. Limited pattern matching is allowed,
- * then the string is 0 to 14 digits, followed by an asterisk(<code>*</code>).
- * @return An IMSICondition object, that can tell whether its IMSI number matches that of the device.
- * If the number contains an asterisk(<code>*</code>), then the beginning
- * of the IMSI is compared to the pattern.
- * @throws NullPointerException if one of the parameters is <code>null</code>.
- * @throws IllegalArgumentException if the IMSI is not a string of 15 digits, or
- * 0 to 14 digits with an <code>*</code> at the end.
+ * @param bundle This parameter is ignored, as the IMSI number is a property
+ * of the mobile subscriber and thus is the same for all bundles.
+ * @param conditionInfo Contains the IMSI value against which to match the
+ * subscriber's IMSI. Its {@link ConditionInfo#getArgs()} method
+ * should return a String array with one value: the IMSI string. The
+ * IMSI is 15 digits without hyphens. Limited pattern matching is
+ * allowed: the string is 0 to 14 digits, followed by an asterisk (
+ * <code>*</code>).
+ * @return A Condition object that indicates whether the specified IMSI
+ * number matches that of the subscriber. If the number ends with an
+ * asterisk (<code>*</code>), then the beginning of the IMSI is
+ * compared to the pattern.
+ * @throws IllegalArgumentException If the IMSI is not a string of 15
+ * digits, or 0 to 14 digits with an <code>*</code> at the end.
*/
- public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
- if (bundle==null) throw new NullPointerException("bundle");
- if (conditionInfo==null) throw new NullPointerException("conditionInfo");
+ public static Condition getCondition(Bundle bundle,
+ ConditionInfo conditionInfo) {
String imsi = conditionInfo.getArgs()[0];
- if (imsi.length()>15) throw new IllegalArgumentException("imsi too long: "+imsi);
+ int length = imsi.length();
+ if (length > IMSI_LENGTH) {
+ throw new IllegalArgumentException("IMSI too long: " + imsi);
+ }
if (imsi.endsWith("*")) {
- imsi = imsi.substring(0,imsi.length()-1);
- } else {
- if (imsi.length()!=15) throw new IllegalArgumentException("not a valid imei: "+imsi);
+ length--;
+ imsi = imsi.substring(0, length);
}
- for(int i=0;i<imsi.length();i++) {
- int c = imsi.charAt(i);
- if (c<'0'||c>'9') throw new IllegalArgumentException("not a valid imei: "+imsi);
+ else {
+ if (length < IMSI_LENGTH) {
+ throw new IllegalArgumentException("IMSI too short: " + imsi);
+ }
}
- if (IMSICondition.imsi==null) {
- System.err.println("The OSGi Reference Implementation of org.osgi.util.gsm.IMSICondition ");
- System.err.println("needs the system property "+ORG_OSGI_UTIL_GSM_IMSI+" set.");
+ for (int i = 0; i < length; i++) {
+ char c = imsi.charAt(i);
+ if (('0' <= c) && (c <= '9')) {
+ continue;
+ }
+ throw new IllegalArgumentException("not a valid IMSI: " + imsi);
+ }
+ if (IMSI == null) {
+ System.err
+ .println("The OSGi implementation of org.osgi.util.gsm.IMSICondition needs the system property "
+ + ORG_OSGI_UTIL_GSM_IMSI + " set.");
return Condition.FALSE;
}
- return (IMSICondition.imsi.startsWith(imsi))?Condition.TRUE:Condition.FALSE;
+ return IMSI.startsWith(imsi) ? Condition.TRUE : Condition.FALSE;
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html
new file mode 100644
index 0000000..2b6bd0e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Mobile GSM Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.gsm; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
index 0b6cc70..82779cc 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/Measurement.java,v 1.14 2006/07/11 00:54:06 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +15,6 @@
*/
package org.osgi.util.measurement;
-
/**
* Represents a value with an error, a unit and a time-stamp.
*
@@ -46,15 +43,16 @@
* Note: This class has a natural ordering that is inconsistent with equals. See
* {@link #compareTo}.
*
- * @version $Revision: 1.14 $
+ * @Immutable
+ * @version $Revision: 5715 $
*/
public class Measurement implements Comparable {
- /* package private so it can be accessed by Unit */
- final double value;
- final double error;
- final long time;
- final Unit unit;
- private transient String name;
+ private final double value;
+ private final double error;
+ private final long time;
+ private final Unit unit;
+ private transient volatile String name;
+ private transient volatile int hashCode;
/**
* Create a new <code>Measurement</code> object.
@@ -370,7 +368,8 @@
* object.
*/
public String toString() {
- if (name == null) {
+ String result = name;
+ if (result == null) {
StringBuffer sb = new StringBuffer();
sb.append(value);
if (error != 0.0d) {
@@ -382,9 +381,10 @@
sb.append(" ");
sb.append(u);
}
- name = sb.toString();
+ result = sb.toString();
+ name = result;
}
- return name;
+ return result;
}
/**
@@ -422,25 +422,20 @@
throw new ArithmeticException("Cannot compare " + this + " and "
+ that);
}
- if (value == that.value) {
+ int result = Double.compare(value, that.value);
+ if (result == 0) {
return 0;
}
- if (value < that.value) {
- if ((value + error) >= (that.value - that.error)) {
+ if (result < 0) {
+ if (Double.compare(value + error, that.value - that.error) >= 0) {
return 0;
}
- else {
- return -1;
- }
+ return -1;
}
- else {
- if ((value - error) <= (that.value + that.error)) {
- return 0;
- }
- else {
- return 1;
- }
+ if (Double.compare(value - error, that.value + that.error) <= 0) {
+ return 0;
}
+ return 1;
}
/**
@@ -449,8 +444,16 @@
* @return A hash code value for this object.
*/
public int hashCode() {
- long bits = Double.doubleToLongBits(value + error);
- return ((int) (bits ^ (bits >>> 32))) ^ unit.hashCode();
+ int h = hashCode;
+ if (h == 0) {
+ long bits = Double.doubleToLongBits(value);
+ h = 31 * 17 + ((int) (bits ^ (bits >>> 32)));
+ bits = Double.doubleToLongBits(error);
+ h = 31 * h + ((int) (bits ^ (bits >>> 32)));
+ h = 31 * h + unit.hashCode();
+ hashCode = h;
+ }
+ return h;
}
/**
@@ -474,7 +477,8 @@
return false;
}
Measurement that = (Measurement) obj;
- return (value == that.value) && (error == that.error)
+ return (Double.compare(value, that.value) == 0)
+ && (Double.compare(error, that.error) == 0)
&& unit.equals(that.unit);
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java
index 77ce395..7fcc469 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/State.java,v 1.8 2006/06/16 16:31:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,12 +25,13 @@
* <p>
* A <code>State</code> object is immutable so that it may be easily shared.
*
- * @version $Revision: 1.8 $
+ * @Immutable
+ * @version $Revision: 5715 $
*/
public class State {
- final int value;
- final long time;
- final String name;
+ private final int value;
+ private final long time;
+ private final String name;
/**
* Create a new <code>State</code> object.
@@ -108,9 +107,9 @@
* @return A hash code value for this object.
*/
public int hashCode() {
- int hash = value;
+ int hash = 31 * 17 + value;
if (name != null) {
- hash ^= name.hashCode();
+ hash = 31 * hash + name.hashCode();
}
return hash;
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java
index e53bb25..5bea0c1 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/Unit.java,v 1.15 2006/06/16 16:31:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +28,8 @@
* +63. Any operation which produces an exponent outside of this range will
* result in a <code>Unit</code> object with undefined exponents.
*
- * @version $Revision: 1.15 $
+ * @Immutable
+ * @version $Revision: 5715 $
*/
/*
* This local class maintains the information about units. It can calculate new
@@ -279,9 +278,11 @@
private final static Unit[] allUnits = new Unit[] {m, s, kg, K, A, mol,
cd, rad, m_s, m_s2, m2, m3, Hz, N, Pa, J, W, C, V, F, Ohm, S, Wb,
T, lx, Gy, kat, unity };
+
+ /* @GuardedBy("this") */
private static Hashtable base;
- private String name;
- private long type;
+ private final String name;
+ private final long type;
/**
* Creates a new <code>Unit</code> instance.
@@ -290,6 +291,9 @@
* @param type the type of the <code>Unit</code>
*/
private Unit(String name, long type) {
+ if (name == null) {
+ name = computeName(type);
+ }
this.name = name;
this.type = type;
//System.out.println( name + " " + Long.toHexString( type ) );
@@ -338,7 +342,7 @@
* @return This object's hash code.
*/
public int hashCode() {
- return (int) ((type >>> 32) ^ type);
+ return 31 * 17 + (int) (type ^ (type >>> 32));
}
/**
@@ -435,16 +439,12 @@
*
* @return the <code>Unit</code>
*/
- static Unit find(long type) {
+ static synchronized Unit find(long type) {
if (base == null) {
- synchronized (Unit.class) {
- if (base == null) {
- int size = allUnits.length;
- base = new Hashtable(size << 1);
- for (int i = 0; i < size; i++) {
- base.put(allUnits[i], allUnits[i]);
- }
- }
+ int size = allUnits.length;
+ base = new Hashtable(size << 1);
+ for (int i = 0; i < size; i++) {
+ base.put(allUnits[i], allUnits[i]);
}
}
Unit unit = new Unit(null, type);
@@ -462,43 +462,39 @@
* @return A <code>String</code> object representing the <code>Unit</code>
*/
public String toString() {
- if (name == null) {
- int m = (int) (((type >> m_SHIFT) & MASK) - ZERO);
- int s = (int) (((type >> s_SHIFT) & MASK) - ZERO);
- int kg = (int) (((type >> kg_SHIFT) & MASK) - ZERO);
- int K = (int) (((type >> K_SHIFT) & MASK) - ZERO);
- int A = (int) (((type >> A_SHIFT) & MASK) - ZERO);
- int mol = (int) (((type >> mol_SHIFT) & MASK) - ZERO);
- int cd = (int) (((type >> cd_SHIFT) & MASK) - ZERO);
- int rad = (int) (((type >> rad_SHIFT) & MASK) - ZERO);
- StringBuffer numerator = new StringBuffer();
- StringBuffer denominator = new StringBuffer();
- addSIname(m, "m", numerator, denominator);
- addSIname(s, "s", numerator, denominator);
- addSIname(kg, "kg", numerator, denominator);
- addSIname(K, "K", numerator, denominator);
- addSIname(A, "A", numerator, denominator);
- addSIname(mol, "mol", numerator, denominator);
- addSIname(cd, "cd", numerator, denominator);
- addSIname(rad, "rad", numerator, denominator);
- if (denominator.length() > 0) {
- if (numerator.length() == 0) {
- numerator.append("1");
- }
- numerator.append("/");
- numerator.append((Object) denominator); /*
- * we use (Object) to
- * avoid using new 1.4
- * method
- * append(StringBuffer)
- */
- }
- name = numerator.toString();
- }
return name;
}
- private void addSIname(int si, String name, StringBuffer numerator,
+ private static String computeName(long type) {
+ int m = (int) (((type >> m_SHIFT) & MASK) - ZERO);
+ int s = (int) (((type >> s_SHIFT) & MASK) - ZERO);
+ int kg = (int) (((type >> kg_SHIFT) & MASK) - ZERO);
+ int K = (int) (((type >> K_SHIFT) & MASK) - ZERO);
+ int A = (int) (((type >> A_SHIFT) & MASK) - ZERO);
+ int mol = (int) (((type >> mol_SHIFT) & MASK) - ZERO);
+ int cd = (int) (((type >> cd_SHIFT) & MASK) - ZERO);
+ int rad = (int) (((type >> rad_SHIFT) & MASK) - ZERO);
+ StringBuffer numerator = new StringBuffer();
+ StringBuffer denominator = new StringBuffer();
+ addSIname(m, "m", numerator, denominator);
+ addSIname(s, "s", numerator, denominator);
+ addSIname(kg, "kg", numerator, denominator);
+ addSIname(K, "K", numerator, denominator);
+ addSIname(A, "A", numerator, denominator);
+ addSIname(mol, "mol", numerator, denominator);
+ addSIname(cd, "cd", numerator, denominator);
+ addSIname(rad, "rad", numerator, denominator);
+ if (denominator.length() > 0) {
+ if (numerator.length() == 0) {
+ numerator.append("1");
+ }
+ numerator.append("/");
+ numerator.append(denominator.toString());
+ }
+ return numerator.toString();
+ }
+
+ private static void addSIname(int si, String name, StringBuffer numerator,
StringBuffer denominator) {
if (si != 0) {
StringBuffer sb = (si > 0) ? numerator : denominator;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/package.html
new file mode 100644
index 0000000..2eb3a8c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Measurement Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.measurement; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
index 423ba1a..3b40080 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.mobile/src/org/osgi/util/mobile/UserPromptCondition.java,v 1.26 2006/07/10 08:18:30 pnagy Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/package.html
new file mode 100644
index 0000000..5590197
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Mobile Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.mobile; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java b/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java
index cf9e1ca..5fe3e0f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.position/src/org/osgi/util/position/Position.java,v 1.9 2006/07/12 21:21:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,16 +33,19 @@
* hashCode() because it is not clear how missing values should be handled. It
* is up to the user of a position to determine how best to compare two position
* objects. A <code>Position</code> object is immutable.
+ *
+ * @Immutable
+ * @version $Revision: 6860 $
*/
public class Position {
- private Measurement altitude;
- private Measurement longitude;
- private Measurement latitude;
- private Measurement speed;
- private Measurement track;
+ private final Measurement altitude;
+ private final Measurement longitude;
+ private final Measurement latitude;
+ private final Measurement speed;
+ private final Measurement track;
/**
- * Contructs a <code>Position</code> object with the given values.
+ * Constructs a <code>Position</code> object with the given values.
*
* @param lat a <code>Measurement</code> object specifying the latitude in
* radians, or null
@@ -63,33 +64,87 @@
if (!Unit.rad.equals(lat.getUnit())) {
throw new IllegalArgumentException("Invalid Latitude");
}
- this.latitude = lat;
}
if (lon != null) {
if (!Unit.rad.equals(lon.getUnit())) {
throw new IllegalArgumentException("Invalid Longitude");
}
- this.longitude = lon;
}
- normalizeLatLon();
if (alt != null) {
if (!Unit.m.equals(alt.getUnit())) {
throw new IllegalArgumentException("Invalid Altitude");
}
- this.altitude = alt;
}
if (speed != null) {
if (!Unit.m_s.equals(speed.getUnit())) {
throw new IllegalArgumentException("Invalid Speed");
}
- this.speed = speed;
}
if (track != null) {
if (!Unit.rad.equals(track.getUnit())) {
throw new IllegalArgumentException("Invalid Track");
}
- this.track = normalizeTrack(track);
}
+
+ /*
+ * Verify the longitude and latitude parameters so they fit the normal
+ * coordinate system. A latitude is between -90 (south) and +90 (north).
+ * A longitude is between -180 (Western hemisphere) and +180 (eastern
+ * hemisphere). This method first normalizes the latitude and longitude
+ * between +/- 180. If the |latitude| > 90, then the longitude is added
+ * 180 and the latitude is normalized to fit +/-90. (Example are with
+ * degrees though radians are used) <br> No normalization takes place
+ * when either lon or lat is null.
+ */
+ normalizeLatLon: {
+ if (lat == null || lon == null) {
+ break normalizeLatLon;
+ }
+ double dlat = lat.getValue();
+ double dlon = lon.getValue();
+ if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE
+ && dlat <= LAT_RANGE) {
+ break normalizeLatLon;
+ }
+ dlon = normalize(dlon, LON_RANGE);
+ dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree
+ // Check if we have to move to other side of the earth
+ if (dlat > LAT_RANGE || dlat < -LAT_RANGE) {
+ dlon = normalize(dlon - LON_RANGE, LON_RANGE);
+ dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE);
+ }
+ lon = new Measurement(dlon, lon.getError(), lon.getUnit(), lon
+ .getTime());
+ lat = new Measurement(dlat, lat.getError(), lat.getUnit(), lat
+ .getTime());
+ }
+
+ /*
+ * Normalize track to be a value such that: 0 <= value < +2PI. This
+ * corresponds to 0 deg to +360 deg. 0 is North, 0.5PI is East, PI is
+ * South, 1.5PI is West
+ */
+ normalizeTrack: {
+ if (track == null) {
+ break normalizeTrack;
+ }
+ double dtrack = track.getValue();
+ if ((0.0D <= dtrack) && (dtrack < TRACK_RANGE)) {
+ break normalizeTrack; /* value is already normalized */
+ }
+ dtrack %= TRACK_RANGE;
+ if (dtrack < 0.0D) {
+ dtrack += TRACK_RANGE;
+ }
+ track = new Measurement(dtrack, track.getError(), track.getUnit(),
+ track.getTime());
+ }
+
+ this.latitude = lat;
+ this.longitude = lon;
+ this.altitude = alt;
+ this.speed = speed;
+ this.track = track;
}
/**
@@ -153,37 +208,6 @@
private static final double LAT_RANGE = Math.PI / 2.0D;
/**
- * Verify the longitude and latitude parameters so they fit the normal
- * coordinate system. A latitude is between -90 (south) and +90 (north). A A
- * longitude is between -180 (Western hemisphere) and +180 (eastern
- * hemisphere). This method first normalizes the latitude and longitude
- * between +/- 180. If the |latitude| > 90, then the longitude is added 180
- * and the latitude is normalized to fit +/-90. (Example are with degrees
- * though radians are used) <br>
- * No normalization takes place when either lon or lat is null.
- */
- private void normalizeLatLon() {
- if (longitude == null || latitude == null)
- return;
- double dlon = longitude.getValue();
- double dlat = latitude.getValue();
- if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE
- && dlat <= LAT_RANGE)
- return;
- dlon = normalize(dlon, LON_RANGE);
- dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree
- // Check if we have to move to other side of the earth
- if (dlat > LAT_RANGE || dlat < -LAT_RANGE) {
- dlon = normalize(dlon - LON_RANGE, LON_RANGE);
- dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE);
- }
- longitude = new Measurement(dlon, longitude.getError(), longitude
- .getUnit(), longitude.getTime());
- latitude = new Measurement(dlat, latitude.getError(), latitude
- .getUnit(), latitude.getTime());
- }
-
- /**
* This function normalizes the a value according to a range. This is not
* simple modulo (as I thought when I started), but requires some special
* handling. For positive numbers we subtract 2*range from the number so
@@ -201,7 +225,7 @@
* @param value The value that needs adjusting
* @param range -range = < value < range
*/
- private double normalize(double value, double range) {
+ private static double normalize(double value, double range) {
double twiceRange = 2.0D * range;
while (value >= range) {
value -= twiceRange;
@@ -213,25 +237,4 @@
}
private static final double TRACK_RANGE = Math.PI * 2.0D;
-
- /**
- * Normalize track to be a value such that: 0 <= value < +2PI. This
- * corresponds to 0 deg to +360 deg. 0 is North 0.5*PI is East PI is South
- * 1.5*PI is West
- *
- * @param track Value to be normalized
- * @return Normalized value
- */
- private Measurement normalizeTrack(Measurement track) {
- double value = track.getValue();
- if ((0.0D <= value) && (value < TRACK_RANGE)) {
- return track; /* value is already normalized */
- }
- value %= TRACK_RANGE;
- if (value < 0.0D) {
- value += TRACK_RANGE;
- }
- return new Measurement(value, track.getError(), track.getUnit(), track
- .getTime());
- }
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/position/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/position/package.html
new file mode 100644
index 0000000..d0d745f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/position/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Position Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.position; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/position/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/position/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/position/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/AbstractTracked.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/AbstractTracked.java
new file mode 100644
index 0000000..681148f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/AbstractTracked.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract class to track items. If a Tracker is reused (closed then reopened),
+ * then a new AbstractTracked object is used. This class acts a map of tracked
+ * item -> customized object. Subclasses of this class will act as the listener
+ * object for the tracker. This class is used to synchronize access to the
+ * tracked items. This is not a public class. It is only for use by the
+ * implementation of the Tracker class.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5871 $
+ * @since 1.4
+ */
+abstract class AbstractTracked {
+ /* set this to true to compile in debug messages */
+ static final boolean DEBUG = false;
+
+ /**
+ * Map of tracked items to customized objects.
+ *
+ * @GuardedBy this
+ */
+ private final Map tracked;
+
+ /**
+ * Modification count. This field is initialized to zero and incremented by
+ * modified.
+ *
+ * @GuardedBy this
+ */
+ private int trackingCount;
+
+ /**
+ * List of items in the process of being added. This is used to deal with
+ * nesting of events. Since events may be synchronously delivered, events
+ * can be nested. For example, when processing the adding of a service and
+ * the customizer causes the service to be unregistered, notification to the
+ * nested call to untrack that the service was unregistered can be made to
+ * the track method.
+ *
+ * Since the ArrayList implementation is not synchronized, all access to
+ * this list must be protected by the same synchronized object for
+ * thread-safety.
+ *
+ * @GuardedBy this
+ */
+ private final List adding;
+
+ /**
+ * true if the tracked object is closed.
+ *
+ * This field is volatile because it is set by one thread and read by
+ * another.
+ */
+ volatile boolean closed;
+
+ /**
+ * Initial list of items for the tracker. This is used to correctly process
+ * the initial items which could be modified before they are tracked. This
+ * is necessary since the initial set of tracked items are not "announced"
+ * by events and therefore the event which makes the item untracked could be
+ * delivered before we track the item.
+ *
+ * An item must not be in both the initial and adding lists at the same
+ * time. An item must be moved from the initial list to the adding list
+ * "atomically" before we begin tracking it.
+ *
+ * Since the LinkedList implementation is not synchronized, all access to
+ * this list must be protected by the same synchronized object for
+ * thread-safety.
+ *
+ * @GuardedBy this
+ */
+ private final LinkedList initial;
+
+ /**
+ * AbstractTracked constructor.
+ */
+ AbstractTracked() {
+ tracked = new HashMap();
+ trackingCount = 0;
+ adding = new ArrayList(6);
+ initial = new LinkedList();
+ closed = false;
+ }
+
+ /**
+ * Set initial list of items into tracker before events begin to be
+ * received.
+ *
+ * This method must be called from Tracker's open method while synchronized
+ * on this object in the same synchronized block as the add listener call.
+ *
+ * @param list The initial list of items to be tracked. <code>null</code>
+ * entries in the list are ignored.
+ * @GuardedBy this
+ */
+ void setInitial(Object[] list) {
+ if (list == null) {
+ return;
+ }
+ int size = list.length;
+ for (int i = 0; i < size; i++) {
+ Object item = list[i];
+ if (item == null) {
+ continue;
+ }
+ if (DEBUG) {
+ System.out.println("AbstractTracked.setInitial: " + item); //$NON-NLS-1$
+ }
+ initial.add(item);
+ }
+ }
+
+ /**
+ * Track the initial list of items. This is called after events can begin to
+ * be received.
+ *
+ * This method must be called from Tracker's open method while not
+ * synchronized on this object after the add listener call.
+ *
+ */
+ void trackInitial() {
+ while (true) {
+ Object item;
+ synchronized (this) {
+ if (closed || (initial.size() == 0)) {
+ /*
+ * if there are no more initial items
+ */
+ return; /* we are done */
+ }
+ /*
+ * move the first item from the initial list to the adding list
+ * within this synchronized block.
+ */
+ item = initial.removeFirst();
+ if (tracked.get(item) != null) {
+ /* if we are already tracking this item */
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
+ }
+ continue; /* skip this item */
+ }
+ if (adding.contains(item)) {
+ /*
+ * if this item is already in the process of being added.
+ */
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
+ }
+ continue; /* skip this item */
+ }
+ adding.add(item);
+ }
+ if (DEBUG) {
+ System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
+ }
+ trackAdding(item, null); /*
+ * Begin tracking it. We call trackAdding
+ * since we have already put the item in the
+ * adding list.
+ */
+ }
+ }
+
+ /**
+ * Called by the owning Tracker object when it is closed.
+ */
+ void close() {
+ closed = true;
+ }
+
+ /**
+ * Begin to track an item.
+ *
+ * @param item Item to be tracked.
+ * @param related Action related object.
+ */
+ void track(final Object item, final Object related) {
+ final Object object;
+ synchronized (this) {
+ if (closed) {
+ return;
+ }
+ object = tracked.get(item);
+ if (object == null) { /* we are not tracking the item */
+ if (adding.contains(item)) {
+ /* if this item is already in the process of being added. */
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
+ }
+ return;
+ }
+ adding.add(item); /* mark this item is being added */
+ }
+ else { /* we are currently tracking this item */
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
+ }
+ modified(); /* increment modification count */
+ }
+ }
+
+ if (object == null) { /* we are not tracking the item */
+ trackAdding(item, related);
+ }
+ else {
+ /* Call customizer outside of synchronized region */
+ customizerModified(item, related, object);
+ /*
+ * If the customizer throws an unchecked exception, it is safe to
+ * let it propagate
+ */
+ }
+ }
+
+ /**
+ * Common logic to add an item to the tracker used by track and
+ * trackInitial. The specified item must have been placed in the adding list
+ * before calling this method.
+ *
+ * @param item Item to be tracked.
+ * @param related Action related object.
+ */
+ private void trackAdding(final Object item, final Object related) {
+ if (DEBUG) {
+ System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
+ }
+ Object object = null;
+ boolean becameUntracked = false;
+ /* Call customizer outside of synchronized region */
+ try {
+ object = customizerAdding(item, related);
+ /*
+ * If the customizer throws an unchecked exception, it will
+ * propagate after the finally
+ */
+ }
+ finally {
+ synchronized (this) {
+ if (adding.remove(item) && !closed) {
+ /*
+ * if the item was not untracked during the customizer
+ * callback
+ */
+ if (object != null) {
+ tracked.put(item, object);
+ modified(); /* increment modification count */
+ notifyAll(); /* notify any waiters */
+ }
+ }
+ else {
+ becameUntracked = true;
+ }
+ }
+ }
+ /*
+ * The item became untracked during the customizer callback.
+ */
+ if (becameUntracked && (object != null)) {
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
+ }
+ /* Call customizer outside of synchronized region */
+ customizerRemoved(item, related, object);
+ /*
+ * If the customizer throws an unchecked exception, it is safe to
+ * let it propagate
+ */
+ }
+ }
+
+ /**
+ * Discontinue tracking the item.
+ *
+ * @param item Item to be untracked.
+ * @param related Action related object.
+ */
+ void untrack(final Object item, final Object related) {
+ final Object object;
+ synchronized (this) {
+ if (initial.remove(item)) { /*
+ * if this item is already in the list
+ * of initial references to process
+ */
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
+ }
+ return; /*
+ * we have removed it from the list and it will not be
+ * processed
+ */
+ }
+
+ if (adding.remove(item)) { /*
+ * if the item is in the process of
+ * being added
+ */
+ if (DEBUG) {
+ System.out
+ .println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
+ }
+ return; /*
+ * in case the item is untracked while in the process of
+ * adding
+ */
+ }
+ object = tracked.remove(item); /*
+ * must remove from tracker before
+ * calling customizer callback
+ */
+ if (object == null) { /* are we actually tracking the item */
+ return;
+ }
+ modified(); /* increment modification count */
+ }
+ if (DEBUG) {
+ System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
+ }
+ /* Call customizer outside of synchronized region */
+ customizerRemoved(item, related, object);
+ /*
+ * If the customizer throws an unchecked exception, it is safe to let it
+ * propagate
+ */
+ }
+
+ /**
+ * Returns the number of tracked items.
+ *
+ * @return The number of tracked items.
+ *
+ * @GuardedBy this
+ */
+ int size() {
+ return tracked.size();
+ }
+
+ /**
+ * Return the customized object for the specified item
+ *
+ * @param item The item to lookup in the map
+ * @return The customized object for the specified item.
+ *
+ * @GuardedBy this
+ */
+ Object getCustomizedObject(final Object item) {
+ return tracked.get(item);
+ }
+
+ /**
+ * Return the list of tracked items.
+ *
+ * @param list An array to contain the tracked items.
+ * @return The specified list if it is large enough to hold the tracked
+ * items or a new array large enough to hold the tracked items.
+ * @GuardedBy this
+ */
+ Object[] getTracked(final Object[] list) {
+ return tracked.keySet().toArray(list);
+ }
+
+ /**
+ * Increment the modification count. If this method is overridden, the
+ * overriding method MUST call this method to increment the tracking count.
+ *
+ * @GuardedBy this
+ */
+ void modified() {
+ trackingCount++;
+ }
+
+ /**
+ * Returns the tracking count for this <code>ServiceTracker</code> object.
+ *
+ * The tracking count is initialized to 0 when this object is opened. Every
+ * time an item is added, modified or removed from this object the tracking
+ * count is incremented.
+ *
+ * @GuardedBy this
+ * @return The tracking count for this object.
+ */
+ int getTrackingCount() {
+ return trackingCount;
+ }
+
+ /**
+ * Call the specific customizer adding method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Item to be tracked.
+ * @param related Action related object.
+ * @return Customized object for the tracked item or <code>null</code> if
+ * the item is not to be tracked.
+ */
+ abstract Object customizerAdding(final Object item, final Object related);
+
+ /**
+ * Call the specific customizer modified method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ abstract void customizerModified(final Object item, final Object related,
+ final Object object);
+
+ /**
+ * Call the specific customizer removed method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ abstract void customizerRemoved(final Object item, final Object related,
+ final Object object);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTracker.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTracker.java
new file mode 100644
index 0000000..8791d98
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTracker.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * The <code>BundleTracker</code> class simplifies tracking bundles much like
+ * the <code>ServiceTracker</code> simplifies tracking services.
+ * <p>
+ * A <code>BundleTracker</code> is constructed with state criteria and a
+ * <code>BundleTrackerCustomizer</code> object. A <code>BundleTracker</code> can
+ * use the <code>BundleTrackerCustomizer</code> to select which bundles are
+ * tracked and to create a customized object to be tracked with the bundle. The
+ * <code>BundleTracker</code> can then be opened to begin tracking all bundles
+ * whose state matches the specified state criteria.
+ * <p>
+ * The <code>getBundles</code> method can be called to get the
+ * <code>Bundle</code> objects of the bundles being tracked. The
+ * <code>getObject</code> method can be called to get the customized object for
+ * a tracked bundle.
+ * <p>
+ * The <code>BundleTracker</code> class is thread-safe. It does not call a
+ * <code>BundleTrackerCustomizer</code> while holding any locks.
+ * <code>BundleTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5894 $
+ * @since 1.4
+ */
+public class BundleTracker implements BundleTrackerCustomizer {
+ /* set this to true to compile in debug messages */
+ static final boolean DEBUG = false;
+
+ /**
+ * The Bundle Context used by this <code>BundleTracker</code>.
+ */
+ protected final BundleContext context;
+
+ /**
+ * The <code>BundleTrackerCustomizer</code> object for this tracker.
+ */
+ final BundleTrackerCustomizer customizer;
+
+ /**
+ * Tracked bundles: <code>Bundle</code> object -> customized Object and
+ * <code>BundleListener</code> object
+ */
+ private volatile Tracked tracked;
+
+ /**
+ * Accessor method for the current Tracked object. This method is only
+ * intended to be used by the unsynchronized methods which do not modify the
+ * tracked field.
+ *
+ * @return The current Tracked object.
+ */
+ private Tracked tracked() {
+ return tracked;
+ }
+
+ /**
+ * State mask for bundles being tracked. This field contains the ORed values
+ * of the bundle states being tracked.
+ */
+ final int mask;
+
+ /**
+ * Create a <code>BundleTracker</code> for bundles whose state is present in
+ * the specified state mask.
+ *
+ * <p>
+ * Bundles whose state is present on the specified state mask will be
+ * tracked by this <code>BundleTracker</code>.
+ *
+ * @param context The <code>BundleContext</code> against which the tracking
+ * is done.
+ * @param stateMask The bit mask of the <code>OR</code>ing of the bundle
+ * states to be tracked.
+ * @param customizer The customizer object to call when bundles are added,
+ * modified, or removed in this <code>BundleTracker</code>. If
+ * customizer is <code>null</code>, then this
+ * <code>BundleTracker</code> will be used as the
+ * <code>BundleTrackerCustomizer</code> and this
+ * <code>BundleTracker</code> will call the
+ * <code>BundleTrackerCustomizer</code> methods on itself.
+ * @see Bundle#getState()
+ */
+ public BundleTracker(BundleContext context, int stateMask,
+ BundleTrackerCustomizer customizer) {
+ this.context = context;
+ this.mask = stateMask;
+ this.customizer = (customizer == null) ? this : customizer;
+ }
+
+ /**
+ * Open this <code>BundleTracker</code> and begin tracking bundles.
+ *
+ * <p>
+ * Bundle which match the state criteria specified when this
+ * <code>BundleTracker</code> was created are now tracked by this
+ * <code>BundleTracker</code>.
+ *
+ * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+ * with which this <code>BundleTracker</code> was created is no
+ * longer valid.
+ * @throws java.lang.SecurityException If the caller and this class do not
+ * have the appropriate
+ * <code>AdminPermission[context bundle,LISTENER]</code>, and the
+ * Java Runtime Environment supports permissions.
+ */
+ public void open() {
+ final Tracked t;
+ synchronized (this) {
+ if (tracked != null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("BundleTracker.open"); //$NON-NLS-1$
+ }
+ t = new Tracked();
+ synchronized (t) {
+ context.addBundleListener(t);
+ Bundle[] bundles = context.getBundles();
+ if (bundles != null) {
+ int length = bundles.length;
+ for (int i = 0; i < length; i++) {
+ int state = bundles[i].getState();
+ if ((state & mask) == 0) {
+ /* null out bundles whose states are not interesting */
+ bundles[i] = null;
+ }
+ }
+ /* set tracked with the initial bundles */
+ t.setInitial(bundles);
+ }
+ }
+ tracked = t;
+ }
+ /* Call tracked outside of synchronized region */
+ t.trackInitial(); /* process the initial references */
+ }
+
+ /**
+ * Close this <code>BundleTracker</code>.
+ *
+ * <p>
+ * This method should be called when this <code>BundleTracker</code> should
+ * end the tracking of bundles.
+ *
+ * <p>
+ * This implementation calls {@link #getBundles()} to get the list of
+ * tracked bundles to remove.
+ */
+ public void close() {
+ final Bundle[] bundles;
+ final Tracked outgoing;
+ synchronized (this) {
+ outgoing = tracked;
+ if (outgoing == null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("BundleTracker.close"); //$NON-NLS-1$
+ }
+ outgoing.close();
+ bundles = getBundles();
+ tracked = null;
+ try {
+ context.removeBundleListener(outgoing);
+ }
+ catch (IllegalStateException e) {
+ /* In case the context was stopped. */
+ }
+ }
+ if (bundles != null) {
+ for (int i = 0; i < bundles.length; i++) {
+ outgoing.untrack(bundles[i], null);
+ }
+ }
+ }
+
+ /**
+ * Default implementation of the
+ * <code>BundleTrackerCustomizer.addingBundle</code> method.
+ *
+ * <p>
+ * This method is only called when this <code>BundleTracker</code> has been
+ * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+ *
+ * <p>
+ * This implementation simply returns the specified <code>Bundle</code>.
+ *
+ * <p>
+ * This method can be overridden in a subclass to customize the object to be
+ * tracked for the bundle being added.
+ *
+ * @param bundle The <code>Bundle</code> being added to this
+ * <code>BundleTracker</code> object.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @return The specified bundle.
+ * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
+ */
+ public Object addingBundle(Bundle bundle, BundleEvent event) {
+ return bundle;
+ }
+
+ /**
+ * Default implementation of the
+ * <code>BundleTrackerCustomizer.modifiedBundle</code> method.
+ *
+ * <p>
+ * This method is only called when this <code>BundleTracker</code> has been
+ * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+ *
+ * <p>
+ * This implementation does nothing.
+ *
+ * @param bundle The <code>Bundle</code> whose state has been modified.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @param object The customized object for the specified Bundle.
+ * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
+ */
+ public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+ /* do nothing */
+ }
+
+ /**
+ * Default implementation of the
+ * <code>BundleTrackerCustomizer.removedBundle</code> method.
+ *
+ * <p>
+ * This method is only called when this <code>BundleTracker</code> has been
+ * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+ *
+ * <p>
+ * This implementation does nothing.
+ *
+ * @param bundle The <code>Bundle</code> being removed.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @param object The customized object for the specified bundle.
+ * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
+ */
+ public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+ /* do nothing */
+ }
+
+ /**
+ * Return an array of <code>Bundle</code>s for all bundles being tracked by
+ * this <code>BundleTracker</code>.
+ *
+ * @return An array of <code>Bundle</code>s or <code>null</code> if no
+ * bundles are being tracked.
+ */
+ public Bundle[] getBundles() {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return null;
+ }
+ synchronized (t) {
+ int length = t.size();
+ if (length == 0) {
+ return null;
+ }
+ return (Bundle[]) t.getTracked(new Bundle[length]);
+ }
+ }
+
+ /**
+ * Returns the customized object for the specified <code>Bundle</code> if
+ * the specified bundle is being tracked by this <code>BundleTracker</code>.
+ *
+ * @param bundle The <code>Bundle</code> being tracked.
+ * @return The customized object for the specified <code>Bundle</code> or
+ * <code>null</code> if the specified <code>Bundle</code> is not
+ * being tracked.
+ */
+ public Object getObject(Bundle bundle) {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return null;
+ }
+ synchronized (t) {
+ return t.getCustomizedObject(bundle);
+ }
+ }
+
+ /**
+ * Remove a bundle from this <code>BundleTracker</code>.
+ *
+ * The specified bundle will be removed from this <code>BundleTracker</code>
+ * . If the specified bundle was being tracked then the
+ * <code>BundleTrackerCustomizer.removedBundle</code> method will be called
+ * for that bundle.
+ *
+ * @param bundle The <code>Bundle</code> to be removed.
+ */
+ public void remove(Bundle bundle) {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return;
+ }
+ t.untrack(bundle, null);
+ }
+
+ /**
+ * Return the number of bundles being tracked by this
+ * <code>BundleTracker</code>.
+ *
+ * @return The number of bundles being tracked.
+ */
+ public int size() {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return 0;
+ }
+ synchronized (t) {
+ return t.size();
+ }
+ }
+
+ /**
+ * Returns the tracking count for this <code>BundleTracker</code>.
+ *
+ * The tracking count is initialized to 0 when this
+ * <code>BundleTracker</code> is opened. Every time a bundle is added,
+ * modified or removed from this <code>BundleTracker</code> the tracking
+ * count is incremented.
+ *
+ * <p>
+ * The tracking count can be used to determine if this
+ * <code>BundleTracker</code> has added, modified or removed a bundle by
+ * comparing a tracking count value previously collected with the current
+ * tracking count value. If the value has not changed, then no bundle has
+ * been added, modified or removed from this <code>BundleTracker</code>
+ * since the previous tracking count was collected.
+ *
+ * @return The tracking count for this <code>BundleTracker</code> or -1 if
+ * this <code>BundleTracker</code> is not open.
+ */
+ public int getTrackingCount() {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return -1;
+ }
+ synchronized (t) {
+ return t.getTrackingCount();
+ }
+ }
+
+ /**
+ * Inner class which subclasses AbstractTracked. This class is the
+ * <code>SynchronousBundleListener</code> object for the tracker.
+ *
+ * @ThreadSafe
+ * @since 1.4
+ */
+ class Tracked extends AbstractTracked implements SynchronousBundleListener {
+ /**
+ * Tracked constructor.
+ */
+ Tracked() {
+ super();
+ }
+
+ /**
+ * <code>BundleListener</code> method for the <code>BundleTracker</code>
+ * class. This method must NOT be synchronized to avoid deadlock
+ * potential.
+ *
+ * @param event <code>BundleEvent</code> object from the framework.
+ */
+ public void bundleChanged(final BundleEvent event) {
+ /*
+ * Check if we had a delayed call (which could happen when we
+ * close).
+ */
+ if (closed) {
+ return;
+ }
+ final Bundle bundle = event.getBundle();
+ final int state = bundle.getState();
+ if (DEBUG) {
+ System.out
+ .println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if ((state & mask) != 0) {
+ track(bundle, event);
+ /*
+ * If the customizer throws an unchecked exception, it is safe
+ * to let it propagate
+ */
+ }
+ else {
+ untrack(bundle, event);
+ /*
+ * If the customizer throws an unchecked exception, it is safe
+ * to let it propagate
+ */
+ }
+ }
+
+ /**
+ * Call the specific customizer adding method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Item to be tracked.
+ * @param related Action related object.
+ * @return Customized object for the tracked item or <code>null</code>
+ * if the item is not to be tracked.
+ */
+ Object customizerAdding(final Object item,
+ final Object related) {
+ return customizer
+ .addingBundle((Bundle) item, (BundleEvent) related);
+ }
+
+ /**
+ * Call the specific customizer modified method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ void customizerModified(final Object item,
+ final Object related, final Object object) {
+ customizer.modifiedBundle((Bundle) item, (BundleEvent) related,
+ object);
+ }
+
+ /**
+ * Call the specific customizer removed method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ void customizerRemoved(final Object item,
+ final Object related, final Object object) {
+ customizer.removedBundle((Bundle) item, (BundleEvent) related,
+ object);
+ }
+ }
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
new file mode 100644
index 0000000..100c6b4
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+
+/**
+ * The <code>BundleTrackerCustomizer</code> interface allows a
+ * <code>BundleTracker</code> to customize the <code>Bundle</code>s that are
+ * tracked. A <code>BundleTrackerCustomizer</code> is called when a bundle is
+ * being added to a <code>BundleTracker</code>. The
+ * <code>BundleTrackerCustomizer</code> can then return an object for the
+ * tracked bundle. A <code>BundleTrackerCustomizer</code> is also called when a
+ * tracked bundle is modified or has been removed from a
+ * <code>BundleTracker</code>.
+ *
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * <code>BundleEvent</code> being received by a <code>BundleTracker</code>.
+ * Since <code>BundleEvent</code>s are received synchronously by the
+ * <code>BundleTracker</code>, it is highly recommended that implementations of
+ * these methods do not alter bundle states while being synchronized on any
+ * object.
+ *
+ * <p>
+ * The <code>BundleTracker</code> class is thread-safe. It does not call a
+ * <code>BundleTrackerCustomizer</code> while holding any locks.
+ * <code>BundleTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5874 $
+ * @since 1.4
+ */
+public interface BundleTrackerCustomizer {
+ /**
+ * A bundle is being added to the <code>BundleTracker</code>.
+ *
+ * <p>
+ * This method is called before a bundle which matched the search parameters
+ * of the <code>BundleTracker</code> is added to the
+ * <code>BundleTracker</code>. This method should return the object to be
+ * tracked for the specified <code>Bundle</code>. The returned object is
+ * stored in the <code>BundleTracker</code> and is available from the
+ * {@link BundleTracker#getObject(Bundle) getObject} method.
+ *
+ * @param bundle The <code>Bundle</code> being added to the
+ * <code>BundleTracker</code>.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @return The object to be tracked for the specified <code>Bundle</code>
+ * object or <code>null</code> if the specified <code>Bundle</code>
+ * object should not be tracked.
+ */
+ public Object addingBundle(Bundle bundle, BundleEvent event);
+
+ /**
+ * A bundle tracked by the <code>BundleTracker</code> has been modified.
+ *
+ * <p>
+ * This method is called when a bundle being tracked by the
+ * <code>BundleTracker</code> has had its state modified.
+ *
+ * @param bundle The <code>Bundle</code> whose state has been modified.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @param object The tracked object for the specified bundle.
+ */
+ public void modifiedBundle(Bundle bundle, BundleEvent event,
+ Object object);
+
+ /**
+ * A bundle tracked by the <code>BundleTracker</code> has been removed.
+ *
+ * <p>
+ * This method is called after a bundle is no longer being tracked by the
+ * <code>BundleTracker</code>.
+ *
+ * @param bundle The <code>Bundle</code> that has been removed.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event associated
+ * with the call to this method.
+ * @param object The tracked object for the specified bundle.
+ */
+ public void removedBundle(Bundle bundle, BundleEvent event,
+ Object object);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java
index c945088..b4e373b 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.29 2007/02/19 19:04:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,53 +16,61 @@
package org.osgi.util.tracker;
-import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
-import org.osgi.framework.*;
+import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
/**
* The <code>ServiceTracker</code> class simplifies using services from the
* Framework's service registry.
* <p>
- * A <code>ServiceTracker</code> object is constructed with search criteria
- * and a <code>ServiceTrackerCustomizer</code> object. A
- * <code>ServiceTracker</code> object can use the
- * <code>ServiceTrackerCustomizer</code> object to customize the service
- * objects to be tracked. The <code>ServiceTracker</code> object can then be
- * opened to begin tracking all services in the Framework's service registry
- * that match the specified search criteria. The <code>ServiceTracker</code>
- * object correctly handles all of the details of listening to
- * <code>ServiceEvent</code> objects and getting and ungetting services.
+ * A <code>ServiceTracker</code> object is constructed with search criteria and
+ * a <code>ServiceTrackerCustomizer</code> object. A <code>ServiceTracker</code>
+ * can use a <code>ServiceTrackerCustomizer</code> to customize the service
+ * objects to be tracked. The <code>ServiceTracker</code> can then be opened to
+ * begin tracking all services in the Framework's service registry that match
+ * the specified search criteria. The <code>ServiceTracker</code> correctly
+ * handles all of the details of listening to <code>ServiceEvent</code>s and
+ * getting and ungetting services.
* <p>
- * The <code>getServiceReferences</code> method can be called to get
- * references to the services being tracked. The <code>getService</code> and
- * <code>getServices</code> methods can be called to get the service objects
- * for the tracked service.
+ * The <code>getServiceReferences</code> method can be called to get references
+ * to the services being tracked. The <code>getService</code> and
+ * <code>getServices</code> methods can be called to get the service objects for
+ * the tracked service.
* <p>
* The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> object while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> while holding any locks.
* <code>ServiceTrackerCustomizer</code> implementations must also be
* thread-safe.
*
* @ThreadSafe
- * @version $Revision: 1.29 $
+ * @version $Revision: 6386 $
*/
public class ServiceTracker implements ServiceTrackerCustomizer {
/* set this to true to compile in debug messages */
static final boolean DEBUG = false;
/**
- * Bundle context against which this <code>ServiceTracker</code> object is
- * tracking.
+ * The Bundle Context used by this <code>ServiceTracker</code>.
*/
protected final BundleContext context;
/**
- * Filter specifying search criteria for the services to track.
+ * The Filter used by this <code>ServiceTracker</code> which specifies the
+ * search criteria for the services to track.
*
* @since 1.1
*/
protected final Filter filter;
/**
- * <code>ServiceTrackerCustomizer</code> object for this tracker.
+ * The <code>ServiceTrackerCustomizer</code> for this tracker.
*/
final ServiceTrackerCustomizer customizer;
/**
@@ -84,17 +90,22 @@
*/
private final ServiceReference trackReference;
/**
- * Tracked services: <code>ServiceReference</code> object -> customized
- * Object and <code>ServiceListener</code> object
+ * Tracked services: <code>ServiceReference</code> -> customized Object and
+ * <code>ServiceListener</code> object
*/
private volatile Tracked tracked;
+
/**
- * Modification count. This field is initialized to zero by open, set to -1
- * by close and incremented by modified.
+ * Accessor method for the current Tracked object. This method is only
+ * intended to be used by the unsynchronized methods which do not modify the
+ * tracked field.
*
- * This field is volatile since it is accessed by multiple threads.
+ * @return The current Tracked object.
*/
- private volatile int trackingCount = -1;
+ private Tracked tracked() {
+ return tracked;
+ }
+
/**
* Cached ServiceReference for getServiceReference.
*
@@ -109,126 +120,153 @@
private volatile Object cachedService;
/**
- * Create a <code>ServiceTracker</code> object on the specified
- * <code>ServiceReference</code> object.
+ * org.osgi.framework package version which introduced
+ * {@link ServiceEvent#MODIFIED_ENDMATCH}
+ */
+ private static final Version endMatchVersion = new Version(1, 5, 0);
+
+ /**
+ * Create a <code>ServiceTracker</code> on the specified
+ * <code>ServiceReference</code>.
*
* <p>
* The service referenced by the specified <code>ServiceReference</code>
- * object will be tracked by this <code>ServiceTracker</code> object.
+ * will be tracked by this <code>ServiceTracker</code>.
*
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param reference <code>ServiceReference</code> object for the service
- * to be tracked.
+ * @param context The <code>BundleContext</code> against which the tracking
+ * is done.
+ * @param reference The <code>ServiceReference</code> for the service to be
+ * tracked.
* @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> object will be used as the
- * <code>ServiceTrackerCustomizer</code> object and the
- * <code>ServiceTracker</code> object will call the
+ * modified, or removed in this <code>ServiceTracker</code>. If
+ * customizer is <code>null</code>, then this
+ * <code>ServiceTracker</code> will be used as the
+ * <code>ServiceTrackerCustomizer</code> and this
+ * <code>ServiceTracker</code> will call the
* <code>ServiceTrackerCustomizer</code> methods on itself.
*/
- public ServiceTracker(BundleContext context, ServiceReference reference,
- ServiceTrackerCustomizer customizer) {
+ public ServiceTracker(final BundleContext context,
+ final ServiceReference reference,
+ final ServiceTrackerCustomizer customizer) {
this.context = context;
this.trackReference = reference;
this.trackClass = null;
this.customizer = (customizer == null) ? this : customizer;
- this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ this.listenerFilter = "(" + Constants.SERVICE_ID + "="
+ + reference.getProperty(Constants.SERVICE_ID).toString() + ")";
try {
this.filter = context.createFilter(listenerFilter);
}
- catch (InvalidSyntaxException e) { // we could only get this exception
- // if the ServiceReference was
- // invalid
- throw new IllegalArgumentException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+ catch (InvalidSyntaxException e) {
+ /*
+ * we could only get this exception if the ServiceReference was
+ * invalid
+ */
+ IllegalArgumentException iae = new IllegalArgumentException(
+ "unexpected InvalidSyntaxException: " + e.getMessage());
+ iae.initCause(e);
+ throw iae;
}
}
/**
- * Create a <code>ServiceTracker</code> object on the specified class
- * name.
+ * Create a <code>ServiceTracker</code> on the specified class name.
*
* <p>
* Services registered under the specified class name will be tracked by
- * this <code>ServiceTracker</code> object.
+ * this <code>ServiceTracker</code>.
*
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param clazz Class name of the services to be tracked.
+ * @param context The <code>BundleContext</code> against which the tracking
+ * is done.
+ * @param clazz The class name of the services to be tracked.
* @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> object will be used as the
- * <code>ServiceTrackerCustomizer</code> object and the
- * <code>ServiceTracker</code> object will call the
+ * modified, or removed in this <code>ServiceTracker</code>. If
+ * customizer is <code>null</code>, then this
+ * <code>ServiceTracker</code> will be used as the
+ * <code>ServiceTrackerCustomizer</code> and this
+ * <code>ServiceTracker</code> will call the
* <code>ServiceTrackerCustomizer</code> methods on itself.
*/
- public ServiceTracker(BundleContext context, String clazz,
- ServiceTrackerCustomizer customizer) {
+ public ServiceTracker(final BundleContext context, final String clazz,
+ final ServiceTrackerCustomizer customizer) {
this.context = context;
this.trackReference = null;
this.trackClass = clazz;
this.customizer = (customizer == null) ? this : customizer;
- this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ // we call clazz.toString to verify clazz is non-null!
+ this.listenerFilter = "(" + Constants.OBJECTCLASS + "="
+ + clazz.toString() + ")";
try {
this.filter = context.createFilter(listenerFilter);
}
- catch (InvalidSyntaxException e) { // we could only get this exception
- // if the clazz argument was
- // malformed
- throw new IllegalArgumentException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+ catch (InvalidSyntaxException e) {
+ /*
+ * we could only get this exception if the clazz argument was
+ * malformed
+ */
+ IllegalArgumentException iae = new IllegalArgumentException(
+ "unexpected InvalidSyntaxException: " + e.getMessage());
+ iae.initCause(e);
+ throw iae;
}
}
/**
- * Create a <code>ServiceTracker</code> object on the specified
- * <code>Filter</code> object.
+ * Create a <code>ServiceTracker</code> on the specified <code>Filter</code>
+ * object.
*
* <p>
* Services which match the specified <code>Filter</code> object will be
- * tracked by this <code>ServiceTracker</code> object.
+ * tracked by this <code>ServiceTracker</code>.
*
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param filter <code>Filter</code> object to select the services to be
+ * @param context The <code>BundleContext</code> against which the tracking
+ * is done.
+ * @param filter The <code>Filter</code> to select the services to be
* tracked.
* @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is null, then this <code>ServiceTracker</code>
- * object will be used as the <code>ServiceTrackerCustomizer</code>
- * object and the <code>ServiceTracker</code> object will call the
+ * modified, or removed in this <code>ServiceTracker</code>. If
+ * customizer is null, then this <code>ServiceTracker</code> will be
+ * used as the <code>ServiceTrackerCustomizer</code> and this
+ * <code>ServiceTracker</code> will call the
* <code>ServiceTrackerCustomizer</code> methods on itself.
* @since 1.1
*/
- public ServiceTracker(BundleContext context, Filter filter,
- ServiceTrackerCustomizer customizer) {
+ public ServiceTracker(final BundleContext context, final Filter filter,
+ final ServiceTrackerCustomizer customizer) {
this.context = context;
this.trackReference = null;
this.trackClass = null;
- this.listenerFilter = null;
+ final Version frameworkVersion = (Version) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String version = context
+ .getProperty(Constants.FRAMEWORK_VERSION);
+ return (version == null) ? Version.emptyVersion
+ : new Version(version);
+ }
+ });
+ final boolean endMatchSupported = (frameworkVersion
+ .compareTo(endMatchVersion) >= 0);
+ this.listenerFilter = endMatchSupported ? filter.toString() : null;
this.filter = filter;
this.customizer = (customizer == null) ? this : customizer;
- if ((context == null) || (filter == null)) { // we throw a NPE here
- // to
- // be consistent with the
- // other constructors
+ if ((context == null) || (filter == null)) {
+ /*
+ * we throw a NPE here to be consistent with the other constructors
+ */
throw new NullPointerException();
}
}
/**
- * Open this <code>ServiceTracker</code> object and begin tracking
- * services.
+ * Open this <code>ServiceTracker</code> and begin tracking services.
*
* <p>
- * This method calls <code>open(false)</code>.
+ * This implementation calls <code>open(false)</code>.
*
- * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
- * object with which this <code>ServiceTracker</code> object was
- * created is no longer valid.
+ * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+ * with which this <code>ServiceTracker</code> was created is no
+ * longer valid.
* @see #open(boolean)
*/
public void open() {
@@ -236,122 +274,140 @@
}
/**
- * Open this <code>ServiceTracker</code> object and begin tracking
- * services.
+ * Open this <code>ServiceTracker</code> and begin tracking services.
*
* <p>
* Services which match the search criteria specified when this
- * <code>ServiceTracker</code> object was created are now tracked by this
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code> was created are now tracked by this
+ * <code>ServiceTracker</code>.
*
* @param trackAllServices If <code>true</code>, then this
* <code>ServiceTracker</code> will track all matching services
* regardless of class loader accessibility. If <code>false</code>,
* then this <code>ServiceTracker</code> will only track matching
- * services which are class loader accessibile to the bundle whose
+ * services which are class loader accessible to the bundle whose
* <code>BundleContext</code> is used by this
* <code>ServiceTracker</code>.
- * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
- * object with which this <code>ServiceTracker</code> object was
- * created is no longer valid.
+ * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+ * with which this <code>ServiceTracker</code> was created is no
+ * longer valid.
* @since 1.3
*/
- public synchronized void open(boolean trackAllServices) {
- if (tracked != null) {
- return;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
- }
- tracked = trackAllServices ? new AllTracked() : new Tracked();
- trackingCount = 0;
- synchronized (tracked) {
- try {
- context.addServiceListener(tracked, listenerFilter);
- ServiceReference[] references;
- if (listenerFilter == null) { // user supplied filter
- references = getInitialReferences(trackAllServices, null,
- filter.toString());
- }
- else { // constructor supplied filter
- if (trackClass == null) {
- references = new ServiceReference[] {trackReference};
- }
- else {
+ public void open(boolean trackAllServices) {
+ final Tracked t;
+ synchronized (this) {
+ if (tracked != null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("ServiceTracker.open: " + filter);
+ }
+ t = trackAllServices ? new AllTracked() : new Tracked();
+ synchronized (t) {
+ try {
+ context.addServiceListener(t, listenerFilter);
+ ServiceReference[] references = null;
+ if (trackClass != null) {
references = getInitialReferences(trackAllServices,
trackClass, null);
}
+ else {
+ if (trackReference != null) {
+ if (trackReference.getBundle() != null) {
+ references = new ServiceReference[] {trackReference};
+ }
+ }
+ else { /* user supplied filter */
+ references = getInitialReferences(trackAllServices,
+ null,
+ (listenerFilter != null) ? listenerFilter
+ : filter.toString());
+ }
+ }
+ /* set tracked with the initial references */
+ t.setInitial(references);
}
-
- tracked.setInitialServices(references); // set tracked with
- // the initial
- // references
+ catch (InvalidSyntaxException e) {
+ throw new RuntimeException(
+ "unexpected InvalidSyntaxException: "
+ + e.getMessage(), e);
+ }
}
- catch (InvalidSyntaxException e) {
- throw new RuntimeException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
+ tracked = t;
}
/* Call tracked outside of synchronized region */
- tracked.trackInitialServices(); // process the initial references
+ t.trackInitial(); /* process the initial references */
}
/**
- * Returns the list of initial <code>ServiceReference</code> objects that
- * will be tracked by this <code>ServiceTracker</code> object.
+ * Returns the list of initial <code>ServiceReference</code>s that will be
+ * tracked by this <code>ServiceTracker</code>.
*
- * @param trackAllServices If true, use getAllServiceReferences.
- * @param trackClass the class name with which the service was registered,
- * or null for all services.
- * @param filterString the filter criteria or null for all services.
- * @return the list of initial <code>ServiceReference</code> objects.
- * @throws InvalidSyntaxException if the filter uses an invalid syntax.
+ * @param trackAllServices If <code>true</code>, use
+ * <code>getAllServiceReferences</code>.
+ * @param className The class name with which the service was registered, or
+ * <code>null</code> for all services.
+ * @param filterString The filter criteria or <code>null</code> for all
+ * services.
+ * @return The list of initial <code>ServiceReference</code>s.
+ * @throws InvalidSyntaxException If the specified filterString has an
+ * invalid syntax.
*/
private ServiceReference[] getInitialReferences(boolean trackAllServices,
- String trackClass, String filterString)
+ String className, String filterString)
throws InvalidSyntaxException {
if (trackAllServices) {
- return context.getAllServiceReferences(trackClass, filterString);
+ return context.getAllServiceReferences(className, filterString);
}
- else {
- return context.getServiceReferences(trackClass, filterString);
- }
+ return context.getServiceReferences(className, filterString);
}
/**
- * Close this <code>ServiceTracker</code> object.
+ * Close this <code>ServiceTracker</code>.
*
* <p>
- * This method should be called when this <code>ServiceTracker</code>
- * object should end the tracking of services.
+ * This method should be called when this <code>ServiceTracker</code> should
+ * end the tracking of services.
+ *
+ * <p>
+ * This implementation calls {@link #getServiceReferences()} to get the list
+ * of tracked services to remove.
*/
- public synchronized void close() {
- if (tracked == null) {
- return;
+ public void close() {
+ final Tracked outgoing;
+ final ServiceReference[] references;
+ synchronized (this) {
+ outgoing = tracked;
+ if (outgoing == null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("ServiceTracker.close: " + filter);
+ }
+ outgoing.close();
+ references = getServiceReferences();
+ tracked = null;
+ try {
+ context.removeServiceListener(outgoing);
+ }
+ catch (IllegalStateException e) {
+ /* In case the context was stopped. */
+ }
}
- if (DEBUG) {
- System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
- }
- tracked.close();
- ServiceReference[] references = getServiceReferences();
- Tracked outgoing = tracked;
- tracked = null;
- try {
- context.removeServiceListener(outgoing);
- }
- catch (IllegalStateException e) {
- /* In case the context was stopped. */
+ modified(); /* clear the cache */
+ synchronized (outgoing) {
+ outgoing.notifyAll(); /* wake up any waiters */
}
if (references != null) {
for (int i = 0; i < references.length; i++) {
- outgoing.untrack(references[i]);
+ outgoing.untrack(references[i], null);
}
}
- trackingCount = -1;
if (DEBUG) {
if ((cachedReference == null) && (cachedService == null)) {
System.out
- .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
+ .println("ServiceTracker.close[cached cleared]: "
+ + filter);
}
}
}
@@ -361,25 +417,26 @@
* <code>ServiceTrackerCustomizer.addingService</code> method.
*
* <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
+ * This method is only called when this <code>ServiceTracker</code> has been
+ * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
*
- * The default implementation returns the result of calling
- * <code>getService</code>, on the <code>BundleContext</code> object
- * with which this <code>ServiceTracker</code> object was created, passing
- * the specified <code>ServiceReference</code> object.
+ * <p>
+ * This implementation returns the result of calling <code>getService</code>
+ * on the <code>BundleContext</code> with which this
+ * <code>ServiceTracker</code> was created passing the specified
+ * <code>ServiceReference</code>.
* <p>
* This method can be overridden in a subclass to customize the service
* object to be tracked for the service being added. In that case, take care
- * not to rely on the default implementation of removedService that will
- * unget the service.
+ * not to rely on the default implementation of
+ * {@link #removedService(ServiceReference, Object) removedService} to unget
+ * the service.
*
- * @param reference Reference to service being added to this
- * <code>ServiceTracker</code> object.
+ * @param reference The reference to the service being added to this
+ * <code>ServiceTracker</code>.
* @return The service object to be tracked for the service added to this
- * <code>ServiceTracker</code> object.
- * @see ServiceTrackerCustomizer
+ * <code>ServiceTracker</code>.
+ * @see ServiceTrackerCustomizer#addingService(ServiceReference)
*/
public Object addingService(ServiceReference reference) {
return context.getService(reference);
@@ -390,17 +447,18 @@
* <code>ServiceTrackerCustomizer.modifiedService</code> method.
*
* <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
+ * This method is only called when this <code>ServiceTracker</code> has been
+ * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
*
- * The default implementation does nothing.
+ * <p>
+ * This implementation does nothing.
*
- * @param reference Reference to modified service.
+ * @param reference The reference to modified service.
* @param service The service object for the modified service.
- * @see ServiceTrackerCustomizer
+ * @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
*/
public void modifiedService(ServiceReference reference, Object service) {
+ /* do nothing */
}
/**
@@ -408,22 +466,21 @@
* <code>ServiceTrackerCustomizer.removedService</code> method.
*
* <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
+ * This method is only called when this <code>ServiceTracker</code> has been
+ * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
*
- * The default implementation calls <code>ungetService</code>, on the
- * <code>BundleContext</code> object with which this
- * <code>ServiceTracker</code> object was created, passing the specified
- * <code>ServiceReference</code> object.
+ * <p>
+ * This implementation calls <code>ungetService</code>, on the
+ * <code>BundleContext</code> with which this <code>ServiceTracker</code>
+ * was created, passing the specified <code>ServiceReference</code>.
* <p>
* This method can be overridden in a subclass. If the default
- * implementation of <code>addingService</code> method was used, this
- * method must unget the service.
+ * implementation of {@link #addingService(ServiceReference) addingService}
+ * method was used, this method must unget the service.
*
- * @param reference Reference to removed service.
+ * @param reference The reference to removed service.
* @param service The service object for the removed service.
- * @see ServiceTrackerCustomizer
+ * @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
*/
public void removedService(ServiceReference reference, Object service) {
context.ungetService(reference);
@@ -431,39 +488,42 @@
/**
* Wait for at least one service to be tracked by this
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code>. This method will also return when this
+ * <code>ServiceTracker</code> is closed.
+ *
* <p>
* It is strongly recommended that <code>waitForService</code> is not used
* during the calling of the <code>BundleActivator</code> methods.
- * <code>BundleActivator</code> methods are expected to complete in a
- * short period of time.
+ * <code>BundleActivator</code> methods are expected to complete in a short
+ * period of time.
*
- * @param timeout time interval in milliseconds to wait. If zero, the method
- * will wait indefinately.
- * @return Returns the result of <code>getService()</code>.
+ * <p>
+ * This implementation calls {@link #getService()} to determine if a service
+ * is being tracked.
+ *
+ * @param timeout The time interval in milliseconds to wait. If zero, the
+ * method will wait indefinitely.
+ * @return Returns the result of {@link #getService()}.
* @throws InterruptedException If another thread has interrupted the
* current thread.
* @throws IllegalArgumentException If the value of timeout is negative.
*/
public Object waitForService(long timeout) throws InterruptedException {
if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$
+ throw new IllegalArgumentException("timeout value is negative");
}
- Object object = getService();
+ Object object = getService();
while (object == null) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
return null;
}
- synchronized (tracked) {
- if (tracked.size() == 0) {
- tracked.wait(timeout);
+ synchronized (t) {
+ if (t.size() == 0) {
+ t.wait(timeout);
}
}
- object = getService();
+ object = getService();
if (timeout > 0) {
return object;
}
@@ -472,53 +532,45 @@
}
/**
- * Return an array of <code>ServiceReference</code> objects for all
- * services being tracked by this <code>ServiceTracker</code> object.
+ * Return an array of <code>ServiceReference</code>s for all services being
+ * tracked by this <code>ServiceTracker</code>.
*
- * @return Array of <code>ServiceReference</code> objects or
- * <code>null</code> if no service are being tracked.
+ * @return Array of <code>ServiceReference</code>s or <code>null</code> if
+ * no services are being tracked.
*/
public ServiceReference[] getServiceReferences() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
return null;
}
- synchronized (tracked) {
- int length = tracked.size();
+ synchronized (t) {
+ int length = t.size();
if (length == 0) {
return null;
}
- ServiceReference[] references = new ServiceReference[length];
- Enumeration keys = tracked.keys();
- for (int i = 0; i < length; i++) {
- references[i] = (ServiceReference) keys.nextElement();
- }
- return references;
+ return (ServiceReference[]) t
+ .getTracked(new ServiceReference[length]);
}
}
/**
- * Returns a <code>ServiceReference</code> object for one of the services
- * being tracked by this <code>ServiceTracker</code> object.
+ * Returns a <code>ServiceReference</code> for one of the services being
+ * tracked by this <code>ServiceTracker</code>.
*
* <p>
* If multiple services are being tracked, the service with the highest
* ranking (as specified in its <code>service.ranking</code> property) is
- * returned.
+ * returned. If there is a tie in ranking, the service with the lowest
+ * service ID (as specified in its <code>service.id</code> property); that
+ * is, the service that was registered first is returned. This is the same
+ * algorithm used by <code>BundleContext.getServiceReference</code>.
*
* <p>
- * If there is a tie in ranking, the service with the lowest service ID (as
- * specified in its <code>service.id</code> property); that is, the
- * service that was registered first is returned.
- * <p>
- * This is the same algorithm used by
- * <code>BundleContext.getServiceReference</code>.
+ * This implementation calls {@link #getServiceReferences()} to get the list
+ * of references for the tracked services.
*
- * @return <code>ServiceReference</code> object or <code>null</code> if
- * no service is being tracked.
+ * @return A <code>ServiceReference</code> or <code>null</code> if no
+ * services are being tracked.
* @since 1.1
*/
public ServiceReference getServiceReference() {
@@ -526,22 +578,21 @@
if (reference != null) {
if (DEBUG) {
System.out
- .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
+ .println("ServiceTracker.getServiceReference[cached]: "
+ + filter);
}
return reference;
}
if (DEBUG) {
- System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
+ System.out.println("ServiceTracker.getServiceReference: " + filter);
}
- ServiceReference[] references = getServiceReferences();
+ ServiceReference[] references = getServiceReferences();
int length = (references == null) ? 0 : references.length;
- if (length == 0) /* if no service is being tracked */
- {
+ if (length == 0) { /* if no service is being tracked */
return null;
}
int index = 0;
- if (length > 1) /* if more than one service, select highest ranking */
- {
+ if (length > 1) { /* if more than one service, select highest ranking */
int rankings[] = new int[length];
int count = 0;
int maxRanking = Integer.MIN_VALUE;
@@ -563,8 +614,7 @@
}
}
}
- if (count > 1) /* if still more than one service, select lowest id */
- {
+ if (count > 1) { /* if still more than one service, select lowest id */
long minId = Long.MAX_VALUE;
for (int i = 0; i < length; i++) {
if (rankings[i] == maxRanking) {
@@ -584,51 +634,51 @@
/**
* Returns the service object for the specified
- * <code>ServiceReference</code> object if the referenced service is being
- * tracked by this <code>ServiceTracker</code> object.
+ * <code>ServiceReference</code> if the specified referenced service is
+ * being tracked by this <code>ServiceTracker</code>.
*
- * @param reference Reference to the desired service.
- * @return Service object or <code>null</code> if the service referenced
- * by the specified <code>ServiceReference</code> object is not
- * being tracked.
+ * @param reference The reference to the desired service.
+ * @return A service object or <code>null</code> if the service referenced
+ * by the specified <code>ServiceReference</code> is not being
+ * tracked.
*/
public Object getService(ServiceReference reference) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
return null;
}
- synchronized (tracked) {
- return tracked.get(reference);
+ synchronized (t) {
+ return t.getCustomizedObject(reference);
}
}
/**
* Return an array of service objects for all services being tracked by this
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code>.
*
- * @return Array of service objects or <code>null</code> if no service are
- * being tracked.
+ * <p>
+ * This implementation calls {@link #getServiceReferences()} to get the list
+ * of references for the tracked services and then calls
+ * {@link #getService(ServiceReference)} for each reference to get the
+ * tracked service object.
+ *
+ * @return An array of service objects or <code>null</code> if no services
+ * are being tracked.
*/
public Object[] getServices() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
return null;
}
- synchronized (tracked) {
- ServiceReference[] references = getServiceReferences();
+ synchronized (t) {
+ ServiceReference[] references = getServiceReferences();
int length = (references == null) ? 0 : references.length;
if (length == 0) {
return null;
}
Object[] objects = new Object[length];
for (int i = 0; i < length; i++) {
- objects[i] = getService(references[i]);
+ objects[i] = getService(references[i]);
}
return objects;
}
@@ -636,13 +686,13 @@
/**
* Returns a service object for one of the services being tracked by this
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code>.
*
* <p>
- * If any services are being tracked, this method returns the result of
- * calling <code>getService(getServiceReference())</code>.
+ * If any services are being tracked, this implementation returns the result
+ * of calling <code>getService(getServiceReference())</code>.
*
- * @return Service object or <code>null</code> if no service is being
+ * @return A service object or <code>null</code> if no services are being
* tracked.
*/
public Object getService() {
@@ -650,258 +700,114 @@
if (service != null) {
if (DEBUG) {
System.out
- .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
+ .println("ServiceTracker.getService[cached]: "
+ + filter);
}
return service;
}
if (DEBUG) {
- System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
+ System.out.println("ServiceTracker.getService: " + filter);
}
- ServiceReference reference = getServiceReference();
+ ServiceReference reference = getServiceReference();
if (reference == null) {
return null;
}
- return cachedService = getService(reference);
+ return cachedService = getService(reference);
}
/**
- * Remove a service from this <code>ServiceTracker</code> object.
+ * Remove a service from this <code>ServiceTracker</code>.
*
* The specified service will be removed from this
- * <code>ServiceTracker</code> object. If the specified service was being
- * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
- * method will be called for that service.
+ * <code>ServiceTracker</code>. If the specified service was being tracked
+ * then the <code>ServiceTrackerCustomizer.removedService</code> method will
+ * be called for that service.
*
- * @param reference Reference to the service to be removed.
+ * @param reference The reference to the service to be removed.
*/
public void remove(ServiceReference reference) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
return;
}
- tracked.untrack(reference);
+ t.untrack(reference, null);
}
/**
* Return the number of services being tracked by this
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code>.
*
- * @return Number of services being tracked.
+ * @return The number of services being tracked.
*/
public int size() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
return 0;
}
- return tracked.size();
+ synchronized (t) {
+ return t.size();
+ }
}
/**
- * Returns the tracking count for this <code>ServiceTracker</code> object.
+ * Returns the tracking count for this <code>ServiceTracker</code>.
*
* The tracking count is initialized to 0 when this
- * <code>ServiceTracker</code> object is opened. Every time a service is
- * added, modified or removed from this <code>ServiceTracker</code> object
- * the tracking count is incremented.
+ * <code>ServiceTracker</code> is opened. Every time a service is added,
+ * modified or removed from this <code>ServiceTracker</code>, the tracking
+ * count is incremented.
*
* <p>
* The tracking count can be used to determine if this
- * <code>ServiceTracker</code> object has added, modified or removed a
- * service by comparing a tracking count value previously collected with the
- * current tracking count value. If the value has not changed, then no
- * service has been added, modified or removed from this
- * <code>ServiceTracker</code> object since the previous tracking count
- * was collected.
+ * <code>ServiceTracker</code> has added, modified or removed a service by
+ * comparing a tracking count value previously collected with the current
+ * tracking count value. If the value has not changed, then no service has
+ * been added, modified or removed from this <code>ServiceTracker</code>
+ * since the previous tracking count was collected.
*
* @since 1.2
- * @return The tracking count for this <code>ServiceTracker</code> object
- * or -1 if this <code>ServiceTracker</code> object is not open.
+ * @return The tracking count for this <code>ServiceTracker</code> or -1 if
+ * this <code>ServiceTracker</code> is not open.
*/
public int getTrackingCount() {
- return trackingCount;
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
+ return -1;
+ }
+ synchronized (t) {
+ return t.getTrackingCount();
+ }
}
/**
* Called by the Tracked object whenever the set of tracked services is
- * modified. Increments the tracking count and clears the cache.
- *
- * @GuardedBy tracked
+ * modified. Clears the cache.
*/
/*
* This method must not be synchronized since it is called by Tracked while
* Tracked is synchronized. We don't want synchronization interactions
- * between the ServiceListener thread and the user thread.
+ * between the listener thread and the user thread.
*/
void modified() {
- trackingCount++; /* increment modification count */
cachedReference = null; /* clear cached value */
cachedService = null; /* clear cached value */
if (DEBUG) {
- System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
+ System.out.println("ServiceTracker.modified: " + filter);
}
}
/**
- * Inner class to track services. If a <code>ServiceTracker</code> object
- * is reused (closed then reopened), then a new Tracked object is used. This
- * class is a hashtable mapping <code>ServiceReference</code> object ->
- * customized Object. This class is the <code>ServiceListener</code>
- * object for the tracker. This class is used to synchronize access to the
- * tracked services. This is not a public class. It is only for use by the
- * implementation of the <code>ServiceTracker</code> class.
+ * Inner class which subclasses AbstractTracked. This class is the
+ * <code>ServiceListener</code> object for the tracker.
*
* @ThreadSafe
*/
- class Tracked extends Hashtable implements ServiceListener {
- static final long serialVersionUID = -7420065199791006079L;
- /**
- * List of ServiceReferences in the process of being added. This is used
- * to deal with nesting of ServiceEvents. Since ServiceEvents are
- * synchronously delivered, ServiceEvents can be nested. For example,
- * when processing the adding of a service and the customizer causes the
- * service to be unregistered, notification to the nested call to
- * untrack that the service was unregistered can be made to the track
- * method.
- *
- * Since the ArrayList implementation is not synchronized, all access to
- * this list must be protected by the same synchronized object for
- * thread-safety.
- *
- * @GuardedBy this
- */
- private final ArrayList adding;
-
- /**
- * true if the tracked object is closed.
- *
- * This field is volatile because it is set by one thread and read by
- * another.
- */
- private volatile boolean closed;
-
- /**
- * Initial list of ServiceReferences for the tracker. This is used to
- * correctly process the initial services which could become
- * unregistered before they are tracked. This is necessary since the
- * initial set of tracked services are not "announced" by ServiceEvents
- * and therefore the ServiceEvent for unregistration could be delivered
- * before we track the service.
- *
- * A service must not be in both the initial and adding lists at the
- * same time. A service must be moved from the initial list to the
- * adding list "atomically" before we begin tracking it.
- *
- * Since the LinkedList implementation is not synchronized, all access
- * to this list must be protected by the same synchronized object for
- * thread-safety.
- *
- * @GuardedBy this
- */
- private final LinkedList initial;
-
+ class Tracked extends AbstractTracked implements ServiceListener {
/**
* Tracked constructor.
*/
- protected Tracked() {
+ Tracked() {
super();
- closed = false;
- adding = new ArrayList(6);
- initial = new LinkedList();
- }
-
- /**
- * Set initial list of services into tracker before ServiceEvents begin
- * to be received.
- *
- * This method must be called from ServiceTracker.open while
- * synchronized on this object in the same synchronized block as the
- * addServiceListener call.
- *
- * @param references The initial list of services to be tracked.
- * @GuardedBy this
- */
- protected void setInitialServices(ServiceReference[] references) {
- if (references == null) {
- return;
- }
- int size = references.length;
- for (int i = 0; i < size; i++) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
- }
- initial.add(references[i]);
- }
- }
-
- /**
- * Track the initial list of services. This is called after
- * ServiceEvents can begin to be received.
- *
- * This method must be called from ServiceTracker.open while not
- * synchronized on this object after the addServiceListener call.
- *
- */
- protected void trackInitialServices() {
- while (true) {
- ServiceReference reference;
- synchronized (this) {
- if (initial.size() == 0) {
- /*
- * if there are no more inital services
- */
- return; /* we are done */
- }
- /*
- * move the first service from the initial list to the
- * adding list within this synchronized block.
- */
- reference = (ServiceReference) initial.removeFirst();
- if (this.get(reference) != null) {
- /* if we are already tracking this service */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
- }
- continue; /* skip this service */
- }
- if (adding.contains(reference)) {
- /*
- * if this service is already in the process of being
- * added.
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
- }
- continue; /* skip this service */
- }
- adding.add(reference);
- }
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
- }
- trackAdding(reference); /*
- * Begin tracking it. We call
- * trackAdding since we have already put
- * the reference in the adding list.
- */
- }
- }
-
- /**
- * Called by the owning <code>ServiceTracker</code> object when it is
- * closed.
- */
- protected void close() {
- closed = true;
}
/**
@@ -911,7 +817,7 @@
*
* @param event <code>ServiceEvent</code> object from the framework.
*/
- public void serviceChanged(ServiceEvent event) {
+ public void serviceChanged(final ServiceEvent event) {
/*
* Check if we had a delayed call (which could happen when we
* close).
@@ -919,33 +825,34 @@
if (closed) {
return;
}
- ServiceReference reference = event.getServiceReference();
+ final ServiceReference reference = event.getServiceReference();
if (DEBUG) {
System.out
- .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
+ .println("ServiceTracker.Tracked.serviceChanged["
+ + event.getType() + "]: " + reference);
}
switch (event.getType()) {
case ServiceEvent.REGISTERED :
case ServiceEvent.MODIFIED :
- if (listenerFilter != null) { // constructor supplied
+ if (listenerFilter != null) { // service listener added with
// filter
- track(reference);
+ track(reference, event);
/*
* If the customizer throws an unchecked exception, it
* is safe to let it propagate
*/
}
- else { // user supplied filter
+ else { // service listener added without filter
if (filter.match(reference)) {
- track(reference);
+ track(reference, event);
/*
* If the customizer throws an unchecked exception,
* it is safe to let it propagate
*/
}
else {
- untrack(reference);
+ untrack(reference, event);
/*
* If the customizer throws an unchecked exception,
* it is safe to let it propagate
@@ -953,8 +860,9 @@
}
}
break;
+ case ServiceEvent.MODIFIED_ENDMATCH :
case ServiceEvent.UNREGISTERING :
- untrack(reference);
+ untrack(reference, event);
/*
* If the customizer throws an unchecked exception, it is
* safe to let it propagate
@@ -964,170 +872,54 @@
}
/**
- * Begin to track the referenced service.
+ * Increment the tracking count and tell the tracker there was a
+ * modification.
*
- * @param reference Reference to a service to be tracked.
+ * @GuardedBy this
*/
- private void track(ServiceReference reference) {
- Object object;
- synchronized (this) {
- object = this.get(reference);
- }
- if (object != null) /* we are already tracking the service */
- {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
- }
- synchronized (this) {
- modified(); /* increment modification count */
- }
- /* Call customizer outside of synchronized region */
- customizer.modifiedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe
- * to let it propagate
- */
- return;
- }
- synchronized (this) {
- if (adding.contains(reference)) { /*
- * if this service is
- * already in the process of
- * being added.
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
- }
- return;
- }
- adding.add(reference); /* mark this service is being added */
- }
-
- trackAdding(reference); /*
- * call trackAdding now that we have put the
- * reference in the adding list
- */
+ void modified() {
+ super.modified(); /* increment the modification count */
+ ServiceTracker.this.modified();
}
/**
- * Common logic to add a service to the tracker used by track and
- * trackInitialServices. The specified reference must have been placed
- * in the adding list before calling this method.
+ * Call the specific customizer adding method. This method must not be
+ * called while synchronized on this object.
*
- * @param reference Reference to a service to be tracked.
+ * @param item Item to be tracked.
+ * @param related Action related object.
+ * @return Customized object for the tracked item or <code>null</code>
+ * if the item is not to be tracked.
*/
- private void trackAdding(ServiceReference reference) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
- }
- Object object = null;
- boolean becameUntracked = false;
- /* Call customizer outside of synchronized region */
- try {
- object = customizer.addingService(reference);
- /*
- * If the customizer throws an unchecked exception, it will
- * propagate after the finally
- */
- }
- finally {
- synchronized (this) {
- if (adding.remove(reference)) { /*
- * if the service was not
- * untracked during the
- * customizer callback
- */
- if (object != null) {
- this.put(reference, object);
- modified(); /* increment modification count */
- notifyAll(); /*
- * notify any waiters in
- * waitForService
- */
- }
- }
- else {
- becameUntracked = true;
- }
- }
- }
- /*
- * The service became untracked during the customizer callback.
- */
- if (becameUntracked) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.removedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe
- * to let it propagate
- */
- }
+ Object customizerAdding(final Object item,
+ final Object related) {
+ return customizer.addingService((ServiceReference) item);
}
/**
- * Discontinue tracking the referenced service.
+ * Call the specific customizer modified method. This method must not be
+ * called while synchronized on this object.
*
- * @param reference Reference to the tracked service.
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
*/
- protected void untrack(ServiceReference reference) {
- Object object;
- synchronized (this) {
- if (initial.remove(reference)) { /*
- * if this service is
- * already in the list of
- * initial references to
- * process
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
- }
- return; /*
- * we have removed it from the list and it will not
- * be processed
- */
- }
+ void customizerModified(final Object item,
+ final Object related, final Object object) {
+ customizer.modifiedService((ServiceReference) item, object);
+ }
- if (adding.remove(reference)) { /*
- * if the service is in the
- * process of being added
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
- }
- return; /*
- * in case the service is untracked while in the
- * process of adding
- */
- }
- object = this.remove(reference); /*
- * must remove from tracker
- * before calling customizer
- * callback
- */
- if (object == null) { /* are we actually tracking the service */
- return;
- }
- modified(); /* increment modification count */
- }
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.removedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe to
- * let it propagate
- */
+ /**
+ * Call the specific customizer removed method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ void customizerRemoved(final Object item,
+ final Object related, final Object object) {
+ customizer.removedService((ServiceReference) item, object);
}
}
@@ -1139,12 +931,10 @@
* @ThreadSafe
*/
class AllTracked extends Tracked implements AllServiceListener {
- static final long serialVersionUID = 4050764875305137716L;
-
/**
* AllTracked constructor.
*/
- protected AllTracked() {
+ AllTracked() {
super();
}
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
index e091078..5c270e3 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java,v 1.13 2007/02/19 19:04:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,76 +20,75 @@
/**
* The <code>ServiceTrackerCustomizer</code> interface allows a
- * <code>ServiceTracker</code> object to customize the service objects that
- * are tracked. The <code>ServiceTrackerCustomizer</code> object is called
- * when a service is being added to the <code>ServiceTracker</code> object.
- * The <code>ServiceTrackerCustomizer</code> can then return an object for the
- * tracked service. The <code>ServiceTrackerCustomizer</code> object is also
- * called when a tracked service is modified or has been removed from the
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code> to customize the service objects that are
+ * tracked. A <code>ServiceTrackerCustomizer</code> is called when a service is
+ * being added to a <code>ServiceTracker</code>. The
+ * <code>ServiceTrackerCustomizer</code> can then return an object for the
+ * tracked service. A <code>ServiceTrackerCustomizer</code> is also called when
+ * a tracked service is modified or has been removed from a
+ * <code>ServiceTracker</code>.
*
* <p>
* The methods in this interface may be called as the result of a
- * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code>
- * object. Since <code>ServiceEvent</code> s are synchronously delivered by
- * the Framework, it is highly recommended that implementations of these methods
- * do not register (<code>BundleContext.registerService</code>), modify (
+ * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code>.
+ * Since <code>ServiceEvent</code>s are synchronously delivered by the
+ * Framework, it is highly recommended that implementations of these methods do
+ * not register (<code>BundleContext.registerService</code>), modify (
* <code>ServiceRegistration.setProperties</code>) or unregister (
* <code>ServiceRegistration.unregister</code>) a service while being
* synchronized on any object.
*
* <p>
* The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> object while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> while holding any locks.
* <code>ServiceTrackerCustomizer</code> implementations must also be
* thread-safe.
*
* @ThreadSafe
- * @version $Revision: 1.13 $
+ * @version $Revision: 5874 $
*/
public interface ServiceTrackerCustomizer {
/**
- * A service is being added to the <code>ServiceTracker</code> object.
+ * A service is being added to the <code>ServiceTracker</code>.
*
* <p>
* This method is called before a service which matched the search
- * parameters of the <code>ServiceTracker</code> object is added to it.
- * This method should return the service object to be tracked for this
- * <code>ServiceReference</code> object. The returned service object is
- * stored in the <code>ServiceTracker</code> object and is available from
- * the <code>getService</code> and <code>getServices</code> methods.
+ * parameters of the <code>ServiceTracker</code> is added to the
+ * <code>ServiceTracker</code>. This method should return the service object
+ * to be tracked for the specified <code>ServiceReference</code>. The
+ * returned service object is stored in the <code>ServiceTracker</code> and
+ * is available from the <code>getService</code> and
+ * <code>getServices</code> methods.
*
- * @param reference Reference to service being added to the
- * <code>ServiceTracker</code> object.
- * @return The service object to be tracked for the
- * <code>ServiceReference</code> object or <code>null</code> if
- * the <code>ServiceReference</code> object should not be tracked.
+ * @param reference The reference to the service being added to the
+ * <code>ServiceTracker</code>.
+ * @return The service object to be tracked for the specified referenced
+ * service or <code>null</code> if the specified referenced service
+ * should not be tracked.
*/
public Object addingService(ServiceReference reference);
/**
- * A service tracked by the <code>ServiceTracker</code> object has been
- * modified.
+ * A service tracked by the <code>ServiceTracker</code> has been modified.
*
* <p>
* This method is called when a service being tracked by the
- * <code>ServiceTracker</code> object has had it properties modified.
+ * <code>ServiceTracker</code> has had it properties modified.
*
- * @param reference Reference to service that has been modified.
- * @param service The service object for the modified service.
+ * @param reference The reference to the service that has been modified.
+ * @param service The service object for the specified referenced service.
*/
public void modifiedService(ServiceReference reference, Object service);
/**
- * A service tracked by the <code>ServiceTracker</code> object has been
- * removed.
+ * A service tracked by the <code>ServiceTracker</code> has been removed.
*
* <p>
* This method is called after a service is no longer being tracked by the
- * <code>ServiceTracker</code> object.
+ * <code>ServiceTracker</code>.
*
- * @param reference Reference to service that has been removed.
- * @param service The service object for the removed service.
+ * @param reference The reference to the service that has been removed.
+ * @param service The service object for the specified referenced service.
*/
public void removedService(ServiceReference reference, Object service);
}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/package.html
new file mode 100644
index 0000000..c29c891
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Tracker Package Version 1.4.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.tracker; version="[1.4,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/packageinfo
new file mode 100644
index 0000000..cc13f19
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/packageinfo
@@ -0,0 +1 @@
+version 1.4
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java b/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java
index c1e6cd8..963c092 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java
@@ -1,7 +1,5 @@
/*
- * $Header: /cvshome/build/org.osgi.util.xml/src/org/osgi/util/xml/XMLParserActivator.java,v 1.11 2006/10/27 18:17:06 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +16,28 @@
package org.osgi.util.xml;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
-import javax.xml.parsers.*;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.SAXParserFactory;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
/**
* A BundleActivator class that allows any JAXP compliant XML Parser to register
@@ -50,8 +63,8 @@
* An XMLParserActivator assumes that it can find the class file names of the
* factory classes in the following files:
* <ul>
- * <li><code>/META-INF/services/javax.xml.parsers.SAXParserFactory</code> is
- * a file contained in a jar available to the runtime which contains the
+ * <li><code>/META-INF/services/javax.xml.parsers.SAXParserFactory</code> is a
+ * file contained in a jar available to the runtime which contains the
* implementation class name(s) of the SAXParserFactory.
* <li><code>/META-INF/services/javax.xml.parsers.DocumentBuilderFactory</code>
* is a file contained in a jar available to the runtime which contains the
@@ -63,11 +76,11 @@
*
* <p>
* <code>XMLParserActivator</code> attempts to instantiate both the
- * <code>SAXParserFactory</code> and the <code>DocumentBuilderFactory</code>.
- * It registers each factory with the framework along with service properties:
+ * <code>SAXParserFactory</code> and the <code>DocumentBuilderFactory</code>. It
+ * registers each factory with the framework along with service properties:
* <ul>
- * <li>{@link #PARSER_VALIDATING}- indicates if this factory supports
- * validating parsers. It's value is a <code>Boolean</code>.
+ * <li>{@link #PARSER_VALIDATING}- indicates if this factory supports validating
+ * parsers. It's value is a <code>Boolean</code>.
* <li>{@link #PARSER_NAMESPACEAWARE}- indicates if this factory supports
* namespace aware parsers It's value is a <code>Boolean</code>.
* </ul>
@@ -76,48 +89,51 @@
* or attributes which could be used to select a parser with a filter. These can
* be added by extending this class and overriding the
* <code>setSAXProperties</code> and <code>setDOMProperties</code> methods.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5900 $
*/
public class XMLParserActivator implements BundleActivator, ServiceFactory {
/** Context of this bundle */
- private BundleContext context;
+ private volatile BundleContext context;
/**
* Filename containing the SAX Parser Factory Class name. Also used as the
* basis for the <code>SERVICE_PID<code> registration property.
*/
- public static final String SAXFACTORYNAME = "javax.xml.parsers.SAXParserFactory";
+ public static final String SAXFACTORYNAME = "javax.xml.parsers.SAXParserFactory";
/**
* Filename containing the DOM Parser Factory Class name. Also used as the
* basis for the <code>SERVICE_PID</code> registration property.
*/
- public static final String DOMFACTORYNAME = "javax.xml.parsers.DocumentBuilderFactory";
+ public static final String DOMFACTORYNAME = "javax.xml.parsers.DocumentBuilderFactory";
/** Path to the factory class name files */
- private static final String PARSERCLASSFILEPATH = "/META-INF/services/";
+ private static final String PARSERCLASSFILEPATH = "/META-INF/services/";
/** Fully qualified path name of SAX Parser Factory Class Name file */
- public static final String SAXCLASSFILE = PARSERCLASSFILEPATH
- + SAXFACTORYNAME;
+ public static final String SAXCLASSFILE = PARSERCLASSFILEPATH
+ + SAXFACTORYNAME;
/** Fully qualified path name of DOM Parser Factory Class Name file */
- public static final String DOMCLASSFILE = PARSERCLASSFILEPATH
- + DOMFACTORYNAME;
+ public static final String DOMCLASSFILE = PARSERCLASSFILEPATH
+ + DOMFACTORYNAME;
/** SAX Factory Service Description */
- private static final String SAXFACTORYDESCRIPTION = "A JAXP Compliant SAX Parser";
+ private static final String SAXFACTORYDESCRIPTION = "A JAXP Compliant SAX Parser";
/** DOM Factory Service Description */
- private static final String DOMFACTORYDESCRIPTION = "A JAXP Compliant DOM Parser";
+ private static final String DOMFACTORYDESCRIPTION = "A JAXP Compliant DOM Parser";
/**
* Service property specifying if factory is configured to support
* validating parsers. The value is of type <code>Boolean</code>.
*/
- public static final String PARSER_VALIDATING = "parser.validating";
+ public static final String PARSER_VALIDATING = "parser.validating";
/**
* Service property specifying if factory is configured to support namespace
* aware parsers. The value is of type <code>Boolean</code>.
*/
- public static final String PARSER_NAMESPACEAWARE = "parser.namespaceAware";
+ public static final String PARSER_NAMESPACEAWARE = "parser.namespaceAware";
/**
* Key for parser factory name property - this must be saved in the parsers
* properties hashtable so that the parser factory can be instantiated from
* a ServiceReference
*/
- private static final String FACTORYNAMEKEY = "parser.factoryname";
+ private static final String FACTORYNAMEKEY = "parser.factoryname";
/**
* Called when this bundle is started so the Framework can perform the
@@ -141,20 +157,12 @@
public void start(BundleContext context) throws Exception {
this.context = context;
Bundle parserBundle = context.getBundle();
- try {
- // check for sax parsers
- registerSAXParsers(getParserFactoryClassNames(parserBundle
- .getResource(SAXCLASSFILE)));
- // check for dom parsers
- registerDOMParsers(getParserFactoryClassNames(parserBundle
- .getResource(DOMCLASSFILE)));
- }
- catch (IOException ioe) {
- // if there were any IO errors accessing the resource files
- // containing the class names
- ioe.printStackTrace();
- throw new FactoryConfigurationError(ioe);
- }
+ // check for sax parsers
+ registerSAXParsers(getParserFactoryClassNames(parserBundle
+ .getResource(SAXCLASSFILE)));
+ // check for dom parsers
+ registerDOMParsers(getParserFactoryClassNames(parserBundle
+ .getResource(DOMCLASSFILE)));
}
/**
@@ -168,6 +176,7 @@
* bundle, and release all services used by the bundle.
*/
public void stop(BundleContext context) throws Exception {
+ // framework will automatically unregister the parser services
}
/**
@@ -177,77 +186,70 @@
*
* @param parserUrl The URL of the service file containing the parser class
* names
- * @return A vector of strings containing the parser class names or null if
- * parserUrl is null
+ * @return A List of strings containing the parser class names.
* @throws IOException if there is a problem reading the URL input stream
*/
- private Vector getParserFactoryClassNames(URL parserUrl) throws IOException {
- Vector v = new Vector(1);
- if (parserUrl != null) {
- String parserFactoryClassName = null;
- InputStream is = parserUrl.openStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
- while (true) {
- parserFactoryClassName = br.readLine();
- if (parserFactoryClassName == null) {
- break; // end of file reached
- }
- String pfcName = parserFactoryClassName.trim();
- if (pfcName.length() == 0) {
- continue; // blank line
- }
- int commentIdx = pfcName.indexOf("#");
- if (commentIdx == 0) { // comment line
- continue;
- }
- else
- if (commentIdx < 0) { // no comment on this line
- v.addElement(pfcName);
- }
- else {
- v.addElement(pfcName.substring(0, commentIdx).trim());
- }
+ private List getParserFactoryClassNames(URL parserUrl) throws IOException {
+ if (parserUrl == null) {
+ return Collections.EMPTY_LIST;
+ }
+ List v = new ArrayList(1);
+ String parserFactoryClassName = null;
+ InputStream is = parserUrl.openStream();
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ while (true) {
+ parserFactoryClassName = br.readLine();
+ if (parserFactoryClassName == null) {
+ break; // end of file reached
}
- return v;
+ String pfcName = parserFactoryClassName.trim();
+ if (pfcName.length() == 0) {
+ continue; // blank line
+ }
+ int commentIdx = pfcName.indexOf("#");
+ if (commentIdx == 0) { // comment line
+ continue;
+ }
+ else
+ if (commentIdx < 0) { // no comment on this line
+ v.add(pfcName);
+ }
+ else {
+ v.add(pfcName.substring(0, commentIdx).trim());
+ }
}
- else {
- return null;
- }
+ return v;
}
/**
* Register SAX Parser Factory Services with the framework.
*
- * @param parserFactoryClassNames - a <code>Vector</code> of
+ * @param parserFactoryClassNames - a <code>List</code> of
* <code>String</code> objects containing the names of the parser
* Factory Classes
* @throws FactoryConfigurationError if thrown from <code>getFactory</code>
*/
- private void registerSAXParsers(Vector parserFactoryClassNames)
+ private void registerSAXParsers(List parserFactoryClassNames)
throws FactoryConfigurationError {
- if (parserFactoryClassNames != null) {
- Enumeration e = parserFactoryClassNames.elements();
- int index = 0;
- while (e.hasMoreElements()) {
- String parserFactoryClassName = (String) e.nextElement();
- // create a sax parser factory just to get it's default
- // properties. It will never be used since
- // this class will operate as a service factory and give each
- // service requestor it's own SaxParserFactory
- SAXParserFactory factory = (SAXParserFactory) getFactory(parserFactoryClassName);
- Hashtable properties = new Hashtable(7);
- // figure out the default properties of the parser
- setDefaultSAXProperties(factory, properties, index);
- // store the parser factory class name in the properties so that
- // it can be retrieved when getService is called
- // to return a parser factory
- properties.put(FACTORYNAMEKEY, parserFactoryClassName);
- // release the factory
- factory = null;
- // register the factory as a service
- context.registerService(SAXFACTORYNAME, this, properties);
- index++;
- }
+ Iterator e = parserFactoryClassNames.iterator();
+ int index = 0;
+ while (e.hasNext()) {
+ String parserFactoryClassName = (String) e.next();
+ // create a sax parser factory just to get it's default
+ // properties. It will never be used since
+ // this class will operate as a service factory and give each
+ // service requestor it's own SaxParserFactory
+ SAXParserFactory factory = (SAXParserFactory) getFactory(parserFactoryClassName);
+ Hashtable properties = new Hashtable(7);
+ // figure out the default properties of the parser
+ setDefaultSAXProperties(factory, properties, index);
+ // store the parser factory class name in the properties so that
+ // it can be retrieved when getService is called
+ // to return a parser factory
+ properties.put(FACTORYNAMEKEY, parserFactoryClassName);
+ // register the factory as a service
+ context.registerService(SAXFACTORYNAME, this, properties);
+ index++;
}
}
@@ -280,10 +282,9 @@
* Set the customizable SAX Parser Service Properties.
*
* <p>
- * This method attempts to instantiate a validating parser and a
- * namespaceaware parser to determine if the parser can support those
- * features. The appropriate properties are then set in the specified
- * properties object.
+ * This method attempts to instantiate a validating parser and a namespace
+ * aware parser to determine if the parser can support those features. The
+ * appropriate properties are then set in the specified properties object.
*
* <p>
* This method can be overridden to add additional SAX2 features and
@@ -328,36 +329,32 @@
/**
* Register DOM Parser Factory Services with the framework.
*
- * @param parserFactoryClassNames - a <code>Vector</code> of
+ * @param parserFactoryClassNames - a <code>List</code> of
* <code>String</code> objects containing the names of the parser
* Factory Classes
* @throws FactoryConfigurationError if thrown from <code>getFactory</code>
*/
- private void registerDOMParsers(Vector parserFactoryClassNames)
+ private void registerDOMParsers(List parserFactoryClassNames)
throws FactoryConfigurationError {
- if (parserFactoryClassNames != null) {
- Enumeration e = parserFactoryClassNames.elements();
- int index = 0;
- while (e.hasMoreElements()) {
- String parserFactoryClassName = (String) e.nextElement();
- // create a dom parser factory just to get it's default
- // properties. It will never be used since
- // this class will operate as a service factory and give each
- // service requestor it's own DocumentBuilderFactory
- DocumentBuilderFactory factory = (DocumentBuilderFactory) getFactory(parserFactoryClassName);
- Hashtable properties = new Hashtable(7);
- // figure out the default properties of the parser
- setDefaultDOMProperties(factory, properties, index);
- // store the parser factory class name in the properties so that
- // it can be retrieved when getService is called
- // to return a parser factory
- properties.put(FACTORYNAMEKEY, parserFactoryClassName);
- // release the factory
- factory = null;
- // register the factory as a service
- context.registerService(DOMFACTORYNAME, this, properties);
- index++;
- }
+ Iterator e = parserFactoryClassNames.iterator();
+ int index = 0;
+ while (e.hasNext()) {
+ String parserFactoryClassName = (String) e.next();
+ // create a dom parser factory just to get it's default
+ // properties. It will never be used since
+ // this class will operate as a service factory and give each
+ // service requestor it's own DocumentBuilderFactory
+ DocumentBuilderFactory factory = (DocumentBuilderFactory) getFactory(parserFactoryClassName);
+ Hashtable properties = new Hashtable(7);
+ // figure out the default properties of the parser
+ setDefaultDOMProperties(factory, properties, index);
+ // store the parser factory class name in the properties so that
+ // it can be retrieved when getService is called
+ // to return a parser factory
+ properties.put(FACTORYNAMEKEY, parserFactoryClassName);
+ // register the factory as a service
+ context.registerService(DOMFACTORYNAME, this, properties);
+ index++;
}
}
@@ -388,10 +385,9 @@
* Set the customizable DOM Parser Service Properties.
*
* <p>
- * This method attempts to instantiate a validating parser and a
- * namespaceaware parser to determine if the parser can support those
- * features. The appropriate properties are then set in the specified props
- * object.
+ * This method attempts to instantiate a validating parser and a namespace
+ * aware parser to determine if the parser can support those features. The
+ * appropriate properties are then set in the specified props object.
*
* <p>
* This method can be overridden to add additional DOM2 features and
@@ -443,20 +439,16 @@
*/
private Object getFactory(String parserFactoryClassName)
throws FactoryConfigurationError {
- Exception e = null;
try {
- return Class.forName(parserFactoryClassName).newInstance();
+ return context.getBundle().loadClass(parserFactoryClassName)
+ .newInstance();
}
- catch (ClassNotFoundException cnfe) {
- e = cnfe;
+ catch (RuntimeException e) {
+ throw e;
}
- catch (InstantiationException ie) {
- e = ie;
+ catch (Exception e) {
+ throw new FactoryConfigurationError(e);
}
- catch (IllegalAccessException iae) {
- e = iae;
- }
- throw new FactoryConfigurationError(e);
}
/**
@@ -484,32 +476,26 @@
ServiceReference sref = registration.getReference();
String parserFactoryClassName = (String) sref
.getProperty(FACTORYNAMEKEY);
- try {
- // need to set factory properties
- Object factory = getFactory(parserFactoryClassName);
- if (factory instanceof SAXParserFactory) {
- ((SAXParserFactory) factory).setValidating(((Boolean) sref
- .getProperty(PARSER_VALIDATING)).booleanValue());
- ((SAXParserFactory) factory).setNamespaceAware(((Boolean) sref
- .getProperty(PARSER_NAMESPACEAWARE)).booleanValue());
+ // need to set factory properties
+ Object factory = getFactory(parserFactoryClassName);
+ if (factory instanceof SAXParserFactory) {
+ ((SAXParserFactory) factory).setValidating(((Boolean) sref
+ .getProperty(PARSER_VALIDATING)).booleanValue());
+ ((SAXParserFactory) factory).setNamespaceAware(((Boolean) sref
+ .getProperty(PARSER_NAMESPACEAWARE)).booleanValue());
+ }
+ else {
+ if (factory instanceof DocumentBuilderFactory) {
+ ((DocumentBuilderFactory) factory)
+ .setValidating(((Boolean) sref
+ .getProperty(PARSER_VALIDATING)).booleanValue());
+ ((DocumentBuilderFactory) factory)
+ .setNamespaceAware(((Boolean) sref
+ .getProperty(PARSER_NAMESPACEAWARE))
+ .booleanValue());
}
- else
- if (factory instanceof DocumentBuilderFactory) {
- ((DocumentBuilderFactory) factory)
- .setValidating(((Boolean) sref
- .getProperty(PARSER_VALIDATING))
- .booleanValue());
- ((DocumentBuilderFactory) factory)
- .setNamespaceAware(((Boolean) sref
- .getProperty(PARSER_NAMESPACEAWARE))
- .booleanValue());
- }
- return factory;
}
- catch (FactoryConfigurationError fce) {
- fce.printStackTrace();
- return null;
- }
+ return factory;
}
/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/xml/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/xml/package.html
new file mode 100644
index 0000000..e153322
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/xml/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>XML Parser Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.xml; version="[1.0,2.0)"
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/xml/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/xml/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/xml/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file