You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by er...@apache.org on 2006/03/29 23:05:18 UTC

svn commit: r389891 [5/9] - in /incubator/felix/trunk/org.osgi.compendium: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/osgi/ src/main/java/org/osgi/service/ src/main/java/org/osgi/service/cm/ src/main/java/org/osgi/service/com...

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,173 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPService.java,v 1.7 2006/03/14 01:21:11 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.upnp;
+
+/**
+ * A representation of a UPnP Service.
+ * 
+ * Each UPnP device contains zero or more services. The UPnP description for a
+ * service defines actions, their arguments, and event characteristics.
+ */
+public interface UPnPService {
+	/**
+	 * Property key for the optional service type uri.
+	 * 
+	 * The service type property is used when registering UPnP Device services
+	 * and UPnP Event Listener services. The property contains a <code>String</code>
+	 * array (<code>String[]</code>) of service types. A UPnP Device service can
+	 * thus announce what types of services it contains. A UPnP Event Listener
+	 * service can announce for what type of UPnP services it wants
+	 * notifications. The service version is encoded in the type string as
+	 * specified in the UPnP specification. A <code>null</code> value is a
+	 * wildcard, matching <b>all </b> service types. Value is
+	 * "UPnP.service.type".
+	 * 
+	 * @see UPnPService#getType()
+	 */
+	String	TYPE	= "UPnP.service.type";
+	/**
+	 * Property key for the optional service id.
+	 * 
+	 * The service id property is used when registering UPnP Device services or
+	 * UPnP Event Listener services. The value of the property contains a
+	 * <code>String</code> array (<code>String[]</code>) of service ids. A UPnP
+	 * Device service can thus announce what service ids it contains. A UPnP
+	 * Event Listener service can announce for what UPnP service ids it wants
+	 * notifications. A service id does <b>not </b> have to be universally
+	 * unique. It must be unique only within a device. A <code>null</code> value
+	 * is a wildcard, matching <b>all </b> services. The value is
+	 * "UPnP.service.id".
+	 */
+	String	ID		= "UPnP.service.id";
+
+	/**
+	 * Returns the <code>serviceId</code> field in the UPnP service description.
+	 * 
+	 * 
+	 * <p>
+	 * For standard services defined by a UPnP Forum working committee, the
+	 * serviceId must contain the following components in the indicated order:
+	 * <ul>
+	 * <li><code>urn:upnp-org:serviceId:</code></li>
+	 * <li>service ID suffix</li>
+	 * </ul>
+	 * Example: <code>urn:upnp-org:serviceId:serviceID</code>.
+	 * 
+	 * <p>
+	 * Note that <code>upnp-org</code> is used instead of
+	 * <code>schemas-upnp-org</code> in this example because an XML schema is not
+	 * defined for each serviceId.
+	 * </p>
+	 * 
+	 * <p>
+	 * For non-standard services specified by UPnP vendors, the serviceId must
+	 * contain the following components in the indicated order:
+	 * <ul>
+	 * <li><code>urn:</code></li>
+	 * <li>ICANN domain name owned by the vendor</li>
+	 * <li><code>:serviceId:</code></li>
+	 * <li>service ID suffix</li>
+	 * </ul>
+	 * Example: <code>urn:domain-name:serviceId:serviceID</code>.
+	 * 
+	 * @return The service ID suffix defined by a UPnP Forum working committee
+	 *         or specified by a UPnP vendor. Must be &lt;= 64 characters.
+	 *         Single URI.
+	 */
+	String getId();
+
+	/**
+	 * Returns the <code>serviceType</code> field in the UPnP service description.
+	 * 
+	 * <p>
+	 * For standard services defined by a UPnP Forum working committee, the
+	 * serviceType must contain the following components in the indicated order:
+	 * <ul>
+	 * <li><code>urn:schemas-upnp-org:service:</code></li>
+	 * <li>service type suffix:</li>
+	 * <li>integer service version</li>
+	 * </ul>
+	 * Example: <code>urn:schemas-upnp-org:service:serviceType:v</code>.
+	 * 
+	 * <p>
+	 * For non-standard services specified by UPnP vendors, the
+	 * <code>serviceType</code> must contain the following components in the
+	 * indicated order:
+	 * <ul>
+	 * <li><code>urn:</code></li>
+	 * <li>ICANN domain name owned by the vendor</li>
+	 * <li><code>:service:</code></li>
+	 * <li>service type suffix:</li>
+	 * <li>integer service version</li>
+	 * </ul>
+	 * Example: <code>urn:domain-name:service:serviceType:v</code>.
+	 * 
+	 * @return The service type suffix defined by a UPnP Forum working committee
+	 *         or specified by a UPnP vendor. Must be &lt;= 64 characters, not
+	 *         including the version suffix and separating colon. Single URI.
+	 */
+	String getType();
+
+	/**
+	 * Returns the version suffix encoded in the <code>serviceType</code> field in
+	 * the UPnP service description.
+	 * 
+	 * @return The integer service version defined by a UPnP Forum working
+	 *         committee or specified by a UPnP vendor.
+	 */
+	String getVersion();
+
+	/**
+	 * Locates a specific action by name.
+	 * 
+	 * Looks up an action by its name.
+	 * 
+	 * @param name Name of action. Must not contain hyphen or hash characters.
+	 *        Should be &lt; 32 characters.
+	 * 
+	 * @return The requested action or <code>null</code> if no action is found.
+	 */
+	UPnPAction getAction(String name);
+
+	/**
+	 * Lists all actions provided by this service.
+	 * 
+	 * @return Array of actions (<code>UPnPAction[]</code> )or <code>null</code> if
+	 *         no actions are defined for this service.
+	 */
+	UPnPAction[] getActions();
+
+	/**
+	 * Lists all <code>UPnPStateVariable</code> objects provided by this service.
+	 * 
+	 * @return Array of state variables or <code>null</code> if none are defined
+	 *         for this service.
+	 */
+	UPnPStateVariable[] getStateVariables();
+
+	/**
+	 * Gets a <code>UPnPStateVariable</code> objects provided by this service by
+	 * name
+	 * 
+	 * @param name Name of the State Variable
+	 * 
+	 * @return State variable or <code>null</code> if no such state variable
+	 *         exists for this service.
+	 */
+	UPnPStateVariable getStateVariable(String name);
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,342 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPStateVariable.java,v 1.7 2006/03/14 01:21:11 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.upnp;
+
+/**
+ * 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.
+ * <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.
+ */
+public interface UPnPStateVariable {
+	/**
+	 * Unsigned 1 <code>Byte</code> int.
+	 * <p>
+	 * Mapped to an <code>Integer</code> object.
+	 */
+	static final String	TYPE_UI1			= "ui1";
+	/**
+	 * Unsigned 2 Byte int.
+	 * <p>
+	 * Mapped to <code>Integer</code> object.
+	 */
+	static final String	TYPE_UI2			= "ui2";
+	/**
+	 * Unsigned 4 Byte int.
+	 * <p>
+	 * Mapped to <code>Long</code> object.
+	 */
+	static final String	TYPE_UI4			= "ui4";
+	/**
+	 * 1 Byte int.
+	 * <p>
+	 * Mapped to <code>Integer</code> object.
+	 */
+	static final String	TYPE_I1				= "i1";
+	/**
+	 * 2 Byte int.
+	 * <p>
+	 * Mapped to <code>Integer</code> object.
+	 */
+	static final String	TYPE_I2				= "i2";
+	/**
+	 * 4 Byte int.
+	 * <p>
+	 * Must be between -2147483648 and 2147483647
+	 * <p>
+	 * Mapped to <code>Integer</code> object.
+	 */
+	static final String	TYPE_I4				= "i4";
+	/**
+	 * Integer number.
+	 * <p>
+	 * Mapped to <code>Integer</code> object.
+	 */
+	static final String	TYPE_INT			= "int";
+	/**
+	 * 4 Byte float.
+	 * <p>
+	 * Same format as float. Must be between 3.40282347E+38 to 1.17549435E-38.
+	 * <p>
+	 * Mapped to <code>Float</code> object.
+	 */
+	static final String	TYPE_R4				= "r4";
+	/**
+	 * 8 Byte float.
+	 * <p>
+	 * Same format as float. Must be between -1.79769313486232E308 and
+	 * -4.94065645841247E-324 for negative values, and between
+	 * 4.94065645841247E-324 and 1.79769313486232E308 for positive values, i.e.,
+	 * IEEE 64-bit (8-Byte) double.
+	 * <p>
+	 * Mapped to <code>Double</code> object.
+	 */
+	static final String	TYPE_R8				= "r8";
+	/**
+	 * Same as r8.
+	 * <p>
+	 * Mapped to <code>Double</code> object.
+	 */
+	static final String	TYPE_NUMBER			= "number";
+	/**
+	 * Same as r8 but no more than 14 digits to the left of the decimal point
+	 * and no more than 4 to the right.
+	 * <p>
+	 * Mapped to <code>Double</code> object.
+	 */
+	static final String	TYPE_FIXED_14_4		= "fixed.14.4";
+	/**
+	 * Floating-point number.
+	 * <p>
+	 * Mantissa (left of the decimal) and/or exponent may have a leading sign.
+	 * Mantissa and/or exponent may have leading zeros. Decimal character in
+	 * mantissa is a period, i.e., whole digits in mantissa separated from
+	 * fractional digits by period. Mantissa separated from exponent by E. (No
+	 * currency symbol.) (No grouping of digits in the mantissa, e.g., no
+	 * commas.)
+	 * <p>
+	 * Mapped to <code>Float</code> object.
+	 */
+	static final String	TYPE_FLOAT			= "float";
+	/**
+	 * Unicode string.
+	 * <p>
+	 * One character long.
+	 * <p>
+	 * Mapped to <code>Character</code> object.
+	 */
+	static final String	TYPE_CHAR			= "char";
+	/**
+	 * Unicode string.
+	 * <p>
+	 * No limit on length.
+	 * <p>
+	 * Mapped to <code>String</code> object.
+	 */
+	static final String	TYPE_STRING			= "string";
+	/**
+	 * A calendar date.
+	 * <p>
+	 * Date in a subset of ISO 8601 format without time data.
+	 * <p>
+	 * See <a
+	 * href="http://www.w3.org/TR/xmlschema-2/#date">http://www.w3.org/TR/xmlschema-2/#date
+	 * </a>.
+	 * <p>
+	 * Mapped to <code>java.util.Date</code> object. Always 00:00 hours.
+	 */
+	static final String	TYPE_DATE			= "date";
+	/**
+	 * A specific instant of time.
+	 * <p>
+	 * Date in ISO 8601 format with optional time but no time zone.
+	 * <p>
+	 * See <a
+	 * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#dateTime
+	 * </a>.
+	 * <p>
+	 * Mapped to <code>java.util.Date</code> object using default time zone.
+	 */
+	static final String	TYPE_DATETIME		= "dateTime";
+	/**
+	 * A specific instant of time.
+	 * <p>
+	 * Date in ISO 8601 format with optional time and optional time zone.
+	 * <p>
+	 * See <a
+	 * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#dateTime
+	 * </a>.
+	 * <p>
+	 * Mapped to <code>java.util.Date</code> object adjusted to default time zone.
+	 */
+	static final String	TYPE_DATETIME_TZ	= "dateTime.tz";
+	/**
+	 * An instant of time that recurs every day.
+	 * <p>
+	 * Time in a subset of ISO 8601 format with no date and no time zone.
+	 * <p>
+	 * See <a
+	 * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#time
+	 * </a>.
+	 * <p>
+	 * Mapped to <code>Long</code>. Converted to milliseconds since midnight.
+	 */
+	static final String	TYPE_TIME			= "time";
+	/**
+	 * An instant of time that recurs every day.
+	 * <p>
+	 * Time in a subset of ISO 8601 format with optional time zone but no date.
+	 * <p>
+	 * See <a
+	 * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#time
+	 * </a>.
+	 * <p>
+	 * Mapped to <code>Long</code> object. Converted to milliseconds since
+	 * midnight and adjusted to default time zone, wrapping at 0 and
+	 * 24*60*60*1000.
+	 */
+	static final String	TYPE_TIME_TZ		= "time.tz";
+	/**
+	 * True or false.
+	 * <p>
+	 * Mapped to <code>Boolean</code> object.
+	 */
+	static final String	TYPE_BOOLEAN		= "boolean";
+	/**
+	 * MIME-style Base64 encoded binary BLOB.
+	 * <p>
+	 * Takes 3 Bytes, splits them into 4 parts, and maps each 6 bit piece to an
+	 * octet. (3 octets are encoded as 4.) No limit on size.
+	 * <p>
+	 * Mapped to <code>byte[]</code> object. The Java byte array will hold the
+	 * decoded content of the BLOB.
+	 */
+	static final String	TYPE_BIN_BASE64		= "bin.base64";
+	/**
+	 * Hexadecimal digits representing octets.
+	 * <p>
+	 * Treats each nibble as a hex digit and encodes as a separate Byte. (1
+	 * octet is encoded as 2.) No limit on size.
+	 * <p>
+	 * Mapped to <code>byte[]</code> object. The Java byte array will hold the
+	 * decoded content of the BLOB.
+	 */
+	static final String	TYPE_BIN_HEX		= "bin.hex";
+	/**
+	 * Universal Resource Identifier.
+	 * <p>
+	 * Mapped to <code>String</code> object.
+	 */
+	static final String	TYPE_URI			= "uri";
+	/**
+	 * Universally Unique ID.
+	 * <p>
+	 * Hexadecimal digits representing octets. Optional embedded hyphens are
+	 * ignored.
+	 * <p>
+	 * Mapped to <code>String</code> object.
+	 */
+	static final String	TYPE_UUID			= "uuid";
+
+	/**
+	 * Returns the variable name.
+	 * 
+	 * <ul>
+	 * <li>All standard variables defined by a UPnP Forum working committee
+	 * must not begin with <code>X_</code> nor <code>A_</code>.</li>
+	 * <li>All non-standard variables specified by a UPnP vendor and added to a
+	 * standard service must begin with <code>X_</code>.</li>
+	 * </ul>
+	 * 
+	 * @return Name of state variable. Must not contain a hyphen character nor a
+	 *         hash character. Should be &lt; 32 characters.
+	 */
+	String getName();
+
+	/**
+	 * Returns the Java class associated with the UPnP data type of this state
+	 * variable.
+	 * <P>
+	 * Mapping between the UPnP data types and Java classes is performed
+	 * according to the schema mentioned above.
+	 * 
+	 * <pre>
+	 * 
+	 *  Integer              ui1, ui2, i1, i2, i4, int
+	 *  Long                 ui4, time, time.tz
+	 *  Float                r4, float
+	 *  Double               r8, number, fixed.14.4
+	 *  Character            char
+	 *  String               string, uri, uuid
+	 *  Date                 date, dateTime, dateTime.tz
+	 *  Boolean              boolean
+	 *  byte[]               bin.base64, bin.hex
+	 *  
+	 * </pre>
+	 * 
+	 * @return A class object corresponding to the Java type of this argument.
+	 */
+	Class getJavaDataType();
+
+	/**
+	 * Returns the UPnP type of this state variable. Valid types are defined as
+	 * constants.
+	 * 
+	 * @return The UPnP data type of this state variable, as defined in above
+	 *         constants.
+	 */
+	String getUPnPDataType();
+
+	/**
+	 * Returns the default value, if defined.
+	 * 
+	 * @return The default value or <code>null</code> if not defined. The type of
+	 *         the returned object can be determined by <code>getJavaDataType</code>.
+	 */
+	Object getDefaultValue();
+
+	/**
+	 * Returns the allowed values, if defined. Allowed values can be defined
+	 * only for String types.
+	 * 
+	 * @return The allowed values or <code>null</code> if not defined. Should be
+	 *         less than 32 characters.
+	 */
+	String[] getAllowedValues();
+
+	/**
+	 * Returns the minimum value, if defined. Minimum values can only be defined
+	 * for numeric types.
+	 * 
+	 * @return The minimum value or <code>null</code> if not defined.
+	 */
+	Number getMinimum();
+
+	/**
+	 * Returns the maximum value, if defined. Maximum values can only be defined
+	 * for numeric types.
+	 * 
+	 * @return The maximum value or <code>null</code> if not defined.
+	 */
+	Number getMaximum();
+
+	/**
+	 * Returns the size of an increment operation, if defined. Step sizes can be
+	 * defined only for numeric types.
+	 * 
+	 * @return The increment size or null if not defined.
+	 */
+	Number getStep();
+
+	/**
+	 * Tells if this StateVariable can be used as an event source.
+	 * 
+	 * If the StateVariable is eventable, an event listener service can be
+	 * registered to be notified when changes to the variable appear.
+	 * 
+	 * @return <code>true</code> if the <code>StateVariable</code> generates events,
+	 *         <code>false</code> otherwise.
+	 */
+	boolean sendsEvents();
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html Wed Mar 29 13:05:08 2006
@@ -0,0 +1,10 @@
+<!-- $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/package.html,v 1.3 2004/12/09 20:04:20 hargrave Exp $ -->
+<BODY>
+<P>The OSGi UPnP API Package. Specification 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
+</pre>
+</BODY>

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo Wed Mar 29 13:05:08 2006
@@ -0,0 +1 @@
+version 1.1

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,104 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Authorization.java,v 1.7 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+/**
+ * The <code>Authorization</code> interface encapsulates an authorization context
+ * on which bundles can base authorization decisions, where appropriate.
+ * <p>
+ * Bundles associate the privilege to access restricted resources or operations
+ * with roles. Before granting access to a restricted resource or operation, a
+ * bundle will check if the <code>Authorization</code> object passed to it possess
+ * the required role, by calling its <code>hasRole</code> method.
+ * <p>
+ * Authorization contexts are instantiated by calling the
+ * {@link UserAdmin#getAuthorization}method.
+ * 
+ * <p>
+ * <i>Trusting Authorization objects </i>
+ * <p>
+ * There are no restrictions regarding the creation of <code>Authorization</code>
+ * objects. Hence, a service must only accept <code>Authorization</code> objects
+ * from bundles that has been authorized to use the service using code based (or
+ * Java 2) permissions.
+ * 
+ * <p>
+ * In some cases it is useful to use <code>ServicePermission</code> to do the code
+ * based access control. A service basing user access control on
+ * <code>Authorization</code> objects passed to it, will then require that a
+ * calling bundle has the <code>ServicePermission</code> to get the service in
+ * question. This is the most convenient way. The OSGi environment will do the
+ * code based permission check when the calling bundle attempts to get the
+ * service from the service registry.
+ * <p>
+ * Example: A servlet using a service on a user's behalf. The bundle with the
+ * servlet must be given the <code>ServicePermission</code> to get the Http
+ * Service.
+ * <p>
+ * However, in some cases the code based permission checks need to be more
+ * fine-grained. A service might allow all bundles to get it, but require
+ * certain code based permissions for some of its methods.
+ * <p>
+ * Example: A servlet using a service on a user's behalf, where some service
+ * functionality is open to anyone, and some is restricted by code based
+ * permissions. When a restricted method is called (e.g., one handing over an
+ * <code>Authorization</code> object), the service explicitly checks that the
+ * calling bundle has permission to make the call.
+ * 
+ * @version $Revision: 1.7 $
+ */
+public interface Authorization {
+	/**
+	 * Gets the name of the {@link User}that this <code>Authorization</code>
+	 * context was created for.
+	 * 
+	 * @return The name of the {@link User}object that this
+	 *         <code>Authorization</code> context was created for, or
+	 *         <code>null</code> if no user was specified when this
+	 *         <code>Authorization</code> context was created.
+	 */
+	public String getName();
+
+	/**
+	 * Checks if the role with the specified name is implied by this
+	 * <code>Authorization</code> context.
+	 * <p>
+	 * 
+	 * Bundles must define globally unique role names that are associated with
+	 * the privilege of accessing restricted resources or operations. Operators
+	 * will grant users access to these resources, by creating a {@link Group}
+	 * object for each role and adding {@link User}objects to it.
+	 * 
+	 * @param name The name of the role to check for.
+	 * 
+	 * @return <code>true</code> if this <code>Authorization</code> context implies
+	 *         the specified role, otherwise <code>false</code>.
+	 */
+	public boolean hasRole(String name);
+
+	/**
+	 * Gets the names of all roles encapsulated by this <code>Authorization</code>
+	 * context.
+	 * 
+	 * @return The names of all roles encapsulated by this
+	 *         <code>Authorization</code> context, or <code>null</code> if no roles
+	 *         are in the context. The predefined role <code>user.anyone</code>
+	 *         will not be included in this list.
+	 */
+	public String[] getRoles();
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,160 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Group.java,v 1.7 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+/**
+ * A named grouping of roles (<code>Role</code> objects).
+ * <p>
+ * Whether or not a given <code>Authorization</code> context implies a
+ * <code>Group</code> object depends on the members of that <code>Group</code>
+ * object.
+ * <p>
+ * A <code>Group</code> object can have two kinds of members: <i>basic </i> and
+ * <i>required </i>. A <code>Group</code> object is implied by an
+ * <code>Authorization</code> context if all of its required members are implied
+ * and at least one of its basic members is implied.
+ * <p>
+ * A <code>Group</code> object must contain at least one basic member in order to
+ * be implied. In other words, a <code>Group</code> object without any basic
+ * member roles is never implied by any <code>Authorization</code> context.
+ * <p>
+ * A <code>User</code> object always implies itself.
+ * <p>
+ * No loop detection is performed when adding members to <code>Group</code>
+ * objects, which means that it is possible to create circular implications.
+ * Loop detection is instead done when roles are checked. The semantics is that
+ * if a role depends on itself (i.e., there is an implication loop), the role is
+ * not implied.
+ * <p>
+ * The rule that a <code>Group</code> object must have at least one basic member
+ * to be implied is motivated by the following example:
+ * 
+ * <pre>
+ * 
+ *  group foo
+ *    required members: marketing
+ *    basic members: alice, bob
+ *  
+ * </pre>
+ * 
+ * Privileged operations that require membership in "foo" can be performed only
+ * by "alice" and "bob", who are in marketing.
+ * <p>
+ * If "alice" and "bob" ever transfer to a different department, anybody in
+ * marketing will be able to assume the "foo" role, which certainly must be
+ * prevented. Requiring that "foo" (or any <code>Group</code> object for that
+ * matter) must have at least one basic member accomplishes that.
+ * <p>
+ * However, this would make it impossible for a <code>Group</code> object to be
+ * implied by just its required members. An example where this implication might
+ * be useful is the following declaration: "Any citizen who is an adult is
+ * allowed to vote." An intuitive configuration of "voter" would be:
+ * 
+ * <pre>
+ * 
+ *  group voter
+ *    required members: citizen, adult
+ *       basic members:
+ *  
+ * </pre>
+ * 
+ * However, according to the above rule, the "voter" role could never be assumed
+ * by anybody, since it lacks any basic members. In order to address this issue
+ * a predefined role named "user.anyone" can be specified, which is always
+ * implied. The desired implication of the "voter" group can then be achieved by
+ * specifying "user.anyone" as its basic member, as follows:
+ * 
+ * <pre>
+ * 
+ *  group voter
+ *    required members: citizen, adult
+ *       basic members: user.anyone
+ *  
+ * </pre>
+ * 
+ * @version $Revision: 1.7 $
+ */
+public interface Group extends User {
+	/**
+	 * Adds the specified <code>Role</code> object as a basic member to this
+	 * <code>Group</code> object.
+	 * 
+	 * @param role The role to add as a basic member.
+	 * 
+	 * @return <code>true</code> if the given role could be added as a basic
+	 *         member, and <code>false</code> if this <code>Group</code> object
+	 *         already contains a <code>Role</code> object whose name matches that
+	 *         of the specified role.
+	 * 
+	 * @throws SecurityException If a security manager exists and the caller
+	 *         does not have the <code>UserAdminPermission</code> with name
+	 *         <code>admin</code>.
+	 */
+	public boolean addMember(Role role);
+
+	/**
+	 * Adds the specified <code>Role</code> object as a required member to this
+	 * <code>Group</code> object.
+	 * 
+	 * @param role The <code>Role</code> object to add as a required member.
+	 * 
+	 * @return <code>true</code> if the given <code>Role</code> object could be
+	 *         added as a required member, and <code>false</code> if this
+	 *         <code>Group</code> object already contains a <code>Role</code> object
+	 *         whose name matches that of the specified role.
+	 * 
+	 * @throws SecurityException If a security manager exists and the caller
+	 *         does not have the <code>UserAdminPermission</code> with name
+	 *         <code>admin</code>.
+	 */
+	public boolean addRequiredMember(Role role);
+
+	/**
+	 * Removes the specified <code>Role</code> object from this <code>Group</code>
+	 * object.
+	 * 
+	 * @param role The <code>Role</code> object to remove from this <code>Group</code>
+	 *        object.
+	 * 
+	 * @return <code>true</code> if the <code>Role</code> object could be removed,
+	 *         otherwise <code>false</code>.
+	 * 
+	 * @throws SecurityException If a security manager exists and the caller
+	 *         does not have the <code>UserAdminPermission</code> with name
+	 *         <code>admin</code>.
+	 */
+	public boolean removeMember(Role role);
+
+	/**
+	 * Gets the basic members of this <code>Group</code> object.
+	 * 
+	 * @return The basic members of this <code>Group</code> object, or
+	 *         <code>null</code> if this <code>Group</code> object does not contain
+	 *         any basic members.
+	 */
+	public Role[] getMembers();
+
+	/**
+	 * Gets the required members of this <code>Group</code> object.
+	 * 
+	 * @return The required members of this <code>Group</code> object, or
+	 *         <code>null</code> if this <code>Group</code> object does not contain
+	 *         any required members.
+	 */
+	public Role[] getRequiredMembers();
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,119 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Role.java,v 1.8 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+import java.util.Dictionary;
+
+/**
+ * The base interface for <code>Role</code> objects managed by the User Admin
+ * service.
+ * 
+ * <p>
+ * This interface exposes the characteristics shared by all <code>Role</code>
+ * classes: a name, a type, and a set of properties.
+ * <p>
+ * Properties represent public information about the <code>Role</code> object that
+ * can be read by anyone. Specific {@link UserAdminPermission}objects are
+ * required to change a <code>Role</code> object's properties.
+ * <p>
+ * <code>Role</code> object properties are <code>Dictionary</code> objects. Changes
+ * to these objects are propagated to the User Admin service and made
+ * persistent.
+ * <p>
+ * Every User Admin service contains a set of predefined <code>Role</code> objects
+ * that are always present and cannot be removed. All predefined <code>Role</code>
+ * objects are of type <code>ROLE</code>. This version of the
+ * <code>org.osgi.service.useradmin</code> package defines a single predefined
+ * role named &quot;user.anyone&quot;, which is inherited by any other role.
+ * Other predefined roles may be added in the future. Since
+ * &quot;user.anyone&quot; is a <code>Role</code> object that has properties
+ * associated with it that can be read and modified. Access to these properties
+ * and their use is application specific and is controlled using
+ * <code>UserAdminPermission</code> in the same way that properties for other
+ * <code>Role</code> objects are.
+ * 
+ * @version $Revision: 1.8 $
+ */
+public interface Role {
+	/**
+	 * The name of the predefined role, user.anyone, that all users and groups
+	 * belong to.
+	 * @since 1.1
+	 */
+	public static final String	USER_ANYONE	= "user.anyone";
+	/**
+	 * The type of a predefined role.
+	 * 
+	 * <p>
+	 * The value of <code>ROLE</code> is 0.
+	 */
+	public static final int		ROLE		= 0;
+	/**
+	 * The type of a {@link User}role.
+	 * 
+	 * <p>
+	 * The value of <code>USER</code> is 1.
+	 */
+	public static final int		USER		= 1;
+	/**
+	 * The type of a {@link Group}role.
+	 * 
+	 * <p>
+	 * The value of <code>GROUP</code> is 2.
+	 */
+	public static final int		GROUP		= 2;
+
+	/**
+	 * Returns the name of this role.
+	 * 
+	 * @return The role's name.
+	 */
+	public String getName();
+
+	/**
+	 * Returns the type of this role.
+	 * 
+	 * @return The role's type.
+	 */
+	public int getType();
+
+	/**
+	 * Returns a <code>Dictionary</code> of the (public) properties of this
+	 * <code>Role</code> object. Any changes to the returned <code>Dictionary</code>
+	 * will change the properties of this <code>Role</code> object. This will
+	 * cause a <code>UserAdminEvent</code> object of type
+	 * {@link UserAdminEvent#ROLE_CHANGED}to be broadcast to any
+	 * <code>UserAdminListener</code> objects.
+	 * 
+	 * <p>
+	 * Only objects of type <code>String</code> may be used as property keys, and
+	 * only objects of type <code>String</code> or <code>byte[]</code> may be used
+	 * as property values. Any other types will cause an exception of type
+	 * <code>IllegalArgumentException</code> to be raised.
+	 * 
+	 * <p>
+	 * In order to add, change, or remove a property in the returned
+	 * <code>Dictionary</code>, a {@link UserAdminPermission}named after the
+	 * property name (or a prefix of it) with action <code>changeProperty</code>
+	 * is required.
+	 * 
+	 * @return <code>Dictionary</code> containing the properties of this
+	 *         <code>Role</code> object.
+	 */
+	public Dictionary getProperties();
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,96 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/User.java,v 1.7 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+import java.util.Dictionary;
+
+/**
+ * A <code>User</code> role managed by a User Admin service.
+ * 
+ * <p>
+ * In this context, the term &quot;user&quot; is not limited to just human
+ * beings. Instead, it refers to any entity that may have any number of
+ * credentials associated with it that it may use to authenticate itself.
+ * <p>
+ * In general, <code>User</code> objects are associated with a specific User Admin
+ * service (namely the one that created them), and cannot be used with other
+ * User Admin services.
+ * <p>
+ * A <code>User</code> object may have credentials (and properties, inherited from
+ * the {@link Role}class) associated with it. Specific
+ * {@link UserAdminPermission}objects are required to read or change a
+ * <code>User</code> object's credentials.
+ * <p>
+ * Credentials are <code>Dictionary</code> objects and have semantics that are
+ * similar to the properties in the <code>Role</code> class.
+ * 
+ * @version $Revision: 1.7 $
+ */
+public interface User extends Role {
+	/**
+	 * Returns a <code>Dictionary</code> of the credentials of this <code>User</code>
+	 * object. Any changes to the returned <code>Dictionary</code> object will
+	 * change the credentials of this <code>User</code> object. This will cause a
+	 * <code>UserAdminEvent</code> object of type
+	 * {@link UserAdminEvent#ROLE_CHANGED}to be broadcast to any
+	 * <code>UserAdminListeners</code> objects.
+	 * 
+	 * <p>
+	 * Only objects of type <code>String</code> may be used as credential keys,
+	 * and only objects of type <code>String</code> or of type <code>byte[]</code>
+	 * may be used as credential values. Any other types will cause an exception
+	 * of type <code>IllegalArgumentException</code> to be raised.
+	 * 
+	 * <p>
+	 * In order to retrieve a credential from the returned <code>Dictionary</code>
+	 * object, a {@link UserAdminPermission}named after the credential name (or
+	 * a prefix of it) with action <code>getCredential</code> is required.
+	 * <p>
+	 * In order to add or remove a credential from the returned
+	 * <code>Dictionary</code> object, a {@link UserAdminPermission}named after
+	 * the credential name (or a prefix of it) with action
+	 * <code>changeCredential</code> is required.
+	 * 
+	 * @return <code>Dictionary</code> object containing the credentials of this
+	 *         <code>User</code> object.
+	 */
+	public Dictionary getCredentials();
+
+	/**
+	 * Checks to see if this <code>User</code> object has a credential with the
+	 * specified <code>key</code> set to the specified <code>value</code>.
+	 * 
+	 * <p>
+	 * If the specified credential <code>value</code> is not of type
+	 * <code>String</code> or <code>byte[]</code>, it is ignored, that is,
+	 * <code>false</code> is returned (as opposed to an
+	 * <code>IllegalArgumentException</code> being raised).
+	 * 
+	 * @param key The credential <code>key</code>.
+	 * @param value The credential <code>value</code>.
+	 * 
+	 * @return <code>true</code> if this user has the specified credential;
+	 *         <code>false</code> otherwise.
+	 * 
+	 * @throws SecurityException If a security manager exists and the caller
+	 *         does not have the <code>UserAdminPermission</code> named after the
+	 *         credential key (or a prefix of it) with action
+	 *         <code>getCredential</code>.
+	 */
+	public boolean hasCredential(String key, Object value);
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,159 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdmin.java,v 1.9 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+import org.osgi.framework.*;
+
+/**
+ * This interface is used to manage a database of named <code>Role</code> objects,
+ * which can be used for authentication and authorization purposes.
+ * 
+ * <p>
+ * This version of the User Admin service defines two types of <code>Role</code>
+ * objects: "User" and "Group". Each type of role is represented by an
+ * <code>int</code> constant and an interface. The range of positive integers is
+ * reserved for new types of roles that may be added in the future. When
+ * defining proprietary role types, negative constant values must be used.
+ * 
+ * <p>
+ * Every role has a name and a type.
+ * 
+ * <p>
+ * A {@link User}object can be configured with credentials (e.g., a password)
+ * and properties (e.g., a street address, phone number, etc.).
+ * <p>
+ * A {@link Group}object represents an aggregation of {@link User}and
+ * {@link Group}objects. In other words, the members of a <code>Group</code>
+ * object are roles themselves.
+ * <p>
+ * Every User Admin service manages and maintains its own namespace of
+ * <code>Role</code> objects, in which each <code>Role</code> object has a unique
+ * name.
+ * 
+ * @version $Revision: 1.9 $
+ */
+public interface UserAdmin {
+	/**
+	 * Creates a <code>Role</code> object with the given name and of the given
+	 * type.
+	 * 
+	 * <p>
+	 * If a <code>Role</code> object was created, a <code>UserAdminEvent</code>
+	 * object of type {@link UserAdminEvent#ROLE_CREATED}is broadcast to any
+	 * <code>UserAdminListener</code> object.
+	 * 
+	 * @param name The <code>name</code> of the <code>Role</code> object to create.
+	 * @param type The type of the <code>Role</code> object to create. Must be
+	 *        either a {@link Role#USER}type or {@link Role#GROUP}type.
+	 * 
+	 * @return The newly created <code>Role</code> object, or <code>null</code> if a
+	 *         role with the given name already exists.
+	 * 
+	 * @throws IllegalArgumentException if <code>type</code> is invalid.
+	 * 
+	 * @throws SecurityException If a security manager exists and the caller
+	 *         does not have the <code>UserAdminPermission</code> with name
+	 *         <code>admin</code>.
+	 */
+	public Role createRole(String name, int type);
+
+	/**
+	 * Removes the <code>Role</code> object with the given name from this User
+	 * Admin service.
+	 * 
+	 * <p>
+	 * If the <code>Role</code> object was removed, a <code>UserAdminEvent</code>
+	 * object of type {@link UserAdminEvent#ROLE_REMOVED}is broadcast to any
+	 * <code>UserAdminListener</code> object.
+	 * 
+	 * @param name The name of the <code>Role</code> object to remove.
+	 * 
+	 * @return <code>true</code> If a <code>Role</code> object with the given name
+	 *         is present in this User Admin service and could be removed,
+	 *         otherwise <code>false</code>.
+	 * 
+	 * @throws SecurityException If a security manager exists and the caller
+	 *         does not have the <code>UserAdminPermission</code> with name
+	 *         <code>admin</code>.
+	 */
+	public boolean removeRole(String name);
+
+	/**
+	 * Gets the <code>Role</code> object with the given <code>name</code> from this
+	 * User Admin service.
+	 * 
+	 * @param name The name of the <code>Role</code> object to get.
+	 * 
+	 * @return The requested <code>Role</code> object, or <code>null</code> if this
+	 *         User Admin service does not have a <code>Role</code> object with
+	 *         the given <code>name</code>.
+	 */
+	public Role getRole(String name);
+
+	/**
+	 * Gets the <code>Role</code> objects managed by this User Admin service that
+	 * have properties matching the specified LDAP filter criteria. See
+	 * <code>org.osgi.framework.Filter</code> for a description of the filter
+	 * syntax. If a <code>null</code> filter is specified, all Role objects
+	 * managed by this User Admin service are returned.
+	 * 
+	 * @param filter The filter criteria to match.
+	 * 
+	 * @return The <code>Role</code> objects managed by this User Admin service
+	 *         whose properties match the specified filter criteria, or all
+	 *         <code>Role</code> objects if a <code>null</code> filter is specified.
+	 *         If no roles match the filter, <code>null</code> will be returned.
+	 * @throws InvalidSyntaxException If the filter is not well formed.
+	 *  
+	 */
+	public Role[] getRoles(String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Gets the user with the given property <code>key</code>-<code>value</code>
+	 * pair from the User Admin service database. This is a convenience method
+	 * for retrieving a <code>User</code> object based on a property for which
+	 * every <code>User</code> object is supposed to have a unique value (within
+	 * the scope of this User Admin service), such as for example a X.500
+	 * distinguished name.
+	 * 
+	 * @param key The property key to look for.
+	 * @param value The property value to compare with.
+	 * 
+	 * @return A matching user, if <em>exactly</em> one is found. If zero or
+	 *         more than one matching users are found, <code>null</code> is
+	 *         returned.
+	 */
+	public User getUser(String key, String value);
+
+	/**
+	 * Creates an <code>Authorization</code> object that encapsulates the
+	 * specified <code>User</code> object and the <code>Role</code> objects it
+	 * possesses. The <code>null</code> user is interpreted as the anonymous user.
+	 * The anonymous user represents a user that has not been authenticated. An
+	 * <code>Authorization</code> object for an anonymous user will be unnamed,
+	 * and will only imply groups that user.anyone implies.
+	 * 
+	 * @param user The <code>User</code> object to create an
+	 *        <code>Authorization</code> object for, or <code>null</code> for the
+	 *        anonymous user.
+	 * 
+	 * @return the <code>Authorization</code> object for the specified
+	 *         <code>User</code> object.
+	 */
+	public Authorization getAuthorization(User user);
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,113 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java,v 1.7 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * <code>Role</code> change event.
+ * <p>
+ * <code>UserAdminEvent</code> objects are delivered asynchronously to any
+ * <code>UserAdminListener</code> objects when a change occurs in any of the
+ * <code>Role</code> objects managed by a User Admin service.
+ * 
+ * <p>
+ * A type code is used to identify the event. The following event types are
+ * defined: {@link #ROLE_CREATED}type, {@link #ROLE_CHANGED}type, and
+ * {@link #ROLE_REMOVED}type. Additional event types may be defined in the
+ * future.
+ * 
+ * @see UserAdmin
+ * @see UserAdminListener
+ * 
+ * @version $Revision: 1.7 $
+ */
+public class UserAdminEvent {
+	private ServiceReference	ref;
+	private int					type;
+	private Role				role;
+	/**
+	 * A <code>Role</code> object has been created.
+	 * 
+	 * <p>
+	 * The value of <code>ROLE_CREATED</code> is 0x00000001.
+	 */
+	public static final int		ROLE_CREATED	= 0x00000001;
+	/**
+	 * A <code>Role</code> object has been modified.
+	 * 
+	 * <p>
+	 * The value of <code>ROLE_CHANGED</code> is 0x00000002.
+	 */
+	public static final int		ROLE_CHANGED	= 0x00000002;
+	/**
+	 * A <code>Role</code> object has been removed.
+	 * 
+	 * <p>
+	 * The value of <code>ROLE_REMOVED</code> is 0x00000004.
+	 */
+	public static final int		ROLE_REMOVED	= 0x00000004;
+
+	/**
+	 * Constructs a <code>UserAdminEvent</code> object from the given
+	 * <code>ServiceReference</code> object, event type, and <code>Role</code>
+	 * object.
+	 * 
+	 * @param ref The <code>ServiceReference</code> object of the User Admin
+	 *        service that generated this event.
+	 * @param type The event type.
+	 * @param role The <code>Role</code> object on which this event occurred.
+	 */
+	public UserAdminEvent(ServiceReference ref, int type, Role role) {
+		this.ref = ref;
+		this.type = type;
+		this.role = role;
+	}
+
+	/**
+	 * Gets the <code>ServiceReference</code> object of the User Admin service
+	 * that generated this event.
+	 * 
+	 * @return The User Admin service's <code>ServiceReference</code> object.
+	 */
+	public ServiceReference getServiceReference() {
+		return ref;
+	}
+
+	/**
+	 * Returns the type of this event.
+	 * 
+	 * <p>
+	 * The type values are {@link #ROLE_CREATED}type, {@link #ROLE_CHANGED}
+	 * type, and {@link #ROLE_REMOVED}type.
+	 * 
+	 * @return The event type.
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * Gets the <code>Role</code> object this event was generated for.
+	 * 
+	 * @return The <code>Role</code> object this event was generated for.
+	 */
+	public Role getRole() {
+		return role;
+	}
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,45 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminListener.java,v 1.7 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+/**
+ * Listener for UserAdminEvents.
+ * 
+ * <p>
+ * <code>UserAdminListener</code> objects are registered with the Framework
+ * service registry and notified with a <code>UserAdminEvent</code> object when a
+ * <code>Role</code> object has been created, removed, or modified.
+ * <p>
+ * <code>UserAdminListener</code> objects can further inspect the received
+ * <code>UserAdminEvent</code> object to determine its type, the <code>Role</code>
+ * object it occurred on, and the User Admin service that generated it.
+ * 
+ * @see UserAdmin
+ * @see UserAdminEvent
+ * 
+ * @version $Revision: 1.7 $
+ */
+public interface UserAdminListener {
+	/**
+	 * Receives notification that a <code>Role</code> object has been created,
+	 * removed, or modified.
+	 * 
+	 * @param event The <code>UserAdminEvent</code> object.
+	 */
+	public void roleChanged(UserAdminEvent event);
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,630 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java,v 1.10 2006/03/14 01:20:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.useradmin;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.security.Permission;
+import java.security.BasicPermission;
+import java.security.PermissionCollection;
+
+/**
+ * Permission to configure and access the {@link Role}objects managed by a User
+ * 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
+ * {@link User}objects).
+ * <p>
+ * The permission name is the name (or name prefix) of a property or credential.
+ * The naming convention follows the hierarchical property naming convention.
+ * Also, an asterisk may appear at the end of the name, following a
+ * &quot;.&quot;, or by itself, to signify a wildcard match. For example:
+ * &quot;org.osgi.security.protocol.*&quot; or &quot;*&quot; is valid, but
+ * &quot;*protocol&quot; or &quot;a*b&quot; are not valid.
+ * 
+ * <p>
+ * The <code>UserAdminPermission</code> with the reserved name &quot;admin&quot;
+ * represents the permission required for creating and removing <code>Role</code>
+ * objects in the User Admin service, as well as adding and removing members in
+ * a <code>Group</code> object. This <code>UserAdminPermission</code> does not have
+ * any actions associated with it.
+ * 
+ * <p>
+ * The actions to be granted are passed to the constructor in a string
+ * containing a list of one or more comma-separated keywords. The possible
+ * keywords are: <code>changeProperty</code>,<code>changeCredential</code>, and
+ * <code>getCredential</code>. Their meaning is defined as follows:
+ * 
+ * <pre>
+ * 
+ *  action
+ *  changeProperty    Permission to change (i.e., add and remove)
+ *                    Role object properties whose names start with
+ *                    the name argument specified in the constructor.
+ *  changeCredential  Permission to change (i.e., add and remove)
+ *                    User object credentials whose names start
+ *                    with the name argument specified in the constructor.
+ *  getCredential     Permission to retrieve and check for the
+ *                    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.
+ * 
+ * <p>
+ * Following is a PermissionInfo style policy entry which grants a user
+ * administration bundle a number of <code>UserAdminPermission</code> object:
+ * 
+ * <pre>
+ * 
+ *  (org.osgi.service.useradmin.UserAdminPermission &quot;admin&quot;)
+ *  (org.osgi.service.useradmin.UserAdminPermission &quot;com.foo.*&quot; &quot;changeProperty,getCredential,changeCredential&quot;)
+ *  (org.osgi.service.useradmin.UserAdminPermission &quot;user.*&quot;, &quot;changeProperty,changeCredential&quot;)
+ *  
+ * </pre>
+ * 
+ * The first permission statement grants the bundle the permission to perform
+ * any User Admin service operations of type "admin", that is, create and remove
+ * roles and configure <code>Group</code> objects.
+ * 
+ * <p>
+ * The second permission statement grants the bundle the permission to change
+ * any properties as well as get and change any credentials whose names start
+ * with <code>com.foo.</code>.
+ * 
+ * <p>
+ * The third permission statement grants the bundle the permission to change any
+ * properties and credentials whose names start with <code>user.</code>. This
+ * means that the bundle is allowed to change, but not retrieve any credentials
+ * with the given prefix.
+ * 
+ * <p>
+ * The following policy entry empowers the Http Service bundle to perform user
+ * authentication:
+ * 
+ * <pre>
+ * 
+ *  grant codeBase &quot;${jars}http.jar&quot; {
+ *    permission org.osgi.service.useradmin.UserAdminPermission
+ *      &quot;user.password&quot;, &quot;getCredential&quot;;
+ *  };
+ *  
+ * </pre>
+ * 
+ * <p>
+ * The permission statement grants the Http Service bundle the permission to
+ * validate any password credentials (for authentication purposes), but the
+ * bundle is not allowed to change any properties or credentials.
+ * 
+ * @version $Revision: 1.10 $
+ */
+public final class UserAdminPermission extends BasicPermission {
+    static final long serialVersionUID = -1179971692401603789L;
+	/**
+	 * The permission name &quot;admin&quot;.
+	 */
+	public static final String	ADMIN						= "admin";
+	/**
+	 * The action string &quot;changeProperty&quot;.
+	 */
+	public static final String	CHANGE_PROPERTY				= "changeProperty";
+	private static final int	ACTION_CHANGE_PROPERTY		= 0x1;
+	/**
+	 * The action string &quot;changeCredential&quot;.
+	 */
+	public static final String	CHANGE_CREDENTIAL			= "changeCredential";
+	private static final int	ACTION_CHANGE_CREDENTIAL	= 0x2;
+	/**
+	 * The action string &quot;getCredential&quot;.
+	 */
+	public static final String	GET_CREDENTIAL				= "getCredential";
+	private static final int	ACTION_GET_CREDENTIAL		= 0x4;
+	/**
+	 * All actions
+	 */
+	private static final int	ACTION_ALL					= ACTION_CHANGE_PROPERTY
+																	| ACTION_CHANGE_CREDENTIAL
+																	| ACTION_GET_CREDENTIAL;
+	/**
+	 * No actions.
+	 */
+	static final int			ACTION_NONE					= 0x0;
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private 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;
+
+	/**
+	 * Creates a new <code>UserAdminPermission</code> with the specified name and
+	 * actions. <code>name</code> is either the reserved string &quot;admin&quot;
+	 * or the name of a credential or property, and <code>actions</code> contains
+	 * a comma-separated list of the actions granted on the specified name.
+	 * Valid actions are <code>changeProperty</code>,<code>changeCredential</code>,
+	 * and getCredential.
+	 * 
+	 * @param name the name of this <code>UserAdminPermission</code>
+	 * @param actions the action string.
+	 * 
+	 * @throws IllegalArgumentException If <code>name</code> equals
+	 *         &quot;admin&quot; and <code>actions</code> are specified.
+	 */
+	public UserAdminPermission(String name, String actions) {
+		this(name, getMask(actions));
+	}
+
+	/**
+	 * Package private constructor used by
+	 * <code>UserAdminPermissionCollection</code>.
+	 * 
+	 * @param name class name
+	 * @param mask action mask
+	 */
+	UserAdminPermission(String name, int mask) {
+		super(name);
+		init(mask);
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask action mask
+	 */
+	private void init(int mask) {
+		if (getName().equals(ADMIN)) {
+			if (mask != ACTION_NONE) {
+				throw new IllegalArgumentException("Actions specified for "
+						+ "no-action " + "UserAdminPermission");
+			}
+		}
+		else {
+			if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+				throw new IllegalArgumentException("Invalid action string");
+			}
+		}
+		action_mask = mask;
+	}
+
+	/**
+	 * Parses the action string into the action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int getMask(String actions) {
+		boolean seencomma = false;
+		int mask = ACTION_NONE;
+		if (actions == null) {
+			return (mask);
+		}
+		char[] a = actions.toCharArray();
+		int i = a.length - 1;
+		if (i < 0)
+			return (mask);
+		while (i != -1) {
+			char c;
+			// skip whitespace
+			while ((i != -1)
+					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+							|| c == '\f' || c == '\t'))
+				i--;
+			// check for the known strings
+			int matchlen;
+			if (i >= 12 && match_get(a, i - 10) && match_credential(a, i)) {
+				matchlen = 13;
+				mask |= ACTION_GET_CREDENTIAL;
+			}
+			else
+				if (i >= 13 && match_change(a, i - 8) && match_property(a, i)) {
+					matchlen = 14;
+					mask |= ACTION_CHANGE_PROPERTY;
+				}
+				else
+					if (i >= 15 && match_change(a, i - 10)
+							&& match_credential(a, i)) {
+						matchlen = 16;
+						mask |= ACTION_CHANGE_CREDENTIAL;
+					}
+					else {
+						// parse error
+						throw new IllegalArgumentException(
+								"invalid permission: " + actions);
+					}
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfimport". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+					/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException(
+								"invalid permission: " + actions);
+				}
+				i--;
+			}
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+		return (mask);
+	}
+
+	private static boolean match_change(char[] a, int i) {
+		return ((a[i - 5] == 'c' || a[i - 5] == 'C')
+				&& (a[i - 4] == 'h' || a[i - 4] == 'H')
+				&& (a[i - 3] == 'a' || a[i - 3] == 'A')
+				&& (a[i - 2] == 'n' || a[i - 2] == 'N')
+				&& (a[i - 1] == 'g' || a[i - 1] == 'G') && (a[i - 0] == 'e' || a[i - 0] == 'E'));
+	}
+
+	private static boolean match_get(char[] a, int i) {
+		return ((a[i - 2] == 'g' || a[i - 2] == 'G')
+				&& (a[i - 1] == 'e' || a[i - 1] == 'E') && (a[i - 0] == 't' || a[i - 0] == 'T'));
+	}
+
+	private static boolean match_property(char[] a, int i) {
+		return ((a[i - 7] == 'p' || a[i - 7] == 'P')
+				&& (a[i - 6] == 'r' || a[i - 6] == 'R')
+				&& (a[i - 5] == 'o' || a[i - 5] == 'O')
+				&& (a[i - 4] == 'p' || a[i - 4] == 'P')
+				&& (a[i - 3] == 'e' || a[i - 3] == 'E')
+				&& (a[i - 2] == 'r' || a[i - 2] == 'R')
+				&& (a[i - 1] == 't' || a[i - 1] == 'T') && (a[i - 0] == 'y' || a[i - 0] == 'Y'));
+	}
+
+	private static boolean match_credential(char[] a, int i) {
+		return ((a[i - 9] == 'c' || a[i - 9] == 'C')
+				&& (a[i - 8] == 'r' || a[i - 8] == 'R')
+				&& (a[i - 7] == 'e' || a[i - 7] == 'E')
+				&& (a[i - 6] == 'd' || a[i - 6] == 'D')
+				&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+				&& (a[i - 4] == 'n' || a[i - 4] == 'N')
+				&& (a[i - 3] == 't' || a[i - 3] == 'T')
+				&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+				&& (a[i - 1] == 'a' || a[i - 1] == 'A') && (a[i - 0] == 'l' || a[i - 0] == 'L'));
+	}
+
+	/**
+	 * Checks if this <code>UserAdminPermission</code> object &quot;implies&quot;
+	 * the specified permission.
+	 * <P>
+	 * More specifically, this method returns <code>true</code> if:
+	 * <p>
+	 * <ul>
+	 * <li><i>p </i> is an instanceof <code>UserAdminPermission</code>,
+	 * <li><i>p </i>'s actions are a proper subset of this object's actions,
+	 * and
+	 * <li><i>p </i>'s name is implied by this object's name. For example,
+	 * &quot;java.*&quot; implies &quot;java.home&quot;.
+	 * </ul>
+	 * 
+	 * @param p the permission to check against.
+	 * 
+	 * @return <code>true</code> if the specified permission is implied by this
+	 *         object; <code>false</code> otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (p instanceof 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
+					// admin permission, and then we must be that too
+					(target.action_mask != ACTION_NONE || action_mask == ACTION_NONE) &&
+			// Check that name name matches
+			super.implies(p));
+		}
+		else {
+			return (false);
+		}
+	}
+
+	/**
+	 * Returns the canonical string representation of the actions, separated by
+	 * comma.
+	 * 
+	 * @return the canonical string representation of the actions.
+	 */
+	public String getActions() {
+		if (actions == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+			if ((action_mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
+				sb.append(CHANGE_CREDENTIAL);
+				comma = true;
+			}
+			if ((action_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 (comma)
+					sb.append(',');
+				sb.append(GET_CREDENTIAL);
+			}
+			actions = sb.toString();
+		}
+		return (actions);
+	}
+
+	/**
+	 * 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.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return (new UserAdminPermissionCollection());
+	}
+
+	/**
+	 * Checks two <code>UserAdminPermission</code> objects for equality. Checks
+	 * that <code>obj</code> is a <code>UserAdminPermission</code>, and has the
+	 * same name and actions as this object.
+	 * 
+	 * @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.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return (true);
+		}
+		if (obj instanceof UserAdminPermission) {
+			UserAdminPermission uap = (UserAdminPermission) obj;
+			return ((action_mask == uap.action_mask) && getName().equals(
+					uap.getName()));
+		}
+		else {
+			return (false);
+		}
+	}
+
+	/**
+	 * Returns the hash code of this <code>UserAdminPermission</code> 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);
+	}
+
+	/**
+	 * writeObject is called to save the state of this object to a stream. The
+	 * actions are serialized, and the superclass takes care of the name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s)
+			throws IOException {
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/*
+	 * Restores this object from a stream (i.e., deserializes it).
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream ois)
+			throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		init(getMask(actions));
+	}
+
+	/**
+	 * Returns a string describing this <code>UserAdminPermission</code> object.
+	 * This string must be in <code>PermissionInfo</code> encoded format.
+	 * 
+	 * @return The <code>PermissionInfo</code> encoded string for this
+	 *         <code>UserAdminPermission</code> object.
+	 * @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();
+		}
+		return (description);
+	}
+}
+/**
+ * A <code>UserAdminPermissionCollection</code> stores a set of
+ * <code>UserAdminPermission</code> permissions.
+ */
+
+final class UserAdminPermissionCollection extends PermissionCollection {
+    static final long serialVersionUID = -7222111885230120581L;
+	/**
+	 * Table of permissions.
+	 * 
+	 * @serial
+	 */
+	private Hashtable	permissions;
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 */
+	private boolean		all_allowed;
+
+	/**
+	 * Creates an empty <code>UserAdminPermissionCollection</code> object.
+	 */
+	public UserAdminPermissionCollection() {
+		permissions = new Hashtable();
+		all_allowed = false;
+	}
+
+	/**
+	 * 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
+	 */
+	public void add(Permission permission) {
+		if (!(permission instanceof UserAdminPermission))
+			throw new IllegalArgumentException("Invalid permission: "
+					+ permission);
+		if (isReadOnly()) {
+			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));
+			}
+		}
+		else {
+			permissions.put(name, permission);
+		}
+		if (!all_allowed) {
+			if (name.equals("*"))
+				all_allowed = true;
+		}
+	}
+
+	/**
+	 * Checks to see if this <code>PermissionCollection</code> implies the given
+	 * permission.
+	 * 
+	 * @param permission the <code>Permission</code> object to check against
+	 * 
+	 * @return true if the given permission is implied by this
+	 *         <code>PermissionCollection</code>, false otherwise.
+	 */
+	public boolean implies(Permission permission) {
+		if (!(permission instanceof UserAdminPermission)) {
+			return (false);
+		}
+		UserAdminPermission uap = (UserAdminPermission) permission;
+		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);
+				}
+			}
+		}
+		// 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();
+			if ((effective & desired) == desired) {
+				return (true);
+			}
+		}
+		// work our way up the tree...
+		int last;
+		int offset = name.length() - 1;
+		while ((last = name.lastIndexOf(".", offset)) != -1) {
+			name = name.substring(0, last + 1) + "*";
+			x = (UserAdminPermission) permissions.get(name);
+			if (x != null) {
+				effective |= x.getMask();
+				if ((effective & desired) == desired) {
+					return (true);
+				}
+			}
+			offset = last - 1;
+		}
+		// we don't have to check for "*" as it was already checked
+		// at the top (all_allowed), so we just return false
+		return (false);
+	}
+
+	/**
+	 * Returns an enumeration of all the <code>UserAdminPermission</code> objects
+	 * in the container.
+	 * 
+	 * @return an enumeration of all the <code>UserAdminPermission</code> objects.
+	 */
+	public Enumeration elements() {
+		return (permissions.elements());
+	}
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html Wed Mar 29 13:05:08 2006
@@ -0,0 +1,10 @@
+<!-- $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/package.html,v 1.3 2005/08/11 03:07:42 hargrave Exp $ -->
+<BODY>
+<P>The OSGi User Admin service Package. Specification 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
+</pre>
+</BODY>

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo Wed Mar 29 13:05:08 2006
@@ -0,0 +1 @@
+version 1.1

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,66 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/BasicEnvelope.java,v 1.8 2006/03/14 01:20:55 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * <code>BasicEnvelope</code> is an implementation of the {@link Envelope}
+ * interface
+ * 
+ * @version $Revision: 1.8 $
+ */
+public class BasicEnvelope implements Envelope {
+	Object	value;
+	Object	identification;
+	String	scope;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param value Content of this envelope, may be <code>null</code>.
+	 * @param identification Identifying object for this <code>Envelope</code>
+	 *        object, must not be <code>null</code>
+	 * @param scope Scope name for this object, must not be <code>null</code>
+	 * @see Envelope
+	 */
+	public BasicEnvelope(Object value, Object identification, String scope) {
+		this.value = value;
+		this.identification = identification;
+		this.scope = scope;
+	}
+
+	/**
+	 * @see org.osgi.service.wireadmin.Envelope#getValue()
+	 */
+	public Object getValue() {
+		return value;
+	}
+
+	/**
+	 * @see org.osgi.service.wireadmin.Envelope#getIdentification()
+	 */
+	public Object getIdentification() {
+		return identification;
+	}
+
+	/**
+	 * @see org.osgi.service.wireadmin.Envelope#getScope()
+	 */
+	public String getScope() {
+		return scope;
+	}
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java?rev=389891&view=auto
==============================================================================
--- incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java (added)
+++ incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java Wed Mar 29 13:05:08 2006
@@ -0,0 +1,103 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Consumer.java,v 1.8 2006/03/14 01:20:55 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * Data Consumer, a service that can receive udpated values from
+ * {@link Producer}services.
+ * 
+ * <p>
+ * Service objects registered under the <code>Consumer</code> interface are
+ * expected to consume values from a Producer service via a <code>Wire</code>
+ * object. A Consumer service may poll the Producer service by calling the
+ * {@link Wire#poll}method. The Consumer service will also receive an updated
+ * value when called at it's {@link #updated}method. The Producer service
+ * should have coerced the value to be an instance of one of the types specified
+ * by the {@link Wire#getFlavors}method, or one of their subclasses.
+ * 
+ * <p>
+ * Consumer service objects must register with a <code>service.pid</code> and a
+ * {@link WireConstants#WIREADMIN_CONSUMER_FLAVORS}property. It is recommended
+ * that Consumer service objects also register with a
+ * <code>service.description</code> property.
+ * 
+ * <p>
+ * If an <code>Exception</code> is thrown by any of the <code>Consumer</code>
+ * methods, a <code>WireAdminEvent</code> of type
+ * {@link WireAdminEvent#CONSUMER_EXCEPTION}is broadcast by the Wire Admin
+ * service.
+ * 
+ * <p>
+ * Security Considerations - Data consuming bundles will require
+ * <code>ServicePermission[Consumer,REGISTER]</code>. In general, only the Wire
+ * Admin service bundle should have this permission. Thus only the Wire Admin
+ * service may directly call a Consumer service. Care must be taken in the
+ * sharing of <code>Wire</code> objects with other bundles.
+ * <p>
+ * Consumer services must be registered with their scope when they can receive
+ * 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.8 $
+ */
+public interface Consumer {
+	/**
+	 * Update the value. This Consumer service is called by the <code>Wire</code>
+	 * object with an updated value from the Producer service.
+	 * 
+	 * <p>
+	 * Note: This method may be called by a <code>Wire</code> object prior to this
+	 * object being notified that it is connected to that <code>Wire</code> object
+	 * (via the {@link #producersConnected}method).
+	 * <p>
+	 * When the Consumer service can receive <code>Envelope</code> objects, it
+	 * must have registered all scope names together with the service object,
+	 * and each of those names must be permitted by the bundle's
+	 * <code>WirePermission</code>. If an <code>Envelope</code> object is delivered
+	 * with the <code>updated</code> method, then the Consumer service should
+	 * assume that the security check has been performed.
+	 * 
+	 * @param wire The <code>Wire</code> object which is delivering the updated
+	 *        value.
+	 * @param value The updated value. The value should be an instance of one of
+	 *        the types specified by the {@link Wire#getFlavors}method.
+	 */
+	public void updated(Wire wire, Object value);
+
+	/**
+	 * Update the list of <code>Wire</code> objects to which this Consumer service
+	 * is connected.
+	 * 
+	 * <p>
+	 * This method is called when the Consumer service is first registered and
+	 * subsequently whenever a <code>Wire</code> associated with this Consumer
+	 * service becomes connected, is modified or becomes disconnected.
+	 * 
+	 * <p>
+	 * The Wire Admin service must call this method asynchronously. This implies
+	 * that implementors of Consumer can be assured that the callback will not
+	 * take place during registration when they execute the registration in a
+	 * synchronized method.
+	 * 
+	 * @param wires An array of the current and complete list of <code>Wire</code>
+	 *        objects to which this Consumer service is connected. May be
+	 *        <code>null</code> if the Consumer service is not currently connected
+	 *        to any <code>Wire</code> objects.
+	 */
+	public void producersConnected(Wire[] wires);
+}

Propchange: incubator/felix/trunk/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
------------------------------------------------------------------------------
    svn:eol-style = native