You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ch...@apache.org on 2008/06/02 13:40:01 UTC
svn commit: r662399 [8/9] - in /felix/trunk/deploymentadmin: ./ service/
service/src/ service/src/main/ service/src/main/java/
service/src/main/java/org/ service/src/main/java/org/apache/
service/src/main/java/org/apache/felix/ service/src/main/java/or...
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/StatusVariable.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/StatusVariable.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/StatusVariable.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/StatusVariable.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,433 @@
+/*
+ * $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.
+ *
+ * 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.monitor;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+
+/**
+ * A <code>StatusVariable</code> object represents the value of a status
+ * variable taken with a certain collection method at a certain point of time.
+ * The type of the <code>StatusVariable</code> can be <code>int</code>,
+ * <code>float</code>, <code>boolean</code> or <code>String</code>.
+ * <p>
+ * A <code>StatusVariable</code> is identified by an ID string that is unique
+ * within the scope of a <code>Monitorable</code>. The ID must be a non-
+ * <code>null</code>, non-empty string that conforms to the "symbolic-name"
+ * 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.
+ */
+public final class StatusVariable {
+ //----- Public constants -----//
+ /**
+ * Constant for identifying <code>int</code> data type.
+ */
+ public static final int TYPE_INTEGER = 0;
+
+ /**
+ * Constant for identifying <code>float</code> data type.
+ */
+ public static final int TYPE_FLOAT = 1;
+
+ /**
+ * Constant for identifying <code>String</code> data type.
+ */
+ public static final int TYPE_STRING = 2;
+
+ /**
+ * Constant for identifying <code>boolean</code> data type.
+ */
+ public static final int TYPE_BOOLEAN = 3;
+
+ /**
+ * Constant for identifying 'Cumulative Counter' data collection method.
+ */
+ public static final int CM_CC = 0;
+
+ /**
+ * Constant for identifying 'Discrete Event Registration' data collection
+ * method.
+ */
+ public static final int CM_DER = 1;
+
+ /**
+ * Constant for identifying 'Gauge' data collection method.
+ */
+ public static final int CM_GAUGE = 2;
+
+ /**
+ * Constant for identifying 'Status Inspection' data collection method.
+ */
+ public static final int CM_SI = 3;
+
+ //----- Package private constants -----//
+
+ static final String SYMBOLIC_NAME_CHARACTERS =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" +
+ "-_."; // a subset of the characters allowed in DMT URIs
+
+ static final int MAX_ID_LENGTH = 32;
+
+ //----- Private fields -----//
+ private String id;
+ private Date timeStamp;
+ private int cm;
+ private int type;
+
+ private int intData;
+ private float floatData;
+ private String stringData;
+ private boolean booleanData;
+
+
+ //----- Constructors -----//
+ /**
+ * Constructor for a <code>StatusVariable</code> of <code>int</code>
+ * type.
+ *
+ * @param id the identifier of the <code>StatusVariable</code>
+ * @param cm the collection method, one of the <code>CM_</code> constants
+ * @param data the <code>int</code> value of the
+ * <code>StatusVariable</code>
+ * @throws java.lang.IllegalArgumentException if the given <code>id</code>
+ * is not a valid <code>StatusVariable</code> name, or if
+ * <code>cm</code> is not one of the collection method constants
+ * @throws java.lang.NullPointerException if the <code>id</code>
+ * parameter is <code>null</code>
+ */
+ public StatusVariable(String id, int cm, int data) {
+ setCommon(id, cm);
+ type = TYPE_INTEGER;
+ intData = data;
+ }
+
+ /**
+ * Constructor for a <code>StatusVariable</code> of <code>float</code>
+ * type.
+ *
+ * @param id the identifier of the <code>StatusVariable</code>
+ * @param cm the collection method, one of the <code>CM_</code> constants
+ * @param data the <code>float</code> value of the
+ * <code>StatusVariable</code>
+ * @throws java.lang.IllegalArgumentException if the given <code>id</code>
+ * is not a valid <code>StatusVariable</code> name, or if
+ * <code>cm</code> is not one of the collection method constants
+ * @throws java.lang.NullPointerException if the <code>id</code> parameter
+ * is <code>null</code>
+ */
+ public StatusVariable(String id, int cm, float data) {
+ setCommon(id, cm);
+ type = TYPE_FLOAT;
+ floatData = data;
+ }
+
+ /**
+ * Constructor for a <code>StatusVariable</code> of <code>boolean</code>
+ * type.
+ *
+ * @param id the identifier of the <code>StatusVariable</code>
+ * @param cm the collection method, one of the <code>CM_</code> constants
+ * @param data the <code>boolean</code> value of the
+ * <code>StatusVariable</code>
+ * @throws java.lang.IllegalArgumentException if the given <code>id</code>
+ * is not a valid <code>StatusVariable</code> name, or if
+ * <code>cm</code> is not one of the collection method constants
+ * @throws java.lang.NullPointerException if the <code>id</code> parameter
+ * is <code>null</code>
+ */
+ public StatusVariable(String id, int cm, boolean data) {
+ setCommon(id, cm);
+ type = TYPE_BOOLEAN;
+ booleanData = data;
+ }
+
+ /**
+ * Constructor for a <code>StatusVariable</code> of <code>String</code>
+ * type.
+ *
+ * @param id the identifier of the <code>StatusVariable</code>
+ * @param cm the collection method, one of the <code>CM_</code> constants
+ * @param data the <code>String</code> value of the
+ * <code>StatusVariable</code>, can be <code>null</code>
+ * @throws java.lang.IllegalArgumentException if the given <code>id</code>
+ * is not a valid <code>StatusVariable</code> name, or if
+ * <code>cm</code> is not one of the collection method constants
+ * @throws java.lang.NullPointerException if the <code>id</code> parameter
+ * is <code>null</code>
+ */
+ public StatusVariable(String id, int cm, String data) {
+ setCommon(id, cm);
+ type = TYPE_STRING;
+ stringData = data;
+ }
+
+
+ // ----- Public methods -----//
+ /**
+ * Returns the ID of this <code>StatusVariable</code>. The ID is unique
+ * within the scope of a <code>Monitorable</code>.
+ *
+ * @return the ID of this <code>StatusVariable</code>
+ */
+ public String getID() {
+ return id;
+ }
+
+ /**
+ * Returns information on the data type of this <code>StatusVariable</code>.
+ *
+ * @return one of the <code>TYPE_</code> constants indicating the type of
+ * this <code>StatusVariable</code>
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Returns the timestamp associated with the <code>StatusVariable</code>.
+ * The timestamp is stored when the <code>StatusVariable</code> instance is
+ * created, generally during the {@link Monitorable#getStatusVariable}
+ * method call.
+ *
+ * @return the time when the <code>StatusVariable</code> value was
+ * queried, cannot be <code>null</code>
+ *
+ */
+ public Date getTimeStamp() {
+ return timeStamp;
+ }
+
+ /**
+ * Returns the <code>StatusVariable</code> value if its type is
+ * <code>String</code>.
+ *
+ * @return the <code>StatusVariable</code> value as a <code>String</code>
+ * @throws java.lang.IllegalStateException if the type of the
+ * <code>StatusVariable</code> is not <code>String</code>
+ */
+ public String getString() throws IllegalStateException {
+ if (type != TYPE_STRING)
+ throw new IllegalStateException(
+ "This StatusVariable does not contain a String value.");
+ return stringData;
+ }
+
+ /**
+ * Returns the <code>StatusVariable</code> value if its type is
+ * <code>int</code>.
+ *
+ * @return the <code>StatusVariable</code> value as an <code>int</code>
+ * @throws java.lang.IllegalStateException if the type of this
+ * <code>StatusVariable</code> is not <code>int</code>
+ */
+ public int getInteger() throws IllegalStateException {
+ if (type != TYPE_INTEGER)
+ throw new IllegalStateException(
+ "This StatusVariable does not contain an integer value.");
+ return intData;
+ }
+
+ /**
+ * Returns the <code>StatusVariable</code> value if its type is
+ * <code>float</code>.
+ *
+ * @return the <code>StatusVariable</code> value as a <code>float</code>
+ * @throws java.lang.IllegalStateException if the type of this
+ * <code>StatusVariable</code> is not <code>float</code>
+ */
+ public float getFloat() throws IllegalStateException {
+ if (type != TYPE_FLOAT)
+ throw new IllegalStateException(
+ "This StatusVariable does not contain a float value.");
+ return floatData;
+ }
+
+ /**
+ * Returns the <code>StatusVariable</code> value if its type is
+ * <code>boolean</code>.
+ *
+ * @return the <code>StatusVariable</code> value as a <code>boolean</code>
+ * @throws java.lang.IllegalStateException if the type of this
+ * <code>StatusVariable</code> is not <code>boolean</code>
+ */
+ public boolean getBoolean() throws IllegalStateException {
+ if (type != TYPE_BOOLEAN)
+ throw new IllegalStateException(
+ "This StatusVariable does not contain a boolean value.");
+ return booleanData;
+ }
+
+ /**
+ * Returns the collection method of this <code>StatusVariable</code>. See
+ * section 3.3 b) in [ETSI TS 132 403]
+ *
+ * @return one of the <code>CM_</code> constants
+ */
+ public int getCollectionMethod() {
+ return cm;
+ }
+
+ /**
+ * Compares the specified object with this <code>StatusVariable</code>.
+ * Two <code>StatusVariable</code> objects are considered equal if their
+ * full path, collection method and type are identical, and the data
+ * (selected by their type) is equal.
+ *
+ * @param obj the object to compare with this <code>StatusVariable</code>
+ * @return <code>true</code> if the argument represents the same
+ * <code>StatusVariable</code> as this object
+ */
+ public boolean equals(Object obj) {
+ if (!(obj instanceof StatusVariable))
+ return false;
+
+ StatusVariable other = (StatusVariable) obj;
+
+ if (!equals(id, other.id) || cm != other.cm || type != other.type)
+ return false;
+
+ switch (type) {
+ case TYPE_INTEGER: return intData == other.intData;
+ case TYPE_FLOAT: return floatData == other.floatData;
+ case TYPE_STRING: return equals(stringData, other.stringData);
+ case TYPE_BOOLEAN: return booleanData == other.booleanData;
+ }
+
+ return false; // never reached
+ }
+
+ /**
+ * Returns the hash code value for this <code>StatusVariable</code>. The
+ * hash code is calculated based on the full path, collection method and
+ * value of the <code>StatusVariable</code>.
+ *
+ * @return the hash code of this object
+ */
+ public int hashCode() {
+ int hash = hashCode(id) ^ cm;
+
+ switch (type) {
+ case TYPE_INTEGER: return hash ^ intData;
+ case TYPE_FLOAT: return hash ^ hashCode(new Float(floatData));
+ case TYPE_BOOLEAN: return hash ^ hashCode(new Boolean(booleanData));
+ case TYPE_STRING: return hash ^ hashCode(stringData);
+ }
+
+ return 0; // never reached
+ }
+
+ // String representation: StatusVariable(path, cm, time, type, value)
+ /**
+ * Returns a <code>String</code> representation of this
+ * <code>StatusVariable</code>. The returned <code>String</code>
+ * contains the full path, collection method, timestamp, type and value
+ * parameters of the <code>StatusVariable</code> in the following format:
+ * <pre>StatusVariable(<path>, <cm>, <timestamp>, <type>, <value>)</pre>
+ * The collection method identifiers used in the string representation are
+ * "CC", "DER", "GAUGE" and "SI" (without the quotes). The format of the
+ * timestamp is defined by the <code>Date.toString</code> method, while the
+ * type is identified by one of the strings "INTEGER", "FLOAT", "STRING" and
+ * "BOOLEAN". The final field contains the string representation of the
+ * value of the status variable.
+ *
+ * @return the <code>String</code> representation of this
+ * <code>StatusVariable</code>
+ */
+ public String toString() {
+ String cmName = null;
+ switch (cm) {
+ case CM_CC: cmName = "CC"; break;
+ case CM_DER: cmName = "DER"; break;
+ case CM_GAUGE: cmName = "GAUGE"; break;
+ case CM_SI: cmName = "SI"; break;
+ }
+
+ String beg = "StatusVariable(" + id + ", " + cmName + ", "
+ + timeStamp + ", ";
+
+ switch (type) {
+ case TYPE_INTEGER: return beg + "INTEGER, " + intData + ")";
+ case TYPE_FLOAT: return beg + "FLOAT, " + floatData + ")";
+ case TYPE_STRING: return beg + "STRING, " + stringData + ")";
+ case TYPE_BOOLEAN: return beg + "BOOLEAN, " + booleanData + ")";
+ }
+
+ return null; // never reached
+ }
+
+ //----- Private methods -----//
+
+ private void setCommon(String id, int cm)
+ throws IllegalArgumentException, NullPointerException {
+ checkId(id, "StatusVariable ID");
+
+ if (cm != CM_CC && cm != CM_DER && cm != CM_GAUGE && cm != CM_SI)
+ throw new IllegalArgumentException(
+ "Unknown data collection method constant '" + cm + "'.");
+
+ this.id = id;
+ this.cm = cm;
+ timeStamp = new Date();
+ }
+
+
+ private boolean equals(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+
+ private int hashCode(Object o) {
+ return o == null ? 0 : o.hashCode();
+ }
+
+ private static void checkId(String id, String idName)
+ throws IllegalArgumentException, NullPointerException {
+ if (id == null)
+ throw new NullPointerException(idName + " is null.");
+ if(id.length() == 0)
+ throw new IllegalArgumentException(idName + " is empty.");
+
+ byte[] nameBytes;
+ try {
+ nameBytes = id.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // never happens, "UTF-8" must always be supported
+ throw new IllegalStateException(e.getMessage());
+ }
+ if(nameBytes.length > MAX_ID_LENGTH)
+ throw new IllegalArgumentException(idName + " is too long " +
+ "(over " + MAX_ID_LENGTH + " bytes in UTF-8 encoding).");
+
+ if(id.equals(".") || id.equals(".."))
+ throw new IllegalArgumentException(idName + " is invalid.");
+
+ if(!containsValidChars(id))
+ throw new IllegalArgumentException(idName +
+ " contains invalid characters.");
+ }
+
+ private static boolean containsValidChars(String name) {
+ char[] chars = name.toCharArray();
+ for(int i = 0; i < chars.length; i++)
+ if(SYMBOLIC_NAME_CHARACTERS.indexOf(chars[i]) == -1)
+ return false;
+
+ return true;
+ }
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/package.html?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/package.html (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/package.html Mon Jun 2 04:39:58 2008
@@ -0,0 +1,10 @@
+<!-- $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/package.html,v 1.4 2006/07/12 21:07:13 hargrave Exp $ -->
+<BODY>
+<p>Monitor Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the <TT>Import-Package</TT> header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.monitor; version=1.0
+</pre>
+</BODY>
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/packageinfo?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/packageinfo (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/monitor/packageinfo Mon Jun 2 04:39:58 2008
@@ -0,0 +1 @@
+version 1.0
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/BackingStoreException.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/BackingStoreException.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/BackingStoreException.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/BackingStoreException.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,83 @@
+/*
+ * $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.
+ *
+ * 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.prefs;
+
+/**
+ * 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 $
+ */
+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.
+ */
+ public BackingStoreException(String s) {
+ super(s);
+ this.cause = null;
+ }
+
+ /**
+ * Constructs a <code>BackingStoreException</code> with the specified detail
+ * message.
+ *
+ * @param s 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;
+ }
+
+ /**
+ * 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.1
+ */
+ public Throwable getCause() {
+ return cause;
+ }
+
+ /**
+ * 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.1
+ */
+ public Throwable initCause(Throwable cause) {
+ throw new IllegalStateException();
+ }
+
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/Preferences.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/Preferences.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/Preferences.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/Preferences.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,702 @@
+/*
+ * $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.
+ *
+ * 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.prefs;
+
+/**
+ * A node in a hierarchical collection of preference data.
+ *
+ * <p>
+ * This interface allows applications to store and retrieve user and system
+ * preference data. This data is stored persistently in an
+ * implementation-dependent backing store. Typical implementations include flat
+ * files, OS-specific registries, directory servers and SQL databases.
+ *
+ * <p>
+ * For each bundle, there is a separate tree of nodes for each user, and one for
+ * system preferences. The precise description of "user" and "system" will vary
+ * from one bundle to another. Typical information stored in the user preference
+ * tree might include font choice, and color choice for a bundle which interacts
+ * with the user via a servlet. Typical information stored in the system
+ * preference tree might include installation data, or things like high score
+ * information for a game program.
+ *
+ * <p>
+ * Nodes in a preference tree are named in a similar fashion to directories in a
+ * hierarchical file system. Every node in a preference tree has a <i>node name
+ * </i> (which is not necessarily unique), a unique <i>absolute path name </i>,
+ * and a path name <i>relative </i> to each ancestor including itself.
+ *
+ * <p>
+ * The root node has a node name of the empty <code>String</code> object ("").
+ * Every other node has an arbitrary node name, specified at the time it is
+ * created. The only restrictions on this name are that it cannot be the empty
+ * string, and it cannot contain the slash character ('/').
+ *
+ * <p>
+ * The root node has an absolute path name of <code>"/"</code>. Children of the
+ * root node have absolute path names of <code>"/" + </code> <i><node name>
+ * </i>. All other nodes have absolute path names of <i><parent's absolute
+ * path name> </i> <code> + "/" + </code> <i><node name> </i>. Note that
+ * all absolute path names begin with the slash character.
+ *
+ * <p>
+ * A node <i>n </i>'s path name relative to its ancestor <i>a </i> is simply the
+ * string that must be appended to <i>a </i>'s absolute path name in order to
+ * form <i>n </i>'s absolute path name, with the initial slash character (if
+ * present) removed. Note that:
+ * <ul>
+ * <li>No relative path names begin with the slash character.
+ * <li>Every node's path name relative to itself is the empty string.
+ * <li>Every node's path name relative to its parent is its node name (except
+ * for the root node, which does not have a parent).
+ * <li>Every node's path name relative to the root is its absolute path name
+ * with the initial slash character removed.
+ * </ul>
+ *
+ * <p>
+ * Note finally that:
+ * <ul>
+ * <li>No path name contains multiple consecutive slash characters.
+ * <li>No path name with the exception of the root's absolute path name end in
+ * the slash character.
+ * <li>Any string that conforms to these two rules is a valid path name.
+ * </ul>
+ *
+ * <p>
+ * Each <code>Preference</code> node has zero or more properties associated with
+ * it, where a property consists of a name and a value. The bundle writer is
+ * free to choose any appropriate names for properties. Their values can be of
+ * type <code>String</code>,<code>long</code>,<code>int</code>,<code>boolean</code>,
+ * <code>byte[]</code>,<code>float</code>, or <code>double</code> but they can
+ * always be accessed as if they were <code>String</code> objects.
+ *
+ * <p>
+ * All node name and property name comparisons are case-sensitive.
+ *
+ * <p>
+ * All of the methods that modify preference data are permitted to operate
+ * asynchronously; they may return immediately, and changes will eventually
+ * propagate to the persistent backing store, with an implementation-dependent
+ * delay. The <code>flush</code> method may be used to synchronously force updates
+ * to the backing store.
+ *
+ * <p>
+ * Implementations must automatically attempt to flush to the backing store any
+ * pending updates for a bundle's preferences when the bundle is stopped or
+ * otherwise ungets the Preferences Service.
+ *
+ * <p>
+ * The methods in this class may be invoked concurrently by multiple threads in
+ * a single Java Virtual Machine (JVM) without the need for external
+ * synchronization, and the results will be equivalent to some serial execution.
+ * If this class is used concurrently <i>by multiple JVMs </i> that store their
+ * preference data in the same backing store, the data store will not be
+ * corrupted, but no other guarantees are made concerning the consistency of the
+ * preference data.
+ *
+ *
+ * @version $Revision: 1.11 $
+ */
+public interface Preferences {
+ /**
+ * Associates the specified value with the specified key in this node.
+ *
+ * @param key key with which the specified value is to be associated.
+ * @param value value to be associated with the specified key.
+ * @throws NullPointerException if <code>key</code> or <code>value</code> is
+ * <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ */
+ public void put(String key, String value);
+
+ /**
+ * Returns the value associated with the specified <code>key</code> in this
+ * node. Returns the specified default if there is no value associated with
+ * the <code>key</code>, or the backing store is inaccessible.
+ *
+ * @param key key whose associated value is to be returned.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the backing store is
+ * inaccessible.
+ * @return the value associated with <code>key</code>, or <code>def</code> if
+ * no value is associated with <code>key</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>. (A
+ * <code>null</code> default <i>is </i> permitted.)
+ */
+ public String get(String key, String def);
+
+ /**
+ * Removes the value associated with the specified <code>key</code> in this
+ * node, if any.
+ *
+ * @param key key whose mapping is to be removed from this node.
+ * @see #get(String,String)
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ */
+ public void remove(String key);
+
+ /**
+ * Removes all of the properties (key-value associations) in this node. This
+ * call has no effect on any descendants of this node.
+ *
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #remove(String)
+ */
+ public void clear() throws BackingStoreException;
+
+ /**
+ * Associates a <code>String</code> object representing the specified
+ * <code>int</code> value with the specified <code>key</code> in this node. The
+ * associated string is the one that would be returned if the <code>int</code>
+ * value were passed to <code>Integer.toString(int)</code>. This method is
+ * intended for use in conjunction with {@link #getInt} method.
+ *
+ * <p>
+ * Implementor's note: it is <i>not </i> necessary that the property value
+ * be represented by a <code>String</code> object in the backing store. If the
+ * backing store supports integer values, it is not unreasonable to use
+ * them. This implementation detail is not visible through the
+ * <code>Preferences</code> API, which allows the value to be read as an
+ * <code>int</code> (with <code>getInt</code> or a <code>String</code> (with
+ * <code>get</code>) type.
+ *
+ * @param key key with which the string form of value is to be associated.
+ * @param value <code>value</code> whose string form is to be associated with
+ * <code>key</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #getInt(String,int)
+ */
+ public void putInt(String key, int value);
+
+ /**
+ * Returns the <code>int</code> value represented by the <code>String</code>
+ * object associated with the specified <code>key</code> in this node. The
+ * <code>String</code> object is converted to an <code>int</code> as by
+ * <code>Integer.parseInt(String)</code>. Returns the specified default if
+ * there is no value associated with the <code>key</code>, the backing store
+ * is inaccessible, or if <code>Integer.parseInt(String)</code> would throw a
+ * <code>NumberFormatException</code> if the associated <code>value</code> were
+ * passed. This method is intended for use in conjunction with the
+ * {@link #putInt} method.
+ *
+ * @param key key whose associated value is to be returned as an
+ * <code>int</code>.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the associated value
+ * cannot be interpreted as an <code>int</code> or the backing store is
+ * inaccessible.
+ * @return the <code>int</code> value represented by the <code>String</code>
+ * object associated with <code>key</code> in this node, or
+ * <code>def</code> if the associated value does not exist or cannot
+ * be interpreted as an <code>int</code> type.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #putInt(String,int)
+ * @see #get(String,String)
+ */
+ public int getInt(String key, int def);
+
+ /**
+ * Associates a <code>String</code> object representing the specified
+ * <code>long</code> value with the specified <code>key</code> in this node. The
+ * associated <code>String</code> object is the one that would be returned if
+ * the <code>long</code> value were passed to <code>Long.toString(long)</code>.
+ * This method is intended for use in conjunction with the {@link #getLong}
+ * method.
+ *
+ * <p>
+ * Implementor's note: it is <i>not </i> necessary that the <code>value</code>
+ * be represented by a <code>String</code> type in the backing store. If the
+ * backing store supports <code>long</code> values, it is not unreasonable to
+ * use them. This implementation detail is not visible through the <code>
+ * Preferences</code> API, which allows the value to be read as a
+ * <code>long</code> (with <code>getLong</code> or a <code>String</code> (with
+ * <code>get</code>) type.
+ *
+ * @param key <code>key</code> with which the string form of <code>value</code>
+ * is to be associated.
+ * @param value <code>value</code> whose string form is to be associated with
+ * <code>key</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #getLong(String,long)
+ */
+ public void putLong(String key, long value);
+
+ /**
+ * Returns the <code>long</code> value represented by the <code>String</code>
+ * object associated with the specified <code>key</code> in this node. The
+ * <code>String</code> object is converted to a <code>long</code> as by
+ * <code>Long.parseLong(String)</code>. Returns the specified default if
+ * there is no value associated with the <code>key</code>, the backing store
+ * is inaccessible, or if <code>Long.parseLong(String)</code> would throw a
+ * <code>NumberFormatException</code> if the associated <code>value</code> were
+ * passed. This method is intended for use in conjunction with the
+ * {@link #putLong} method.
+ *
+ * @param key <code>key</code> whose associated value is to be returned as a
+ * <code>long</code> value.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the associated value
+ * cannot be interpreted as a <code>long</code> type or the backing
+ * store is inaccessible.
+ * @return the <code>long</code> value represented by the <code>String</code>
+ * object associated with <code>key</code> in this node, or
+ * <code>def</code> if the associated value does not exist or cannot
+ * be interpreted as a <code>long</code> type.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #putLong(String,long)
+ * @see #get(String,String)
+ */
+ public long getLong(String key, long def);
+
+ /**
+ * Associates a <code>String</code> object representing the specified
+ * <code>boolean</code> value with the specified key in this node. The
+ * associated string is "true" if the value is <code>true</code>, and "false"
+ * if it is <code>false</code>. This method is intended for use in
+ * conjunction with the {@link #getBoolean} method.
+ *
+ * <p>
+ * Implementor's note: it is <i>not </i> necessary that the value be
+ * represented by a string in the backing store. If the backing store
+ * supports <code>boolean</code> values, it is not unreasonable to use them.
+ * This implementation detail is not visible through the <code>Preferences
+ * </code> API, which allows the value to be read as a <code>boolean</code>
+ * (with <code>getBoolean</code>) or a <code>String</code> (with <code>get</code>)
+ * type.
+ *
+ * @param key <code>key</code> with which the string form of value is to be
+ * associated.
+ * @param value value whose string form is to be associated with
+ * <code>key</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #getBoolean(String,boolean)
+ * @see #get(String,String)
+ */
+ public void putBoolean(String key, boolean value);
+
+ /**
+ * Returns the <code>boolean</code> value represented by the <code>String</code>
+ * object associated with the specified <code>key</code> in this node. Valid
+ * strings are "true", which represents <code>true</code>, and "false", which
+ * represents <code>false</code>. Case is ignored, so, for example, "TRUE"
+ * and "False" are also valid. This method is intended for use in
+ * conjunction with the {@link #putBoolean} method.
+ *
+ * <p>
+ * Returns the specified default if there is no value associated with the
+ * <code>key</code>, the backing store is inaccessible, or if the associated
+ * value is something other than "true" or "false", ignoring case.
+ *
+ * @param key <code>key</code> whose associated value is to be returned as a
+ * <code>boolean</code>.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the associated value
+ * cannot be interpreted as a <code>boolean</code> or the backing store
+ * is inaccessible.
+ * @return the <code>boolean</code> value represented by the <code>String</code>
+ * object associated with <code>key</code> in this node, or
+ * <code>null</code> if the associated value does not exist or cannot
+ * be interpreted as a <code>boolean</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #get(String,String)
+ * @see #putBoolean(String,boolean)
+ */
+ public boolean getBoolean(String key, boolean def);
+
+ /**
+ * Associates a <code>String</code> object representing the specified
+ * <code>float</code> value with the specified <code>key</code> in this node.
+ * The associated <code>String</code> object is the one that would be returned
+ * if the <code>float</code> value were passed to
+ * <code>Float.toString(float)</code>. This method is intended for use in
+ * conjunction with the {@link #getFloat} method.
+ *
+ * <p>
+ * Implementor's note: it is <i>not </i> necessary that the value be
+ * represented by a string in the backing store. If the backing store
+ * supports <code>float</code> values, it is not unreasonable to use them.
+ * This implementation detail is not visible through the <code>Preferences
+ * </code> API, which allows the value to be read as a <code>float</code> (with
+ * <code>getFloat</code>) or a <code>String</code> (with <code>get</code>) type.
+ *
+ * @param key <code>key</code> with which the string form of value is to be
+ * associated.
+ * @param value value whose string form is to be associated with
+ * <code>key</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #getFloat(String,float)
+ */
+ public void putFloat(String key, float value);
+
+ /**
+ * Returns the float <code>value</code> represented by the <code>String</code>
+ * object associated with the specified <code>key</code> in this node. The
+ * <code>String</code> object is converted to a <code>float</code> value as by
+ * <code>Float.parseFloat(String)</code>. Returns the specified default if
+ * there is no value associated with the <code>key</code>, the backing store
+ * is inaccessible, or if <code>Float.parseFloat(String)</code> would throw a
+ * <code>NumberFormatException</code> if the associated value were passed.
+ * This method is intended for use in conjunction with the {@link #putFloat}
+ * method.
+ *
+ * @param key <code>key</code> whose associated value is to be returned as a
+ * <code>float</code> value.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the associated value
+ * cannot be interpreted as a <code>float</code> type or the backing
+ * store is inaccessible.
+ * @return the <code>float</code> value represented by the string associated
+ * with <code>key</code> in this node, or <code>def</code> if the
+ * associated value does not exist or cannot be interpreted as a
+ * <code>float</code> type.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @see #putFloat(String,float)
+ * @see #get(String,String)
+ */
+ public float getFloat(String key, float def);
+
+ /**
+ * Associates a <code>String</code> object representing the specified
+ * <code>double</code> value with the specified <code>key</code> in this node.
+ * The associated <code>String</code> object is the one that would be returned
+ * if the <code>double</code> value were passed to
+ * <code>Double.toString(double)</code>. This method is intended for use in
+ * conjunction with the {@link #getDouble} method
+ *
+ * <p>
+ * Implementor's note: it is <i>not </i> necessary that the value be
+ * represented by a string in the backing store. If the backing store
+ * supports <code>double</code> values, it is not unreasonable to use them.
+ * This implementation detail is not visible through the <code>Preferences
+ * </code> API, which allows the value to be read as a <code>double</code> (with
+ * <code>getDouble</code>) or a <code>String</code> (with <code>get</code>)
+ * type.
+ *
+ * @param key <code>key</code> with which the string form of value is to be
+ * associated.
+ * @param value value whose string form is to be associated with
+ * <code>key</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #getDouble(String,double)
+ */
+ public void putDouble(String key, double value);
+
+ /**
+ * Returns the <code>double</code> value represented by the <code>String</code>
+ * object associated with the specified <code>key</code> in this node. The
+ * <code>String</code> object is converted to a <code>double</code> value as by
+ * <code>Double.parseDouble(String)</code>. Returns the specified default if
+ * there is no value associated with the <code>key</code>, the backing store
+ * is inaccessible, or if <code>Double.parseDouble(String)</code> would throw
+ * a <code>NumberFormatException</code> if the associated value were passed.
+ * This method is intended for use in conjunction with the
+ * {@link #putDouble} method.
+ *
+ * @param key <code>key</code> whose associated value is to be returned as a
+ * <code>double</code> value.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the associated value
+ * cannot be interpreted as a <code>double</code> type or the backing
+ * store is inaccessible.
+ * @return the <code>double</code> value represented by the <code>String</code>
+ * object associated with <code>key</code> in this node, or
+ * <code>def</code> if the associated value does not exist or cannot
+ * be interpreted as a <code>double</code> type.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the the {@link #removeNode()} method.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>.
+ * @see #putDouble(String,double)
+ * @see #get(String,String)
+ */
+ public double getDouble(String key, double def);
+
+ /**
+ * Associates a <code>String</code> object representing the specified
+ * <code>byte[]</code> with the specified <code>key</code> in this node. The
+ * associated <code>String</code> object the <i>Base64 </i> encoding of the
+ * <code>byte[]</code>, as defined in <a
+ * href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 </a>, Section 6.8,
+ * with one minor change: the string will consist solely of characters from
+ * the <i>Base64 Alphabet </i>; it will not contain any newline characters.
+ * This method is intended for use in conjunction with the
+ * {@link #getByteArray} method.
+ *
+ * <p>
+ * Implementor's note: it is <i>not </i> necessary that the value be
+ * represented by a <code>String</code> type in the backing store. If the
+ * backing store supports <code>byte[]</code> values, it is not unreasonable
+ * to use them. This implementation detail is not visible through the <code>
+ * Preferences</code> API, which allows the value to be read as an a
+ * <code>byte[]</code> object (with <code>getByteArray</code>) or a
+ * <code>String</code> object (with <code>get</code>).
+ *
+ * @param key <code>key</code> with which the string form of <code>value</code>
+ * is to be associated.
+ * @param value <code>value</code> whose string form is to be associated with
+ * <code>key</code>.
+ * @throws NullPointerException if <code>key</code> or <code>value</code> is
+ * <code>null</code>.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #getByteArray(String,byte[])
+ * @see #get(String,String)
+ */
+ public void putByteArray(String key, byte[] value);
+
+ /**
+ * Returns the <code>byte[]</code> value represented by the <code>String</code>
+ * object associated with the specified <code>key</code> in this node. Valid
+ * <code>String</code> objects are <i>Base64 </i> encoded binary data, as
+ * defined in <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 </a>,
+ * Section 6.8, with one minor change: the string must consist solely of
+ * characters from the <i>Base64 Alphabet </i>; no newline characters or
+ * extraneous characters are permitted. This method is intended for use in
+ * conjunction with the {@link #putByteArray} method.
+ *
+ * <p>
+ * Returns the specified default if there is no value associated with the
+ * <code>key</code>, the backing store is inaccessible, or if the associated
+ * value is not a valid Base64 encoded byte array (as defined above).
+ *
+ * @param key <code>key</code> whose associated value is to be returned as a
+ * <code>byte[]</code> object.
+ * @param def the value to be returned in the event that this node has no
+ * value associated with <code>key</code> or the associated value
+ * cannot be interpreted as a <code>byte[]</code> type, or the backing
+ * store is inaccessible.
+ * @return the <code>byte[]</code> value represented by the <code>String</code>
+ * object associated with <code>key</code> in this node, or
+ * <code>def</code> if the associated value does not exist or cannot
+ * be interpreted as a <code>byte[]</code>.
+ * @throws NullPointerException if <code>key</code> is <code>null</code>. (A
+ * <code>null</code> value for <code>def</code> <i>is </i> permitted.)
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #get(String,String)
+ * @see #putByteArray(String,byte[])
+ */
+ public byte[] getByteArray(String key, byte[] def);
+
+ /**
+ * Returns all of the keys that have an associated value in this node. (The
+ * returned array will be of size zero if this node has no preferences and
+ * not <code>null</code>!)
+ *
+ * @return an array of the keys that have an associated value in this node.
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ */
+ public String[] keys() throws BackingStoreException;
+
+ /**
+ * Returns the names of the children of this node. (The returned array will
+ * be of size zero if this node has no children and not <code>null</code>!)
+ *
+ * @return the names of the children of this node.
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ */
+ public String[] childrenNames() throws BackingStoreException;
+
+ /**
+ * Returns the parent of this node, or <code>null</code> if this is the root.
+ *
+ * @return the parent of this node.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ */
+ public Preferences parent();
+
+ /**
+ * Returns a named <code>Preferences</code> object (node), creating it and any
+ * of its ancestors if they do not already exist. Accepts a relative or
+ * absolute pathname. Absolute pathnames (which begin with <code>'/'</code>)
+ * are interpreted relative to the root of this node. Relative pathnames
+ * (which begin with any character other than <code>'/'</code>) are
+ * interpreted relative to this node itself. The empty string (<code>""</code>)
+ * is a valid relative pathname, referring to this node itself.
+ *
+ * <p>
+ * If the returned node did not exist prior to this call, this node and any
+ * ancestors that were created by this call are not guaranteed to become
+ * persistent until the <code>flush</code> method is called on the returned
+ * node (or one of its descendants).
+ *
+ * @param pathName the path name of the <code>Preferences</code> object to
+ * return.
+ * @return the specified <code>Preferences</code> object.
+ * @throws IllegalArgumentException if the path name is invalid.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @throws NullPointerException if path name is <code>null</code>.
+ * @see #flush()
+ */
+ public Preferences node(String pathName);
+
+ /**
+ * Returns true if the named node exists. Accepts a relative or absolute
+ * pathname. Absolute pathnames (which begin with <code>'/'</code>) are
+ * interpreted relative to the root of this node. Relative pathnames (which
+ * begin with any character other than <code>'/'</code>) are interpreted
+ * relative to this node itself. The pathname <code>""</code> is valid, and
+ * refers to this node itself.
+ *
+ * <p>
+ * If this node (or an ancestor) has already been removed with the
+ * {@link #removeNode()} method, it <i>is </i> legal to invoke this method,
+ * but only with the pathname <code>""</code>; the invocation will return
+ * <code>false</code>. Thus, the idiom <code>p.nodeExists("")</code> may be
+ * used to test whether <code>p</code> has been removed.
+ *
+ * @param pathName the path name of the node whose existence is to be
+ * checked.
+ * @return true if the specified node exists.
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method and
+ * <code>pathname</code> is not the empty string (<code>""</code>).
+ * @throws IllegalArgumentException if the path name is invalid (i.e., it
+ * contains multiple consecutive slash characters, or ends with a
+ * slash character and is more than one character long).
+ */
+ public boolean nodeExists(String pathName)
+ throws BackingStoreException;
+
+ /**
+ * Removes this node and all of its descendants, invalidating any properties
+ * contained in the removed nodes. Once a node has been removed, attempting
+ * any method other than <code>name()</code>,<code>absolutePath()</code> or
+ * <code>nodeExists("")</code> on the corresponding <code>Preferences</code>
+ * instance will fail with an <code>IllegalStateException</code>. (The
+ * methods defined on <code>Object</code> can still be invoked on a node after
+ * it has been removed; they will not throw <code>IllegalStateException</code>.)
+ *
+ * <p>
+ * The removal is not guaranteed to be persistent until the <code>flush</code>
+ * method is called on the parent of this node.
+ *
+ * @throws IllegalStateException if this node (or an ancestor) has already
+ * been removed with the {@link #removeNode()} method.
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @see #flush()
+ */
+ public void removeNode() throws BackingStoreException;
+
+ /**
+ * Returns this node's name, relative to its parent.
+ *
+ * @return this node's name, relative to its parent.
+ */
+ public String name();
+
+ /**
+ * Returns this node's absolute path name. Note that:
+ * <ul>
+ * <li>Root node - The path name of the root node is <code>"/"</code>.
+ * <li>Slash at end - Path names other than that of the root node may not
+ * end in slash (<code>'/'</code>).
+ * <li>Unusual names -<code>"."</code> and <code>".."</code> have <i>no </i>
+ * special significance in path names.
+ * <li>Illegal names - The only illegal path names are those that contain
+ * multiple consecutive slashes, or that end in slash and are not the root.
+ * </ul>
+ *
+ * @return this node's absolute path name.
+ */
+ public String absolutePath();
+
+ /**
+ * Forces any changes in the contents of this node and its descendants to
+ * the persistent store.
+ *
+ * <p>
+ * Once this method returns successfully, it is safe to assume that all
+ * changes made in the subtree rooted at this node prior to the method
+ * invocation have become permanent.
+ *
+ * <p>
+ * Implementations are free to flush changes into the persistent store at
+ * any time. They do not need to wait for this method to be called.
+ *
+ * <p>
+ * When a flush occurs on a newly created node, it is made persistent, as
+ * are any ancestors (and descendants) that have yet to be made persistent.
+ * Note however that any properties value changes in ancestors are <i>not
+ * </i> guaranteed to be made persistent.
+ *
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #sync()
+ */
+ public void flush() throws BackingStoreException;
+
+ /**
+ * Ensures that future reads from this node and its descendants reflect any
+ * changes that were committed to the persistent store (from any VM) prior
+ * to the <code>sync</code> invocation. As a side-effect, forces any changes
+ * in the contents of this node and its descendants to the persistent store,
+ * as if the <code>flush</code> method had been invoked on this node.
+ *
+ * @throws BackingStoreException if this operation cannot be completed due
+ * to a failure in the backing store, or inability to communicate
+ * with it.
+ * @throws IllegalStateException if this node (or an ancestor) has been
+ * removed with the {@link #removeNode()} method.
+ * @see #flush()
+ */
+ public void sync() throws BackingStoreException;
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/PreferencesService.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/PreferencesService.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/PreferencesService.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/PreferencesService.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,56 @@
+/*
+ * $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.
+ *
+ * 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.prefs;
+
+/**
+ * The Preferences Service.
+ *
+ * <p>
+ * Each bundle using this service has its own set of preference trees: one for
+ * system preferences, and one for each user.
+ *
+ * <p>
+ * A <code>PreferencesService</code> object is specific to the bundle which
+ * obtained it from the service registry. If a bundle wishes to allow another
+ * bundle to access its preferences, it should pass its
+ * <code>PreferencesService</code> object to that bundle.
+ *
+ */
+public interface PreferencesService {
+ /**
+ * Returns the root system node for the calling bundle.
+ *
+ * @return The root system node for the calling bundle.
+ */
+ public Preferences getSystemPreferences();
+
+ /**
+ * Returns the root node for the specified user and the calling bundle.
+ *
+ * @param name The user for which to return the preference root node.
+ * @return The root node for the specified user and the calling bundle.
+ */
+ public Preferences getUserPreferences(String name);
+
+ /**
+ * Returns the names of users for which node trees exist.
+ *
+ * @return The names of users for which node trees exist.
+ */
+ public String[] getUsers();
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/package.html?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/package.html (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/package.html Mon Jun 2 04:39:58 2008
@@ -0,0 +1 @@
+<!-- $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/package.html,v 1.4 2006/07/12 21:06:58 hargrave Exp $ -->
<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
</pre>
</BODY>
\ No newline at end of file
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/packageinfo?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/packageinfo (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/service/prefs/packageinfo Mon Jun 2 04:39:58 2008
@@ -0,0 +1 @@
+version 1.1
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMEICondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMEICondition.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMEICondition.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMEICondition.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,85 @@
+/*
+ * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMEICondition.java,v 1.20 2006/07/12 21:21:32 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 2006). 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.gsm;
+
+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 IMEI condition. Instances of this class contain a
+ * string value that is matched against the IMEI of the device.
+ */
+public class IMEICondition {
+ private static final String ORG_OSGI_UTIL_GSM_IMEI = "org.osgi.util.gsm.imei";
+ private static final String imei ;
+
+ static {
+ imei = (String)
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
+ }
+ }
+ );
+ }
+
+ private IMEICondition() {
+ }
+
+ /**
+ * Creates an IMEICondition 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.
+ */
+ public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
+ if (bundle==null) throw new NullPointerException("bundle");
+ String imei = conditionInfo.getArgs()[0];
+ if (imei.length()>15) 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);
+ }
+ 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);
+ }
+ 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.");
+ return Condition.FALSE;
+ }
+ return IMEICondition.imei.startsWith(imei)?Condition.TRUE:Condition.FALSE;
+ }
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMSICondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMSICondition.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMSICondition.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/IMSICondition.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,84 @@
+/*
+ * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMSICondition.java,v 1.22 2006/07/12 21:21:32 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 2006). 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.gsm;
+
+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 IMSI condition. Instances of this class contain a
+ * string value that is matched against the IMSI of the subscriber.
+ */
+public class IMSICondition {
+ private static final String ORG_OSGI_UTIL_GSM_IMSI = "org.osgi.util.gsm.imsi";
+ private static final String imsi;
+
+ static {
+ imsi = (String)
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
+ }
+ }
+ );
+ }
+
+ private IMSICondition() {}
+
+ /**
+ * 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.
+ */
+ public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
+ if (bundle==null) throw new NullPointerException("bundle");
+ if (conditionInfo==null) throw new NullPointerException("conditionInfo");
+ String imsi = conditionInfo.getArgs()[0];
+ if (imsi.length()>15) 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);
+ }
+ 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);
+ }
+ 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.");
+ return Condition.FALSE;
+ }
+ return (IMSICondition.imsi.startsWith(imsi))?Condition.TRUE:Condition.FALSE;
+ }
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/package.html?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/package.html (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/package.html Mon Jun 2 04:39:58 2008
@@ -0,0 +1,10 @@
+<!-- $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/package.html,v 1.2 2006/07/12 21:06:54 hargrave Exp $ -->
+<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
+</pre>
+</BODY>
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/packageinfo?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/packageinfo (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/gsm/packageinfo Mon Jun 2 04:39:58 2008
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/UserPromptCondition.java?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/UserPromptCondition.java (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/UserPromptCondition.java Mon Jun 2 04:39:58 2008
@@ -0,0 +1,256 @@
+/*
+ * $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.
+ *
+ * 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.mobile;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionInfo;
+
+/**
+ * Class representing a user prompt condition. Instances of this class hold two
+ * values: a prompt string that is to be displayed to the user and the
+ * permission level string according to MIDP2.0 (oneshot, session, blanket).
+ *
+ */
+public class UserPromptCondition implements Condition {
+
+ /*
+ * NOTE: An implementor may also choose to replace this class in
+ * their distribution with a class that directly interfaces with the
+ * policy implementation. This replacement class MUST NOT alter the
+ * public/protected signature of this class.
+ */
+ // this will need to be set by the implementation class
+ static Method factory = null;
+ Condition realUserPromptCondition;
+
+ private final Bundle bundle;
+ private final String levels;
+ private final String defaultLevel;
+ private final String catalogName;
+ private final String message;
+
+ /**
+ * Returns a UserPromptCondition object with the given prompt string and permission
+ * level. The user should be given choice as to what level of permission is
+ * given. Thus, the lifetime of the permission is controlled by the user.
+ *
+ * @param bundle the bundle to ask about.
+ * @param conditionInfo the conditionInfo containing the construction information. Its
+ * {@link ConditionInfo#getArgs()} method should return a String array with 4
+ * strings in it:
+ * <ol start="0">
+ * <li>the possible permission levels. This is a comma-separated list that can contain
+ * following strings: ONESHOT SESSION BLANKET. The order is not important. This
+ * parameter is case-insensitive.
+ * </li>
+ * <li>the default permission level, one chosen from the possible permission levels. If
+ * it is an empty string, then there is no default. This parameter
+ * is case-insensitive.</li>
+ * <li>the message catalog base name. It will be loaded by a {@link java.util.ResourceBundle},
+ * or equivalent
+ * from an exporting OSGi Bundle. Thus, if the catalogName is "com.provider.messages.userprompt",
+ * then there should be an OSGi Bundle exporting the "com.provider.messages" package, and inside
+ * it files like "userprompt_en_US.properties".</li>
+ * <li>textual description of the condition, to be displayed to the user. If
+ * it starts with a '%' sign, then the message is looked up from the catalog specified previously.
+ * The key is the rest of the string after the '%' sign.</li>
+ * </ol>
+ * @return The requested UserPromptCondition.
+ * @throws IllegalArgumentException if the parameters are malformed.
+ * @throws NullPointerException if one of the parameters is <code>null</code>.
+ */
+ public static Condition getCondition(Bundle bundle,ConditionInfo conditionInfo)
+ {
+ String[] args = conditionInfo.getArgs();
+ if (args==null) throw new NullPointerException("args");
+ if (args.length!=4) throw new IllegalArgumentException("args.length=="+args.length+" (should be 4)");
+ if (bundle==null) throw new NullPointerException("bundle");
+ String levels = args[0];
+ String defaultLevel = args[1];
+ String catalogName = args[2];
+ String message = args[3];
+ if (levels==null) throw new NullPointerException("levels");
+ if (defaultLevel==null) throw new NullPointerException("defaultLevel");
+ if (catalogName==null) throw new NullPointerException("catalogName");
+ if (message==null) throw new NullPointerException("message");
+
+ if (factory==null) {
+ // the bundle implementing the UserPromptCondition has not started yet.
+ // Do wrapping magick.
+ return new UserPromptCondition(bundle,levels,defaultLevel,catalogName,message);
+ } else {
+ // there is already a factory, no need to do any wrapping magic
+ try {
+ return (Condition) factory.invoke(null,new Object[]{bundle,levels,defaultLevel,catalogName,message});
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ Throwable original = e.getTargetException();
+ if (original instanceof NullPointerException) throw (NullPointerException) original;
+ if (original instanceof IllegalArgumentException) throw (IllegalArgumentException) original;
+ e.printStackTrace();
+ }
+ // the factory method is not working, fallback behavior:
+ factory = null;
+ return new UserPromptCondition(bundle,levels,defaultLevel,catalogName,message);
+ }
+ }
+
+ /**
+ * Instances of the UserPromptCondition are simply store the construction parameters
+ * until a "real" UserPromptCondition is registered in setFactory(). At that point, it
+ * will delegate all calls there.
+ * @param unused this parameter is here so that ConditionalPermissionAdmin would not
+ * use this as the constructor instead of the getInstance
+ * @param bundle
+ * @param levels
+ * @param defaultLevel
+ * @param catalogName
+ * @param message
+ */
+ private UserPromptCondition(Bundle bundle,String levels,String defaultLevel,String catalogName,String message) {
+ this.bundle=bundle;
+ this.levels=levels;
+ this.defaultLevel=defaultLevel;
+ this.catalogName=catalogName;
+ this.message=message;
+ }
+
+ /**
+ * Check if a factory is registered, and if yes, create userprompt to delegate calls to.
+ */
+ private void lookForImplementation() {
+ if ((realUserPromptCondition==null)&&(factory!=null)) {
+ try {
+ realUserPromptCondition = (Condition) factory.invoke(null,new Object[]{bundle,levels,defaultLevel,catalogName,message});
+ return;
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ // only if the factory call fails with some invocation exception
+ factory = null;
+ }
+ }
+
+ /**
+ * Checks if the {@link #isSatisfied()} method needs to prompt the user, thus cannot
+ * give results instantly.
+ * This depends on the permission level given in
+ * {@link UserPromptCondition#getCondition(Bundle, ConditionInfo)}.
+ * <ul>
+ * <li>ONESHOT - isPostponed always returns true. The user is prompted for question every time.</li>
+ * <li>SESSION - isPostponed returns true until the user decides either yes or no for the current session.</li>
+ * <li>BLANKET - isPostponed returns true until the user decides either always or never.</li>
+ * </ul>
+ * Regardless of the session level, the user is always given the option to reject the prompt
+ * permanently, as if BLANKET/never was chosen. In this case, the question is not postponed
+ * anymore, and {@link #isSatisfied()} returns false.<br/>
+ * If the system supports an separately accessible permission management GUI,
+ * that may reset the condition
+ * to its initial state.
+ *
+ * @return True, if user interaction is needed.
+ */
+ public boolean isPostponed() {
+ lookForImplementation();
+ if (realUserPromptCondition!=null) {
+ return realUserPromptCondition.isPostponed();
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Checks whether the condition may change during the lifetime of the UserPromptCondition object.
+ * This depends on the permission level given in
+ * {@link UserPromptCondition#getCondition(Bundle, ConditionInfo)}.
+ * <ul>
+ * <li>ONESHOT - true</li>
+ * <li>SESSION - true, if the application model's session lifetime is
+ * shorter than the UserPromptCondition object lifetime</li>
+ * <li>BLANKET - false</li>
+ * </ul>
+ * If the system supports separately accessible permission management GUI,
+ * then this function may also return true for SESSION and BLANKET.
+ *
+ * @return True, if the condition can change.
+ */
+ public boolean isMutable() {
+ lookForImplementation();
+ if (realUserPromptCondition!=null) {
+ return realUserPromptCondition.isMutable();
+ } else {
+ // since we don't know what the actual status is, we cannot say
+ // "the condition cannot change anymore"
+ return true;
+ }
+ }
+
+ /**
+ * Displays the prompt string to
+ * the user and returns true if the user accepts. Depending on the
+ * amount of levels the condition is assigned to, the prompt may have
+ * multiple accept buttons and one of them can be selected by default (see
+ * default level parameter at {@link UserPromptCondition#getCondition(Bundle, ConditionInfo)}).
+ * It must always be possible for the user
+ * to stop further prompting of this question, even with ONESHOT and SESSION levels.
+ * In case of BLANKET
+ * and SESSION levels, it is possible that the user has already answered the question,
+ * in this case there will be no prompting, but immediate return with the previous answer.
+ *
+ * @return True if the user accepts the prompt (or accepts any prompt in
+ * case there are multiple permission levels).
+ */
+ public boolean isSatisfied() {
+ lookForImplementation();
+ if (realUserPromptCondition!=null) {
+ return realUserPromptCondition.isSatisfied();
+ } else {
+ // paranoid security option
+ return false;
+ }
+ }
+
+ /**
+ * Checks an array of UserPrompt conditions.
+ *
+ * @param conds The array containing the UserPrompt conditions to evaluate.
+ * @param context Storage area for evaluation. The {@link org.osgi.service.condpermadmin.ConditionalPermissionAdmin}
+ * may evaluate a condition several times for one permission check, so this context
+ * will be used to store results of ONESHOT questions. This way asking the same question
+ * twice in a row can be avoided. If context is null, temporary results will not be stored.
+ * @return True, if all conditions are satisfied.
+ * @throws NullPointerException if conds is null.
+ */
+ public boolean isSatisfied(Condition[] conds, Dictionary context) {
+ lookForImplementation();
+ if (realUserPromptCondition!=null) {
+ return realUserPromptCondition.isSatisfied(conds,context);
+ } else {
+ // paranoid security option
+ return false;
+ }
+ }
+}
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/package.html
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/package.html?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/package.html (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/package.html Mon Jun 2 04:39:58 2008
@@ -0,0 +1,10 @@
+<!-- $Header: /cvshome/build/org.osgi.util.mobile/src/org/osgi/util/mobile/package.html,v 1.2 2006/07/12 21:07:11 hargrave Exp $ -->
+<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
+</pre>
+</BODY>
Added: felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/packageinfo
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/packageinfo?rev=662399&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/packageinfo (added)
+++ felix/trunk/deploymentadmin/service/src/main/java/org/osgi/util/mobile/packageinfo Mon Jun 2 04:39:58 2008
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file