Integrated the newly ASL relicensed OSGi code.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@386363 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.osgi/src/main/java/org/osgi/framework/AdminPermission.java b/org.osgi/src/main/java/org/osgi/framework/AdminPermission.java
index c36d82e..d2846c9 100644
--- a/org.osgi/src/main/java/org/osgi/framework/AdminPermission.java
+++ b/org.osgi/src/main/java/org/osgi/framework/AdminPermission.java
@@ -1,933 +1,392 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AdminPermission.java,v 1.12 2005/05/13 20:32:54 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.*;
-import java.util.*;
-
-
-/**
- * Indicates the caller's authority to perform specific privileged administrative
- * operations on or to get sensitive information about a bundle.
- *
- * <ul>
- * <li>The <code>{@link AdminPermission#METADATA}</code> action allows calls to
- * <ul>
- * <li>{@link Bundle#getHeaders()}
- * <li>{@link Bundle#getHeaders(String)}
- * <li>{@link Bundle#getLocation()}
- * </ul>
- * <li>The <code>{@link AdminPermission#RESOURCE}</code> action allows calls to
- * <ul>
- * <li>{@link Bundle#getResource(String)}
- * <li>{@link Bundle#getEntry(String)}
- * <li>{@link Bundle#getEntryPaths(String)}
- * <li>Bundle resource/entry URL creation
- * </ul>
- * <li>The <code>{@link AdminPermission#METADATA}</code> action allows calls to
- * <ul>
- * <li>{@link Bundle#loadClass(String)}
- * </ul>
- * <li>The <code>{@link AdminPermission#LIFECYCLE}</code> action allows calls to
- * <ul>
- * <li>{@link BundleContext#installBundle(String)}
- * <li>{@link BundleContext#installBundle(String, InputStream)}
- * <li>{@link Bundle#update()}
- * <li>{@link Bundle#update(InputStream)}
- * <li>{@link Bundle#uninstall()}
- * </ul>
- * <li>The <code>{@link AdminPermission#EXECUTE}</code> action allows calls to
- * <ul>
- * <li>{@link Bundle#start()}
- * <li>{@link Bundle#stop()}
- * <li>{@link org.osgi.service.startlevel.StartLevel#setBundleStartLevel(Bundle, int)}
- * </ul>
- * <li>The <code>{@link AdminPermission#LISTENER}</code> action allows calls to
- * <ul>
- * <li>{@link BundleContext#addBundleListener(BundleListener)} for
- * <code>SynchronousBundleListener</code>
- * <li>{@link BundleContext#removeBundleListener(BundleListener)} for
- * <code>SynchronousBundleListener</code>
- * </ul>
- * <li>The <code>{@link AdminPermission#PERMISSION}</code> action allows calls to
- * <ul>
- * <li>{@link org.osgi.service.permissionadmin.PermissionAdmin#setPermissions(String, PermissionInfo[])}
- * <li>{@link org.osgi.service.permissionadmin.PermissionAdmin#setDefaultPermissions(PermissionInfo[])}
- * </ul>
- * <li>The <code>{@link AdminPermission#RESOLVE}</code> action allows calls to
- * <ul>
- * <li>{@link org.osgi.service.packageadmin.PackageAdmin#refreshPackages(Bundle[])}</code>
- * <li>{@link org.osgi.service.packageadmin.PackageAdmin#resolveBundles(Bundle[])}</code>
- * </ul>
- * <li>The <code>{@link AdminPermission#STARTLEVEL}</code> action allows calls to
- * <ul>
- * <li>{@link org.osgi.service.startlevel.StartLevel#setStartLevel(int)}
- * <li>{@link org.osgi.service.startlevel.StartLevel#setInitialBundleStartLevel(int)}
- * </ul>
- * </ul>
- *
- * The special action "*" will represent all actions.
- *
- * @version $Revision: 1.12 $
- */
-
-public final class AdminPermission extends Permission
-{
- static final long serialVersionUID = 207051004521261705L;
-
- /**
- * The action string <code>class</code> (Value is "class").
- */
- public final static String CLASS = "class"; //$NON-NLS-1$
-
- /**
- * The action string <code>execute</code> (Value is "execute").
- */
- public final static String EXECUTE = "execute"; //$NON-NLS-1$
-
- /**
- * The action string <code>lifecycle</code> (Value is "lifecycle").
- */
- public final static String LIFECYCLE = "lifecycle"; //$NON-NLS-1$
-
- /**
- * The action string <code>listener</code> (Value is "listener").
- */
- public final static String LISTENER = "listener"; //$NON-NLS-1$
-
- /**
- * The action string <code>metadata</code> (Value is "metadata").
- */
- public final static String METADATA = "metadata"; //$NON-NLS-1$
-
- /**
- * The action string <code>permission</code> (Value is "permission").
- */
- public final static String PERMISSION = "permission"; //$NON-NLS-1$
-
- /**
- * The action string <code>resolve</code> (Value is "resolve").
- */
- public final static String RESOLVE = "resolve"; //$NON-NLS-1$
-
- /**
- * The action string <code>resource</code> (Value is "resource").
- */
- public final static String RESOURCE = "resource"; //$NON-NLS-1$
-
- /**
- * The action string <code>startlevel</code> (Value is "startlevel").
- */
- public final static String STARTLEVEL = "startlevel"; //$NON-NLS-1$
-
- /**
- * The action string <code>extensionLifecycle</code> (Value is "extensionLifecycle").
- */
- public final static String EXTENSIONLIFECYCLE = "extensionLifecycle"; //$NON-NLS-1$
-
- private final static int ACTION_CLASS = 0x00000001;
- private final static int ACTION_EXECUTE = 0x00000002;
- private final static int ACTION_LIFECYCLE = 0x00000004;
- private final static int ACTION_LISTENER = 0x00000008;
- private final static int ACTION_METADATA = 0x00000010;
- private final static int ACTION_PERMISSION = 0x00000020;
- private final static int ACTION_RESOLVE = 0x00000040;
- private final static int ACTION_RESOURCE = 0x00000080;
- private final static int ACTION_STARTLEVEL = 0x00000100;
- private final static int ACTION_EXTENSIONLIFECYCLE = 0x00000200;
- private final static int ACTION_ALL =
- ACTION_CLASS |
- ACTION_EXECUTE |
- ACTION_LIFECYCLE |
- ACTION_LISTENER |
- ACTION_METADATA |
- ACTION_PERMISSION |
- ACTION_RESOLVE |
- ACTION_RESOURCE |
- ACTION_STARTLEVEL |
- ACTION_EXTENSIONLIFECYCLE;
- private final static int ACTION_NONE = 0;
-
- /**
- * Indicates that this AdminPermission refers to all bundles
- * @serial
- */
- private boolean wildcard;
-
- /**
- * An x.500 distinguished name used to match a bundle's signature - only used if
- * wildcard is false and bundle = null
- * @serial
- */
- private String filter;
-
- /**
- * The actions in canonical form.
- *
- * @serial
- */
- private String actions = null;
-
- /**
- * The actions mask.
- */
- private transient int action_mask = ACTION_NONE;
-
- /**
- * The bundle governed by this AdminPermission - only used if
- * wildcard is false and filter == null
- */
- private transient Bundle bundle;
-
- /**
- * If this AdminPermission was constructed with a bundle, this dictionary holds
- * the properties of that bundle, used to match a filter in implies.
- * This is not initialized until necessary, and then cached in this object.
- */
- private transient Dictionary bundleProperties;
-
- /**
- * If this AdminPermission was constructed with a filter, this dictionary holds
- * a Filter matching object used to evaluate the filter in implies.
- * This is not initialized until necessary, and then cached in this object
- */
- private transient Filter filterImpl;
-
- /**
- * Creates a new <code>AdminPermission</code> object that matches
- * all bundles and has all actions. Equivalent to
- * AdminPermission("*","*");
- */
- public AdminPermission()
- {
- this("*",AdminPermission.ACTION_ALL); //$NON-NLS-1$
- }
-
- /**
- * Creates a new <code>AdminPermission</code> object for use by the <code>Policy</code>
- * object to instantiate new <code>Permission</code> objects.
- *
- * Null arguments are equivalent to "*"
- *
- * @param filter an X.500 Distinguished Name suffix or "*" to match all bundles
- * @param actions <code>class</code>, <code>execute</code>, <code>lifecycle</code>,
- * <code>listener</code>, <code>metadata</code>, <code>permission</code>, <code>resolve</code>,
- * <code>resource</code>, <code>startlevel</code>, or "*" to indicate all actions
- */
- public AdminPermission(String filter, String actions)
- {
- //arguments will be null if called from a PermissionInfo defined with
- //no args
- this(
- (filter == null ? "*" : filter), //$NON-NLS-1$
- getMask((actions == null ? "*" : actions)) //$NON-NLS-1$
- );
- }
-
- /**
- * Creates a new <code>AdminPermission</code> object for use by the <code>Policy</code>
- * object to instantiate new <code>Permission</code> objects.
- *
- * @param bundle A bundle
- * @param actions <code>class</code>, <code>execute</code>, <code>lifecycle</code>,
- * <code>listener</code>, <code>metadata</code>, <code>permission</code>, <code>resolve</code>,
- * <code>resource</code>, <code>startlevel</code>, or "*" to indicate all actions
- */
- public AdminPermission(Bundle bundle, String actions) {
- super(bundle.toString());
- this.bundle = bundle;
- this.wildcard = false;
- this.filter = null;
- this.action_mask = getMask(actions);
- }
-
- /**
- * Package private constructor used by AdminPermissionCollection.
- *
- * @param filter name filter
- * @param action_mask mask
- */
- AdminPermission(String filter, int action_mask) {
- super(filter);
-
- //name must be either * or a filter
- if (filter.equals("*")) { //$NON-NLS-1$
- this.wildcard = true;
- this.filter = null;
- } else {
- this.wildcard = false;
- this.filter = filter;
- }
- this.bundle = null;
- this.action_mask = action_mask;
- }
-
- /**
- * Parse action string into 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 >= 4 &&
- (a[i-4] == 'c' || a[i-4] == 'C') &&
- (a[i-3] == 'l' || a[i-3] == 'L') &&
- (a[i-2] == 'a' || a[i-2] == 'A') &&
- (a[i-1] == 's' || a[i-1] == 'S') &&
- (a[i] == 's' || a[i] == 'S'))
- {
- matchlen = 5;
- mask |= ACTION_CLASS;
-
- } else if (i >= 6 &&
- (a[i-6] == 'e' || a[i-6] == 'E') &&
- (a[i-5] == 'x' || a[i-5] == 'X') &&
- (a[i-4] == 'e' || a[i-4] == 'E') &&
- (a[i-3] == 'c' || a[i-3] == 'C') &&
- (a[i-2] == 'u' || a[i-2] == 'U') &&
- (a[i-1] == 't' || a[i-1] == 'T') &&
- (a[i] == 'e' || a[i] == 'E'))
- {
- matchlen = 7;
- mask |= ACTION_EXECUTE;
-
- } else if (i >= 17 &&
- (a[i-17] == 'e' || a[i-17] == 'E') &&
- (a[i-16] == 'x' || a[i-16] == 'X') &&
- (a[i-15] == 't' || a[i-15] == 'T') &&
- (a[i-14] == 'e' || a[i-14] == 'E') &&
- (a[i-13] == 'n' || a[i-13] == 'N') &&
- (a[i-12] == 's' || a[i-12] == 'S') &&
- (a[i-11] == 'i' || a[i-11] == 'I') &&
- (a[i-10] == 'o' || a[i-10] == 'O') &&
- (a[i-9] == 'n' || a[i-9] == 'N') &&
- (a[i-8] == 'l' || a[i-8] == 'L') &&
- (a[i-7] == 'i' || a[i-7] == 'I') &&
- (a[i-6] == 'f' || a[i-6] == 'F') &&
- (a[i-5] == 'e' || a[i-5] == 'E') &&
- (a[i-4] == 'c' || a[i-4] == 'C') &&
- (a[i-3] == 'y' || a[i-3] == 'Y') &&
- (a[i-2] == 'c' || a[i-2] == 'C') &&
- (a[i-1] == 'l' || a[i-1] == 'L') &&
- (a[i] == 'e' || a[i] == 'E'))
- {
- matchlen = 18;
- mask |= ACTION_EXTENSIONLIFECYCLE;
-
- } else if (i >= 8 &&
- (a[i-8] == 'l' || a[i-8] == 'L') &&
- (a[i-7] == 'i' || a[i-7] == 'I') &&
- (a[i-6] == 'f' || a[i-6] == 'F') &&
- (a[i-5] == 'e' || a[i-5] == 'E') &&
- (a[i-4] == 'c' || a[i-4] == 'C') &&
- (a[i-3] == 'y' || a[i-3] == 'Y') &&
- (a[i-2] == 'c' || a[i-2] == 'C') &&
- (a[i-1] == 'l' || a[i-1] == 'L') &&
- (a[i] == 'e' || a[i] == 'E'))
- {
- matchlen = 9;
- mask |= ACTION_LIFECYCLE;
-
- } else if (i >= 7 &&
- (a[i-7] == 'l' || a[i-7] == 'L') &&
- (a[i-6] == 'i' || a[i-6] == 'I') &&
- (a[i-5] == 's' || a[i-5] == 'S') &&
- (a[i-4] == 't' || a[i-4] == 'T') &&
- (a[i-3] == 'e' || a[i-3] == 'E') &&
- (a[i-2] == 'n' || a[i-2] == 'N') &&
- (a[i-1] == 'e' || a[i-1] == 'E') &&
- (a[i] == 'r' || a[i] == 'R'))
- {
- matchlen = 8;
- mask |= ACTION_LISTENER;
-
- } else if (i >= 7 &&
- (a[i-7] == 'm' || a[i-7] == 'M') &&
- (a[i-6] == 'e' || a[i-6] == 'E') &&
- (a[i-5] == 't' || a[i-5] == 'T') &&
- (a[i-4] == 'a' || a[i-4] == 'A') &&
- (a[i-3] == 'd' || a[i-3] == 'D') &&
- (a[i-2] == 'a' || a[i-2] == 'A') &&
- (a[i-1] == 't' || a[i-1] == 'T') &&
- (a[i] == 'a' || a[i] == 'A'))
- {
- matchlen = 8;
- mask |= ACTION_METADATA;
-
- } else if (i >= 9 &&
- (a[i-9] == 'p' || a[i-9] == 'P') &&
- (a[i-8] == 'e' || a[i-8] == 'E') &&
- (a[i-7] == 'r' || a[i-7] == 'R') &&
- (a[i-6] == 'm' || a[i-6] == 'M') &&
- (a[i-5] == 'i' || a[i-5] == 'I') &&
- (a[i-4] == 's' || a[i-4] == 'S') &&
- (a[i-3] == 's' || a[i-3] == 'S') &&
- (a[i-2] == 'i' || a[i-2] == 'I') &&
- (a[i-1] == 'o' || a[i-1] == 'O') &&
- (a[i] == 'n' || a[i] == 'N'))
- {
- matchlen = 10;
- mask |= ACTION_PERMISSION;
-
- } else if (i >= 6 &&
- (a[i-6] == 'r' || a[i-6] == 'R') &&
- (a[i-5] == 'e' || a[i-5] == 'E') &&
- (a[i-4] == 's' || a[i-4] == 'S') &&
- (a[i-3] == 'o' || a[i-3] == 'O') &&
- (a[i-2] == 'l' || a[i-2] == 'L') &&
- (a[i-1] == 'v' || a[i-1] == 'V') &&
- (a[i] == 'e' || a[i] == 'E'))
- {
- matchlen = 7;
- mask |= ACTION_RESOLVE;
-
- } else if (i >= 7 &&
- (a[i-7] == 'r' || a[i-7] == 'R') &&
- (a[i-6] == 'e' || a[i-6] == 'E') &&
- (a[i-5] == 's' || a[i-5] == 'S') &&
- (a[i-4] == 'o' || a[i-4] == 'O') &&
- (a[i-3] == 'u' || a[i-3] == 'U') &&
- (a[i-2] == 'r' || a[i-2] == 'R') &&
- (a[i-1] == 'c' || a[i-1] == 'C') &&
- (a[i] == 'e' || a[i] == 'E'))
- {
- matchlen = 8;
- mask |= ACTION_RESOURCE;
-
- } else if (i >= 9 &&
- (a[i-9] == 's' || a[i-9] == 'S') &&
- (a[i-8] == 't' || a[i-8] == 'T') &&
- (a[i-7] == 'a' || a[i-7] == 'A') &&
- (a[i-6] == 'r' || a[i-6] == 'R') &&
- (a[i-5] == 't' || a[i-5] == 'T') &&
- (a[i-4] == 'l' || a[i-4] == 'L') &&
- (a[i-3] == 'e' || a[i-3] == 'E') &&
- (a[i-2] == 'v' || a[i-2] == 'V') &&
- (a[i-1] == 'e' || a[i-1] == 'E') &&
- (a[i] == 'l' || a[i] == 'L'))
- {
- matchlen = 10;
- mask |= ACTION_STARTLEVEL;
-
- } else if (i >= 0 &&
- (a[i] == '*'))
- {
- matchlen = 1;
- mask |= ACTION_ALL;
-
- } else {
- // parse error
- throw new IllegalArgumentException(
- "invalid permission: " + actions);
- }
-
- // make sure we didn't just match the tail of a word
- // like "ackbarfstartlevel". 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;
- }
-
- /**
- * Called by <code><@link AdminPermission#implies(Permission)></code> on an AdminPermission
- * which was constructed with a Bundle. This method loads a dictionary with the
- * filter-matchable properties of this bundle. The dictionary is cached so this lookup
- * only happens once.
- *
- * This method should only be called on an AdminPermission which was constructed with a
- * bundle
- *
- * @return a dictionary of properties for this bundle
- */
- private Dictionary getProperties() {
- if (bundleProperties == null) {
- bundleProperties = new Hashtable();
-
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- //set Id
- bundleProperties.put("id",new Long(bundle.getBundleId())); //$NON-NLS-1$
-
- //set location
- bundleProperties.put("location",bundle.getLocation()); //$NON-NLS-1$
-
- //set name
- if (bundle.getSymbolicName() != null)
- bundleProperties.put("name",bundle.getSymbolicName()); //$NON-NLS-1$
-
- //set signers
-// bundleProperties.put("signer",new SignerWrapper(bundle)); //$NON-NLS-1$
-
- return null;
- }
- });
- }
- return bundleProperties;
- }
-/*
- private static class SignerWrapper extends Object {
- private Bundle bundle;
- private String pattern;
- public SignerWrapper(String pattern) {
- this.pattern = pattern;
- }
- SignerWrapper(Bundle bundle) {
- this.bundle = bundle;
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof SignerWrapper))
- return false;
- SignerWrapper other = (SignerWrapper) o;
- AbstractBundle matchBundle = (AbstractBundle) (bundle != null ? bundle : other.bundle);
- String matchPattern = bundle != null ? other.pattern : pattern;
- return matchBundle.getBundleData().matchDNChain(matchPattern);
- }
- }
-*/
-
- /**
- * Called by <tt><@link AdminPermission#implies(Permission)></tt> on an AdminPermission
- * which was constructed with a filter. This method loads a FilterImpl with the
- * filter specification of this AdminPermission. The filter is cached so this work
- * only happens once.
- *
- * This method should only be called on an AdminPermission which was constructed with a
- * filter
- *
- * @return a filterImpl for this bundle
- */
- private Filter getFilterImpl() {
- if (filterImpl == null) {
- try {
- int pos = filter.indexOf("signer"); //$NON-NLS-1$
- if (pos != -1){
-
- //there may be a signer attribute
- StringBuffer filterBuf = new StringBuffer(filter);
- int numAsteriskFound = 0; //use as offset to replace in buffer
-
- int walkbackPos; //temp pos
-
- //find occurences of (signer= and escape out *'s
- while (pos != -1) {
-
- //walk back and look for '(' to see if this is an attr
- walkbackPos = pos-1;
-
- //consume whitespace
- while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
- walkbackPos--;
- }
- if (walkbackPos <0) {
- //filter is invalid - FilterImpl will throw error
- break;
- }
-
- //check to see if we have unescaped '('
- if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
- //'(' was escaped or not there
- pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
- continue;
- }
- pos+=6; //skip over 'signer'
-
- //found signer - consume whitespace before '='
- while (Character.isWhitespace(filter.charAt(pos))) {
- pos++;
- }
-
- //look for '='
- if (filter.charAt(pos) != '=') {
- //attr was signerx - keep looking
- pos = filter.indexOf("signer",pos); //$NON-NLS-1$
- continue;
- }
- pos++; //skip over '='
-
- //found signer value - escape '*'s
- while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
- if (filter.charAt(pos) == '*') {
- filterBuf.insert(pos+numAsteriskFound,'\\');
- numAsteriskFound++;
- }
- pos++;
- }
-
- //end of signer value - look for more?
- pos = filter.indexOf("signer",pos); //$NON-NLS-1$
- } //end while (pos != -1)
- filter = filterBuf.toString();
- } //end if (pos != -1)
-
- filterImpl = FrameworkUtil.createFilter( filter );
- } catch (InvalidSyntaxException e) {
- //we will return null
- }
- }
- return filterImpl;
- }
-
- /**
- * Determines if the specified permission is implied by this object.
- * This method throws an exception if the specified permission was not
- * constructed with a bundle.
- *
- * <p>This method returns <code>true</code> if
- * The specified permission is an AdminPermission AND
- * <ul>
- * <li>this object's filter is an X.500 Distinguished name suffix that
- * matches the specified permission's bundle OR
- * <li>this object's filter is "*" OR
- * <li>this object's bundle is a equal to the specified permission's
- * bundle
- * </ul>
- * AND this object's actions include all of the specified permission's actions
- *
- * Special case: if the specified permission was constructed with "*", then this method
- * returns <code>true</code> if this object's filter is "*" and this object's actions include
- * all of the specified permission's actions
- *
- * @param p The permission to interrogate.
- *
- * @return <code>true</code> if the specified permission is implied by
- * this object; <code>false</code> otherwise.
- * @throws RuntimeException if specified permission was not constructed with
- * a bundle or "*"
- */
- public boolean implies(Permission p)
- {
- if (!(p instanceof AdminPermission))
- return false;
- AdminPermission target = (AdminPermission)p;
- //check actions first - much faster
- if ((action_mask & target.action_mask)!=target.action_mask)
- return false;
- //if passed in a filter, puke
- if (target.filter != null)
- throw new RuntimeException("Cannot imply a filter");
- //special case - only wildcard implies wildcard
- if (target.wildcard)
- return wildcard;
-
- //check our name
- if (filter != null) {
- //it's a filter
- Filter filterImpl = getFilterImpl();
- return filterImpl != null && filterImpl.match(target.getProperties());
- } else if (wildcard) {
- //it's "*"
- return true;
- } else {
- //it's a bundle id
- return bundle.equals(target.bundle);
- }
-
- }
-
- /**
- * Returns the canonical string representation of the <code>AdminPermission</code> actions.
- *
- * <p>Always returns present <code>AdminPermission</code> actions in the following order:
- * <code>CLASS</code>, <code>EXECUTE</code>, <code>LIFECYCLE</code>, <code>LISTENER</code>,
- * <code>METADATA</code>, <code>PERMISSION</code>, <code>RESOLVE</code>, <code>RESOURCE</code>,
- * <code>STARTLEVEL</code>.
- * @return Canonical string representation of the <code>AdminPermission</code> actions.
- */
- public String getActions() {
- if (actions == null) {
- if (action_mask == ACTION_ALL) {
- actions = "*"; //$NON-NLS-1$
- } else {
- StringBuffer sb = new StringBuffer();
-
- if ((action_mask & ACTION_CLASS) == ACTION_CLASS) {
- sb.append(CLASS);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_EXECUTE) == ACTION_EXECUTE) {
- sb.append(EXECUTE);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_LIFECYCLE) == ACTION_LIFECYCLE) {
- sb.append(LIFECYCLE);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_LISTENER) == ACTION_LISTENER) {
- sb.append(LISTENER);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_METADATA) == ACTION_METADATA) {
- sb.append(METADATA);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_PERMISSION) == ACTION_PERMISSION) {
- sb.append(PERMISSION);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_RESOLVE) == ACTION_RESOLVE) {
- sb.append(RESOLVE);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_RESOURCE) == ACTION_RESOURCE) {
- sb.append(RESOURCE);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_STARTLEVEL) == ACTION_STARTLEVEL) {
- sb.append(STARTLEVEL);
- sb.append(',');
- }
-
- if ((action_mask & ACTION_EXTENSIONLIFECYCLE) == ACTION_EXTENSIONLIFECYCLE) {
- sb.append(EXTENSIONLIFECYCLE);
- sb.append(',');
- }
-
- //remove trailing comma
- if (sb.length() > 0) {
- sb.deleteCharAt(sb.length()-1);
- }
-
- actions = sb.toString();
- }
- }
- return actions;
- }
-
- /**
- * Determines the equality of two <code>AdminPermission</code> objects. <p>Two
- * <code>AdminPermission</code> objects are equal.
- *
- * @param obj The object being compared for equality with this object.
- * @return <code>true</code> if <code>obj</code> is equivalent to this
- * <code>AdminPermission</code>; <code>false</code> otherwise.
- */
- public boolean equals(Object obj)
- {
- if (obj == this) {
- return true;
- }
-
- if (!(obj instanceof AdminPermission))
- {
- return false;
- }
-
- AdminPermission a = (AdminPermission) obj;
-
- return (action_mask == a.action_mask) &&
- (wildcard == a.wildcard) &&
- (bundle == null ? a.bundle == null : (a.bundle == null ? false : bundle.getBundleId() == a.bundle.getBundleId())) &&
- (filter == null ? a.filter == null : filter.equals(a.filter));
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return Hash code value for this object.
- */
- public int hashCode() {
- return getName().hashCode() ^ getActions().hashCode();
- }
-
- 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();
- if (filter == null && !wildcard)
- throw new UnsupportedOperationException("cannot serialize");
- s.defaultWriteObject();
- }
-
- /**
- * readObject is called to restore the state of this permission from a
- * stream.
- */
- private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
- // Read in the action, then initialize the rest
- s.defaultReadObject();
- action_mask = getMask(actions);
- }
-
- /**
- * Returns a new <code>PermissionCollection</code> object suitable for storing
- * <code>AdminPermission</code>s.
- *
- * @return A new <code>PermissionCollection</code> object.
- */
- public PermissionCollection newPermissionCollection()
- {
- return(new AdminPermissionCollection());
- }
-
- /**
- * Stores a collection of <code>AdminPermission</code>s.
- */
- private final class AdminPermissionCollection extends PermissionCollection
- {
- private static final long serialVersionUID = 3906372644575328048L;
- /**
- * Collection of permissions.
- *
- * @serial
- */
- private Hashtable permissions;
-
- /**
- * Create an empty AdminPermissions object.
- *
- */
-
- public AdminPermissionCollection()
- {
- permissions = new Hashtable();
- }
-
- /**
- * Adds a permission to the <code>AdminPermission</code> objects. The key for
- * the hashtable is the name
- *
- * @param permission The <code>AdminPermission</code> object to add.
- *
- * @exception IllegalArgumentException If the permission is not an
- * <code>AdminPermission</code> instance.
- *
- * @exception SecurityException If this <code>AdminPermissionCollection</code>
- * object has been marked read-only.
- */
- public void add(Permission permission)
- {
- if (! (permission instanceof AdminPermission))
- throw new IllegalArgumentException("invalid permission: "+
- permission);
- if (isReadOnly())
- throw new SecurityException("attempt to add a Permission to a " +
- "readonly AdminCollection");
- AdminPermission ap = (AdminPermission) permission;
- AdminPermission existing = (AdminPermission) permissions.get(ap.getName());
- if (existing != null){
- int oldMask = existing.action_mask;
- int newMask = ap.action_mask;
-
- if (oldMask != newMask) {
- permissions.put(existing.getName(),
- new AdminPermission(existing.getName(), oldMask | newMask));
- }
- } else {
- permissions.put(ap.getName(), ap);
- }
- }
-
-
- /**
- * Determines if the specified permissions implies the permissions
- * expressed in <code>permission</code>.
- *
- * @param permission The Permission object to compare with the <code>AdminPermission</code>
- * objects in this collection.
- *
- * @return <code>true</code> if <code>permission</code> is implied by an
- * <code>AdminPermission</code> in this collection, <code>false</code> otherwise.
- */
- public boolean implies(Permission permission)
- {
- if (!(permission instanceof AdminPermission))
- return(false);
-
- AdminPermission target = (AdminPermission) permission;
-
- //just iterate one by one
- Iterator permItr = permissions.values().iterator();
-
- while(permItr.hasNext())
- if (((AdminPermission)permItr.next()).implies(target))
- return true;
- return false;
- }
-
-
- /**
- * Returns an enumeration of all <code>AdminPermission</code> objects in the
- * container.
- *
- * @return Enumeration of all <code>AdminPermission</code> objects.
- */
-
- public Enumeration elements()
- {
- return(Collections.enumeration(permissions.values()));
- }
- }
-}
\ No newline at end of file
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AdminPermission.java,v 1.28 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.*;
+
+/**
+ * Indicates the caller's authority to perform specific privileged
+ * administrative operations on or to get sensitive information about a bundle.
+ * The actions for this permission are:
+ *
+ * <pre>
+ * Action Methods
+ * class Bundle.loadClass
+ * execute Bundle.start
+ * Bundle.stop
+ * StartLevel.setBundleStartLevel
+ * extensionLifecycle BundleContext.installBundle for extension bundles
+ * Bundle.update for extension bundles
+ * Bundle.uninstall for extension bundles
+ * lifecycle BundleContext.installBundle
+ * Bundle.update
+ * Bundle.uninstall
+ * listener BundleContext.addBundleListener for SynchronousBundleListener
+ * BundleContext.removeBundleListener for SynchronousBundleListener
+ * metadata Bundle.getHeaders
+ * Bundle.getLocation
+ * resolve PackageAdmin.refreshPackages
+ * PackageAdmin.resolveBundles
+ * resource Bundle.getResource
+ * Bundle.getResources
+ * Bundle.getEntry
+ * Bundle.getEntryPaths
+ * Bundle.findEntries
+ * Bundle resource/entry URL creation
+ * startlevel StartLevel.setStartLevel
+ * StartLevel.setInitialBundleStartLevel
+ * </pre>
+ *
+ * <p>
+ * The special action "*" will represent all actions.
+ * <p>
+ * The name of this permission is a filter expression. The filter gives access
+ * to the following parameters:
+ * <ul>
+ * <li>signer - A Distinguished Name chain used to sign a bundle. Wildcards in
+ * a DN are not matched according to the filter string rules, but according to
+ * the rules defined for a DN chain.</li>
+ * <li>location - The location of a bundle.</li>
+ * <li>id - The bundle ID of the designated bundle.</li>
+ * <li>name - The symbolic name of a bundle.</li>
+ * </ul>
+ *
+ * @version $Revision: 1.28 $
+ */
+
+public final class AdminPermission extends BasicPermission {
+ static final long serialVersionUID = 307051004521261705L;
+
+ /**
+ * The action string <code>class</code> (Value is "class").
+ * @since 1.3
+ */
+ public final static String CLASS = "class";
+ /**
+ * The action string <code>execute</code> (Value is "execute").
+ * @since 1.3
+ */
+ public final static String EXECUTE = "execute";
+ /**
+ * The action string <code>extensionLifecycle</code> (Value is
+ * "extensionLifecycle").
+ * @since 1.3
+ */
+ public final static String EXTENSIONLIFECYCLE = "extensionLifecycle";
+ /**
+ * The action string <code>lifecycle</code> (Value is "lifecycle").
+ * @since 1.3
+ */
+ public final static String LIFECYCLE = "lifecycle";
+ /**
+ * The action string <code>listener</code> (Value is "listener").
+ * @since 1.3
+ */
+ public final static String LISTENER = "listener";
+ /**
+ * The action string <code>metadata</code> (Value is "metadata").
+ * @since 1.3
+ */
+ public final static String METADATA = "metadata";
+ /**
+ * The action string <code>resolve</code> (Value is "resolve").
+ * @since 1.3
+ */
+ public final static String RESOLVE = "resolve";
+ /**
+ * The action string <code>resource</code> (Value is "resource").
+ * @since 1.3
+ */
+ public final static String RESOURCE = "resource";
+ /**
+ * The action string <code>startlevel</code> (Value is "startlevel").
+ * @since 1.3
+ */
+ public final static String STARTLEVEL = "startlevel";
+
+ /*
+ * NOTE: A framework implementor may also choose to replace this class in
+ * their distribution with a class that directly interfaces with the
+ * framework implementation. This replacement class MUST NOT
+ * alter the public/protected signature of this class.
+ */
+
+ /*
+ * This class will load the AdminPermission class in the package named by
+ * the org.osgi.vendor.framework package. For each instance of this class,
+ * an instance of the vendor AdminPermission class will be created and this
+ * class will delegate method calls to the vendor AdminPermission instance.
+ */
+ private static final String packageProperty = "org.osgi.vendor.framework";
+ private static final Constructor initStringString;
+ private static final Constructor initBundleString;
+ static {
+ Constructor[] constructors = (Constructor[]) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String packageName = System
+ .getProperty(packageProperty);
+ if (packageName == null) {
+ throw new NoClassDefFoundError(packageProperty
+ + " property not set");
+ }
+
+ Class delegateClass;
+ try {
+ delegateClass = Class.forName(packageName
+ + ".AdminPermission");
+ }
+ catch (ClassNotFoundException e) {
+ throw new NoClassDefFoundError(e.toString());
+ }
+
+ Constructor[] result = new Constructor[2];
+ try {
+ result[0] = delegateClass
+ .getConstructor(new Class[] {String.class,
+ String.class });
+ result[1] = delegateClass
+ .getConstructor(new Class[] {Bundle.class,
+ String.class });
+ }
+ catch (NoSuchMethodException e) {
+ throw new NoSuchMethodError(e.toString());
+ }
+
+ return result;
+ }
+ });
+
+ initStringString = constructors[0];
+ initBundleString = constructors[1];
+ }
+
+ /*
+ * This is the delegate permission created by the constructor.
+ */
+ private final Permission delegate;
+
+ /**
+ * Creates a new <code>AdminPermission</code> object that matches all
+ * bundles and has all actions. Equivalent to AdminPermission("*","*");
+ */
+ public AdminPermission() {
+ this("*", "*"); //$NON-NLS-1$
+ }
+
+ /**
+ * Create a new AdminPermission.
+ *
+ * This constructor must only be used to create a permission that is going
+ * to be checked.
+ * <p>
+ * Examples:
+ *
+ * <pre>
+ * (signer=\*,o=ACME,c=US)
+ * (&(signer=\*,o=ACME,c=US)(name=com.acme.*)(location=http://www.acme.com/bundles/*))
+ * (id>=1)
+ * </pre>
+ *
+ * <p>
+ * When a signer key is used within the filter expression the signer value
+ * must escape the special filter chars ('*', '(', ')').
+ * <p>
+ * Null arguments are equivalent to "*".
+ *
+ * @param filter A filter expression that can use signer, location, id, and
+ * name keys. A value of "*" or <code>null</code> matches
+ * all bundle.
+ * @param actions <code>class</code>, <code>execute</code>,
+ * <code>extensionLifecycle</code>, <code>lifecycle</code>,
+ * <code>listener</code>, <code>metadata</code>,
+ * <code>resolve</code>, <code>resource</code>, or
+ * <code>startlevel</code>. A value of "*" or <code>null</code>
+ * indicates all actions
+ */
+ public AdminPermission(String filter, String actions) {
+ // arguments will be null if called from a PermissionInfo defined with
+ // no args
+ super(filter == null ? "*" : filter);
+ try {
+ try {
+ delegate = (Permission) initStringString
+ .newInstance(new Object[] {filter, actions});
+ }
+ catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+ catch (Error e) {
+ throw e;
+ }
+ catch (RuntimeException e) {
+ throw e;
+ }
+ catch (Throwable e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ /**
+ * Creates a new <code>AdminPermission</code> object to be used by the
+ * code that must check a <code>Permission</code> object.
+ *
+ * @param bundle A bundle
+ * @param actions <code>class</code>, <code>execute</code>,
+ * <code>extensionLifecycle</code>, <code>lifecycle</code>,
+ * <code>listener</code>, <code>metadata</code>,
+ * <code>resolve</code>, <code>resource</code>,
+ * <code>startlevel</code>
+ * @since 1.3
+ */
+ public AdminPermission(Bundle bundle, String actions) {
+ super(createName(bundle));
+ try {
+ try {
+ delegate = (Permission) initBundleString
+ .newInstance(new Object[] {bundle, actions});
+ }
+ catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+ catch (Error e) {
+ throw e;
+ }
+ catch (RuntimeException e) {
+ throw e;
+ }
+ catch (Throwable e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ /**
+ * Create a permission name from a Bundle
+ *
+ * @param bundle Bundle to use to create permission name.
+ * @return permission name.
+ */
+ private static String createName(Bundle bundle) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("(id=");
+ sb.append(bundle.getBundleId());
+ sb.append(")");
+ return sb.toString();
+ }
+
+ /**
+ * Determines the equality of two <code>AdminPermission</code> objects.
+ *
+ * @param obj The object being compared for equality with this object.
+ * @return <code>true</code> if <code>obj</code> is equivalent to this
+ * <code>AdminPermission</code>; <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof AdminPermission)) {
+ return false;
+ }
+
+ AdminPermission p = (AdminPermission) obj;
+
+ return delegate.equals(p.delegate);
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return Hash code value for this object.
+ */
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ /**
+ * Returns the canonical string representation of the
+ * <code>AdminPermission</code> actions.
+ *
+ * <p>
+ * Always returns present <code>AdminPermission</code> actions in the
+ * following order: <code>class</code>, <code>execute</code>,
+ * <code>extensionLifecycle</code>, <code>lifecycle</code>,
+ * <code>listener</code>, <code>metadata</code>, <code>resolve</code>,
+ * <code>resource</code>, <code>startlevel</code>.
+ *
+ * @return Canonical string representation of the
+ * <code>AdminPermission</code> actions.
+ */
+ public String getActions() {
+ return delegate.getActions();
+ }
+
+ /**
+ * Determines if the specified permission is implied by this object. This
+ * method throws an exception if the specified permission was not
+ * constructed with a bundle.
+ *
+ * <p>
+ * This method returns <code>true</code> if the specified permission is an
+ * AdminPermission AND
+ * <ul>
+ * <li>this object's filter matches the specified permission's bundle ID,
+ * bundle symbolic name, bundle location and bundle signer distinguished
+ * name chain OR</li>
+ * <li>this object's filter is "*"</li>
+ * </ul>
+ * AND this object's actions include all of the specified permission's
+ * actions.
+ * <p>
+ * Special case: if the specified permission was constructed with "*"
+ * filter, then this method returns <code>true</code> if this object's
+ * filter is "*" and this object's actions include all of the specified
+ * permission's actions
+ *
+ * @param p The permission to interrogate.
+ *
+ * @return <code>true</code> if the specified permission is implied by
+ * this object; <code>false</code> otherwise.
+ * @throws RuntimeException if specified permission was not constructed with
+ * a bundle or "*"
+ */
+ public boolean implies(Permission p) {
+ if (!(p instanceof AdminPermission)) {
+ return false;
+ }
+
+ AdminPermission pp = (AdminPermission) p;
+ return delegate.implies(pp.delegate);
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>AdminPermission</code>s.
+ *
+ * @return A new <code>PermissionCollection</code> object.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return delegate.newPermissionCollection();
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/AllServiceListener.java b/org.osgi/src/main/java/org/osgi/framework/AllServiceListener.java
index 6de64bc..b2c30bf 100644
--- a/org.osgi/src/main/java/org/osgi/framework/AllServiceListener.java
+++ b/org.osgi/src/main/java/org/osgi/framework/AllServiceListener.java
@@ -1,48 +1,60 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AllServiceListener.java,v 1.5 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * A <code>ServiceEvent</code> listener.
- *
- * <p><code>AllServiceListener</code> is a listener interface that may be implemented by a bundle
- * developer.
- * <p>An <code>AllServiceListener</code> object is registered with the Framework using the
- * <code>BundleContext.addServiceListener</code> method.
- * <code>AllServiceListener</code> objects are called with a <code>ServiceEvent</code> object when
- * a service is registered, modified, or is in the process of unregistering.
- *
- * <p><code>ServiceEvent</code> object delivery to <code>AllServiceListener</code> objects is filtered by the
- * filter specified when the listener was registered. If the Java Runtime Environment
- * supports permissions, then additional filtering is done.
- * <code>ServiceEvent</code> objects are only delivered to the listener if the bundle which defines
- * the listener object's class has the appropriate <code>ServicePermission</code> to get the service
- * using at least one of the named classes the service was registered under.
- *
- * <p>
- * Unlike normal <code>ServiceListener</code> objects,
- * <code>AllServiceListener</code> objects receive all ServiceEvent objects regardless of the
- * whether the package source of the listening bundle is equal to the package source of
- * the bundle that registered the service. This means that the listener may not be able to
- * cast the service object to any of its corresponding service interfaces if the service
- * object is retrieved.
- *
- * @version $Revision: 1.5 $
- * @see ServiceEvent
- * @see ServicePermission
- */
-
-public abstract interface AllServiceListener extends ServiceListener
-{
- //This is a marker interface
-}
-
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AllServiceListener.java,v 1.8 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (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.framework;
+
+/**
+ * A <code>ServiceEvent</code> listener.
+ *
+ * <p>
+ * <code>AllServiceListener</code> is a listener interface that may be
+ * implemented by a bundle developer.
+ * <p>
+ * An <code>AllServiceListener</code> object is registered with the Framework
+ * using the <code>BundleContext.addServiceListener</code> method.
+ * <code>AllServiceListener</code> objects are called with a
+ * <code>ServiceEvent</code> object when a service is registered, modified, or
+ * is in the process of unregistering.
+ *
+ * <p>
+ * <code>ServiceEvent</code> object delivery to
+ * <code>AllServiceListener</code> objects is filtered by the filter specified
+ * when the listener was registered. If the Java Runtime Environment supports
+ * permissions, then additional filtering is done. <code>ServiceEvent</code>
+ * objects are only delivered to the listener if the bundle which defines the
+ * listener object's class has the appropriate <code>ServicePermission</code>
+ * to get the service using at least one of the named classes the service was
+ * registered under.
+ *
+ * <p>
+ * Unlike normal <code>ServiceListener</code> objects,
+ * <code>AllServiceListener</code> objects receive all ServiceEvent objects
+ * regardless of the whether the package source of the listening bundle is equal
+ * to the package source of the bundle that registered the service. This means
+ * that the listener may not be able to cast the service object to any of its
+ * corresponding service interfaces if the service object is retrieved.
+ *
+ * @version $Revision: 1.8 $
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @since 1.3
+ */
+
+public interface AllServiceListener extends ServiceListener {
+ // This is a marker interface
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/Bundle.java b/org.osgi/src/main/java/org/osgi/framework/Bundle.java
index de19d9f..8776998 100644
--- a/org.osgi/src/main/java/org/osgi/framework/Bundle.java
+++ b/org.osgi/src/main/java/org/osgi/framework/Bundle.java
@@ -1,932 +1,954 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Bundle.java,v 1.27 2005/06/21 16:37:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-/**
- * An installed bundle in the Framework.
- *
- * <p>
- * A <code>Bundle</code> object is the access point to define the lifecycle of
- * an installed bundle. Each bundle installed in the OSGi environment must have
- * an associated <code>Bundle</code> object.
- *
- * <p>
- * A bundle must have a unique identity, a <code>long</code>, chosen by the
- * Framework. This identity must not change during the lifecycle of a bundle,
- * even when the bundle is updated. Uninstalling and then reinstalling the
- * bundle must create a new unique identity.
- *
- * <p>
- * A bundle can be in one of six states:
- * <ul>
- * <li>{@link #UNINSTALLED}
- * <li>{@link #INSTALLED}
- * <li>{@link #RESOLVED}
- * <li>{@link #STARTING}
- * <li>{@link #STOPPING}
- * <li>{@link #ACTIVE}
- * </ul>
- * <p>
- * Values assigned to these states have no specified ordering; they represent
- * bit values that may be ORed together to determine if a bundle is in one of
- * the valid states.
- *
- * <p>
- * A bundle should only execute code when its state is one of
- * <code>STARTING</code>,<code>ACTIVE</code>, or <code>STOPPING</code>.
- * An <code>UNINSTALLED</code> bundle can not be set to another state; it is a
- * zombie and can only be reached because references are kept somewhere.
- *
- * <p>
- * The Framework is the only entity that is allowed to create
- * <code>Bundle</code> objects, and these objects are only valid within the
- * Framework that created them.
- *
- * @version $Revision: 1.27 $
- */
-public abstract interface Bundle {
- /**
- * This bundle is uninstalled and may not be used.
- *
- * <p>
- * The <code>UNINSTALLED</code> state is only visible after a bundle is
- * uninstalled; the bundle is in an unusable state but references to the
- * <code>Bundle</code> object may still be available and used for
- * introspection.
- * <p>
- * The value of <code>UNINSTALLED</code> is 0x00000001.
- */
- public static final int UNINSTALLED = 0x00000001;
-
- /**
- * This bundle is installed but not yet resolved.
- *
- * <p>
- * A bundle is in the <code>INSTALLED</code> state when it has been
- * installed in the Framework but cannot run.
- * <p>
- * This state is visible if the bundle's code dependencies are not resolved.
- * The Framework may attempt to resolve an <code>INSTALLED</code> bundle's
- * code dependencies and move the bundle to the <code>RESOLVED</code>
- * state.
- * <p>
- * The value of <code>INSTALLED</code> is 0x00000002.
- */
- public static final int INSTALLED = 0x00000002;
-
- /**
- * This bundle is resolved and is able to be started.
- *
- * <p>
- * A bundle is in the <code>RESOLVED</code> state when the Framework has
- * successfully resolved the bundle's dependencies. These dependencies
- * include:
- * <ul>
- * <li>The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH}
- * Manifest header.
- * <li>The bundle's package dependencies from its
- * {@link Constants#EXPORT_PACKAGE}and {@link Constants#IMPORT_PACKAGE}
- * Manifest headers.
- * <li>The bundle's required bundle dependencies from its
- * {@link Constants#REQUIRE_BUNDLE}Manifest header.
- * <li>A fragment bundle's host dependency from its
- * {@link Constants#FRAGMENT_HOST}Manifest header.
- * </ul>
- * <p>
- * Note that the bundle is not active yet. A bundle must be put in the
- * <code>RESOLVED</code> state before it can be started. The Framework may
- * attempt to resolve a bundle at any time.
- * <p>
- * The value of <code>RESOLVED</code> is 0x00000004.
- */
- public static final int RESOLVED = 0x00000004;
-
- /**
- * This bundle is in the process of starting.
- *
- * <p>
- * A bundle is in the <code>STARTING</code> state when the {@link #start}
- * method is active. A bundle must be in this state when the bundle's
- * {@link BundleActivator#start}is called. If this method completes without
- * exception, then the bundle has successfully started and must move to the
- * <code>ACTIVE</code> state.
- * <p>
- * The value of <code>STARTING</code> is 0x00000008.
- */
- public static final int STARTING = 0x00000008;
-
- /**
- * This bundle is in the process of stopping.
- *
- * <p>
- * A bundle is in the <code>STOPPING</code> state when the {@link #stop}
- * method is active. A bundle must be in this state when the bundle's
- * {@link BundleActivator#stop}method is called. When this method completes
- * the bundle is stopped and must move to the <code>RESOLVED</code> state.
- * <p>
- * The value of <code>STOPPING</code> is 0x00000010.
- */
- public static final int STOPPING = 0x00000010;
-
- /**
- * This bundle is now running.
- *
- * <p>
- * A bundle is in the <code>ACTIVE</code> state when it has been
- * successfully started.
- * <p>
- * The value of <code>ACTIVE</code> is 0x00000020.
- */
- public static final int ACTIVE = 0x00000020;
-
- /**
- * Returns this bundle's current state.
- *
- * <p>
- * A bundle can be in only one state at any time.
- *
- * @return An element of <code>UNINSTALLED</code>,<code>INSTALLED</code>,
- * <code>RESOLVED</code>,<code>STARTING</code>,
- * <code>STOPPING</code>,<code>ACTIVE</code>.
- */
- public abstract int getState();
-
- /**
- * Starts this bundle.
- *
- * <p>
- * If the Framework implements the optional Start Level service and the
- * current start level is less than this bundle's start level, then the
- * Framework must persistently mark this bundle as started and delay the
- * starting of this bundle until the Framework's current start level becomes
- * equal or more than the bundle's start level.
- * <p>
- * Otherwise, the following steps are required to start a bundle:
- * <ol>
- * <li>If this bundle's state is <code>UNINSTALLED</code> then an
- * <code>IllegalStateException</code> is thrown.
- *
- * <li>If this bundle's state is <code>STARTING</code> or
- * <code>STOPPING</code> then this method must wait for this bundle to
- * change state before continuing. If this does not occur in a reasonable
- * time, a <code>BundleException</code> is thrown to indicate this bundle
- * was unable to be started.
- *
- * <li>If this bundle's state is <code>ACTIVE</code> then this method
- * returns immediately.
- *
- * <li>Persistently record that this bundle has been started. When the
- * Framework is restarted, this bundle must be automatically started.
- *
- * <li>If this bundle's state is not <code>RESOLVED</code>, an attempt
- * is made to resolve this bundle's package dependencies. If the Framework
- * cannot resolve this bundle, a <code>BundleException</code> is thrown.
- *
- * <li>This bundle's state is set to <code>STARTING</code>.
- *
- * <li>The {@link BundleActivator#start}method of this bundle's
- * <code>BundleActivator</code>, if one is specified, is called. If the
- * <code>BundleActivator</code> is invalid or throws an exception, this
- * bundle's state is set back to <code>RESOLVED</code>.<br>
- * Any services registered by the bundle must be unregistered. <br>
- * Any services used by the bundle must be released. <br>
- * Any listeners registered by the bundle must be removed. <br>
- * A <code>BundleException</code> is then thrown.
- *
- * <li>If this bundle's state is <code>UNINSTALLED</code>, because the
- * bundle was uninstalled while the <code>BundleActivator.start</code>
- * method was running, a <code>BundleException</code> is thrown.
- *
- * <li>This bundle's state is set to <code>ACTIVE</code>.
- *
- * <li>A bundle event of type {@link BundleEvent#STARTED}is broadcast.
- * </ol>
- *
- * <b>Preconditions </b>
- * <ul>
- * <li><code>getState()</code> in {<code>INSTALLED</code>}, {
- * <code>RESOLVED</code>}.
- * </ul>
- * <b>Postconditions, no exceptions thrown </b>
- * <ul>
- * <li>Bundle persistent state is marked as active.
- * <li><code>getState()</code> in {<code>ACTIVE</code>}.
- * <li><code>BundleActivator.start()</code> has been called and did not
- * throw an exception.
- * </ul>
- * <b>Postconditions, when an exception is thrown </b>
- * <ul>
- * <li>Depending on when the exception occurred, bundle persistent state is
- * marked as active.
- * <li><code>getState()</code> not in {<code>STARTING</code>}, {
- * <code>ACTIVE</code>}.
- * </ul>
- *
- * @exception BundleException If this bundle could not be started. This
- * could be because a code dependency could not be resolved or
- * the specified <code>BundleActivator</code> could not be
- * loaded or threw an exception.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled or this bundle tries to change its own state.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission[bundle, EXECUTE]</code>,
- * and the Java Runtime Environment supports permissions.
- */
- public abstract void start() throws BundleException;
-
- /**
- * Stops this bundle.
- *
- * <p>
- * The following steps are required to stop a bundle:
- * <ol>
- * <li>If this bundle's state is <code>UNINSTALLED</code> then an
- * <code>IllegalStateException</code> is thrown.
- *
- * <li>If this bundle's state is <code>STARTING</code> or
- * <code>STOPPING</code> then this method must wait for this bundle to
- * change state before continuing. If this does not occur in a reasonable
- * time, a <code>BundleException</code> is thrown to indicate this bundle
- * was unable to be stopped.
- *
- * <li>Persistently record that this bundle has been stopped. When the
- * Framework is restarted, this bundle must not be automatically started.
- *
- * <li>If this bundle's state is not <code>ACTIVE</code> then this method
- * returns immediately.
- *
- * <li>This bundle's state is set to <code>STOPPING</code>.
- *
- * <li>The {@link BundleActivator#stop}method of this bundle's
- * <code>BundleActivator</code>, if one is specified, is called. If that
- * method throws an exception, this method must continue to stop this
- * bundle. A <code>BundleException</code> must be thrown after completion
- * of the remaining steps.
- *
- * <li>Any services registered by this bundle must be unregistered.
- * <li>Any services used by this bundle must be released.
- * <li>Any listeners registered by this bundle must be removed.
- *
- * <li>If this bundle's state is <code>UNINSTALLED</code>, because the
- * bundle was uninstalled while the <code>BundleActivator.stop</code>
- * method was running, a <code>BundleException</code> must be thrown.
- *
- * <li>This bundle's state is set to <code>RESOLVED</code>.
- *
- * <li>A bundle event of type {@link BundleEvent#STOPPED}is broadcast.
- * </ol>
- *
- * <b>Preconditions </b>
- * <ul>
- * <li><code>getState()</code> in {<code>ACTIVE</code>}.
- * </ul>
- * <b>Postconditions, no exceptions thrown </b>
- * <ul>
- * <li>Bundle persistent state is marked as stopped.
- * <li><code>getState()</code> not in {<code>ACTIVE</code>,
- * <code>STOPPING</code>}.
- * <li><code>BundleActivator.stop</code> has been called and did not
- * throw an exception.
- * </ul>
- * <b>Postconditions, when an exception is thrown </b>
- * <ul>
- * <li>Bundle persistent state is marked as stopped.
- * </ul>
- *
- * @exception BundleException If this bundle's <code>BundleActivator</code>
- * could not be loaded or threw an exception.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled or this bundle tries to change its own state.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission[bundle, EXECUTE]</code>,
- * and the Java Runtime Environment supports permissions.
- */
- public abstract void stop() throws BundleException;
-
- /**
- * Updates this bundle.
- *
- * <p>
- * If this bundle's state is <code>ACTIVE</code>, it must be stopped
- * before the update and started after the update successfully completes.
- *
- * <p>
- * If the bundle being updated has exported any packages, these packages
- * must not be updated. Instead, the previous package version must remain
- * exported until the <code>PackageAdmin.refreshPackages</code> method has
- * been has been called or the Framework is relaunched.
- *
- * <p>
- * The following steps are required to update a bundle:
- * <ol>
- * <li>If this bundle's state is <code>UNINSTALLED</code> then an
- * <code>IllegalStateException</code> is thrown.
- *
- * <li>If this bundle's state is <code>ACTIVE</code>,
- * <code>STARTING</code> or <code>STOPPING</code>, the bundle is
- * stopped as described in the <code>Bundle.stop</code> method. If
- * <code>Bundle.stop</code> throws an exception, the exception is rethrown
- * terminating the update.
- *
- * <li>The download location of the new version of this bundle is
- * determined from either the bundle's
- * {@link Constants#BUNDLE_UPDATELOCATION}Manifest header (if available) or
- * the bundle's original location.
- *
- * <li>The location is interpreted in an implementation dependent manner,
- * typically as a URL, and the new version of this bundle is obtained from
- * this location.
- *
- * <li>The new version of this bundle is installed. If the Framework is
- * unable to install the new version of this bundle, the original version of
- * this bundle must be restored and a <code>BundleException</code> must be
- * thrown after completion of the remaining steps.
- *
- * <li>If the bundle has declared an Bundle-RequiredExecutionEnvironment
- * header, then the listed execution environments must be verified against
- * the installed execution environments. If they do not all match, the
- * original version of this bundle must be restored and a
- * <code>BundleException</code> must be thrown after completion of the
- * remaining steps.
- *
- * <li>This bundle's state is set to <code>INSTALLED</code>.
- *
- * <li>If the new version of this bundle was successfully installed, a
- * bundle event of type {@link BundleEvent#UPDATED}is broadcast.
- *
- * <li>If this bundle's state was originally <code>ACTIVE</code>, the
- * updated bundle is started as described in the <code>Bundle.start</code>
- * method. If <code>Bundle.start</code> throws an exception, a Framework
- * event of type {@link FrameworkEvent#ERROR}is broadcast containing the
- * exception.
- * </ol>
- *
- * <b>Preconditions </b>
- * <ul>
- * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
- * </ul>
- * <b>Postconditions, no exceptions thrown </b>
- * <ul>
- * <li><code>getState()</code> in {<code>INSTALLED</code>,
- * <code>RESOLVED</code>,<code>ACTIVE</code>}.
- * <li>This bundle has been updated.
- * </ul>
- * <b>Postconditions, when an exception is thrown </b>
- * <ul>
- * <li><code>getState()</code> in {<code>INSTALLED</code>,
- * <code>RESOLVED</code>,<code>ACTIVE</code>}.
- * <li>Original bundle is still used; no update occurred.
- * </ul>
- *
- * @exception BundleException If the update fails.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled or this bundle tries to change its own state.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission[bundle, LIFECYCLE]</code> for both
- * the current bundle and the updated bundle,
- * and the Java Runtime Environment supports permissions.
- * @see #stop()
- * @see #start()
- */
- public abstract void update() throws BundleException;
-
- /**
- * Updates this bundle from an <code>InputStream</code>.
- *
- * <p>
- * This method performs all the steps listed in <code>Bundle.update()</code>,
- * except the bundle must be read from the supplied <code>InputStream</code>,
- * rather than a <code>URL</code>.
- * <p>
- * This method must always close the <code>InputStream</code> when it is
- * done, even if an exception is thrown.
- *
- * @param in The <code>InputStream</code> from which to read the new
- * bundle.
- * @exception BundleException If the provided stream cannot be read or the
- * update fails.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled or this bundle tries to change its own state.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission[bundle, LIFECYCLE]</code> for both
- * the current bundle and the updated bundle,
- * and the Java Runtime Environment supports permissions.
- * @see #update()
- */
- public abstract void update(InputStream in) throws BundleException;
-
- /**
- * Uninstalls this bundle.
- *
- * <p>
- * This method causes the Framework to notify other bundles that this bundle
- * is being uninstalled, and then puts this bundle into the
- * <code>UNINSTALLED</code> state. The Framework must remove any resources
- * related to this bundle that it is able to remove.
- *
- * <p>
- * If this bundle has exported any packages, the Framework must continue to
- * make these packages available to their importing bundles until the
- * <code>PackageAdmin.refreshPackages</code> method has been called or the
- * Framework is relaunched.
- *
- * <p>
- * The following steps are required to uninstall a bundle:
- * <ol>
- * <li>If this bundle's state is <code>UNINSTALLED</code> then an
- * <code>IllegalStateException</code> is thrown.
- *
- * <li>If this bundle's state is <code>ACTIVE</code>,
- * <code>STARTING</code> or <code>STOPPING</code>, this bundle is
- * stopped as described in the <code>Bundle.stop</code> method. If
- * <code>Bundle.stop</code> throws an exception, a Framework event of type
- * {@link FrameworkEvent#ERROR}is broadcast containing the exception.
- *
- * <li>This bundle's state is set to <code>UNINSTALLED</code>.
- *
- * <li>A bundle event of type {@link BundleEvent#UNINSTALLED}is broadcast.
- *
- * <li>This bundle and any persistent storage area provided for this bundle
- * by the Framework are removed.
- * </ol>
- *
- * <b>Preconditions </b>
- * <ul>
- * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
- * </ul>
- * <b>Postconditions, no exceptions thrown </b>
- * <ul>
- * <li><code>getState()</code> in {<code>UNINSTALLED</code>}.
- * <li>This bundle has been uninstalled.
- * </ul>
- * <b>Postconditions, when an exception is thrown </b>
- * <ul>
- * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
- * <li>This Bundle has not been uninstalled.
- * </ul>
- *
- * @exception BundleException If the uninstall failed. This can occur if
- * another thread is attempting to change the bundle's state and
- * does not complete in a timely manner.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled or this bundle tries to change its own state.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission[bundle, LIFECYCLE]</code>,
- * and the Java Runtime Environment supports permissions.
- * @see #stop()
- */
- public abstract void uninstall() throws BundleException;
-
- /**
- * Returns this bundle's Manifest headers and values. This method returns
- * all the Manifest headers and values from the main section of the bundle's
- * Manifest file; that is, all lines prior to the first blank line.
- *
- * <p>
- * Manifest header names are case-insensitive. The methods of the returned
- * <code>Dictionary</code> object must operate on header names in a
- * case-insensitive manner.
- *
- * If a Manifest header value starts with "%", it must be
- * localized according to the default locale.
- *
- * <p>
- * For example, the following Manifest headers and values are included if
- * they are present in the Manifest file:
- *
- * <pre>
- * Bundle-Name
- * Bundle-Vendor
- * Bundle-Version
- * Bundle-Description
- * Bundle-DocURL
- * Bundle-ContactAddress
- * </pre>
- *
- * <p>
- * This method must continue to return Manifest header information while
- * this bundle is in the <code>UNINSTALLED</code> state.
- *
- * @return A <code>Dictionary</code> object containing this bundle's
- * Manifest headers and values.
- *
- * @exception java.lang.SecurityException If the caller does not have the appropriate
- * <code>AdminPermission[bundle, METADATA]</code>, and the
- * Java Runtime Environment supports permissions.
- *
- * @see Constants#BUNDLE_LOCALIZATION
- */
- public abstract Dictionary getHeaders();
-
- /**
- * Returns this bundle's identifier. The bundle is assigned a unique
- * identifier by the Framework when it is installed in the OSGi environment.
- *
- * <p>
- * A bundle's unique identifier has the following attributes:
- * <ul>
- * <li>Is unique and persistent.
- * <li>Is a <code>long</code>.
- * <li>Its value is not reused for another bundle, even after the bundle is
- * uninstalled.
- * <li>Does not change while the bundle remains installed.
- * <li>Does not change when the bundle is updated.
- * </ul>
- *
- * <p>
- * This method must continue to return this bundle's unique identifier while
- * this bundle is in the <code>UNINSTALLED</code> state.
- *
- * @return The unique identifier of this bundle.
- */
- public abstract long getBundleId();
-
- /**
- * Returns this bundle's location identifier.
- *
- * <p>
- * The bundle location identifier is the location passed to
- * <code>BundleContext.installBundle</code> when a bundle is installed.
- * The bundle location identifier does not change while the bundle remains
- * installed, even if the bundle is updated.
- *
- * <p>
- * This method must continue to return this bundle's location identifier
- * while this bundle is in the <code>UNINSTALLED</code> state.
- *
- * @return The string representation of this bundle's location identifier.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission[bundle, METADATA]</code>,
- * and the Java Runtime Environment supports permissions.
- */
- public abstract String getLocation();
-
- /**
- * Returns this bundle's <code>ServiceReference</code> list for all
- * services it has registered or <code>null</code> if this bundle has no
- * registered services.
- *
- * <p>
- * If the Java runtime supports permissions, a <code>ServiceReference</code>
- * object to a service is included in the returned list only if the caller
- * has the <code>ServicePermission</code> to get the service using at
- * least one of the named classes the service was registered under.
- *
- * <p>
- * The list is valid at the time of the call to this method, however, as the
- * Framework is a very dynamic environment, services can be modified or
- * unregistered at anytime.
- *
- * @return An array of <code>ServiceReference</code> objects or
- * <code>null</code>.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- * @see ServiceRegistration
- * @see ServiceReference
- * @see ServicePermission
- */
- public abstract ServiceReference[] getRegisteredServices();
-
- /**
- * Returns this bundle's <code>ServiceReference</code> list for all
- * services it is using or returns <code>null</code> if this bundle is not
- * using any services. A bundle is considered to be using a service if its
- * use count for that service is greater than zero.
- *
- * <p>
- * If the Java Runtime Environment supports permissions, a
- * <code>ServiceReference</code> object to a service is included in the
- * returned list only if the caller has the <code>ServicePermission</code>
- * to get the service using at least one of the named classes the service
- * was registered under.
- * <p>
- * The list is valid at the time of the call to this method, however, as the
- * Framework is a very dynamic environment, services can be modified or
- * unregistered at anytime.
- *
- * @return An array of <code>ServiceReference</code> objects or
- * <code>null</code>.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- * @see ServiceReference
- * @see ServicePermission
- */
- public abstract ServiceReference[] getServicesInUse();
-
- /**
- * Determines if this bundle has the specified permissions.
- *
- * <p>
- * If the Java Runtime Environment does not support permissions, this method
- * always returns <code>true</code>.
- * <p>
- * <code>permission</code> is of type <code>Object</code> to avoid
- * referencing the <code>java.security.Permission</code> class directly.
- * This is to allow the Framework to be implemented in Java environments
- * which do not support permissions.
- *
- * <p>
- * If the Java Runtime Environment does support permissions, this bundle and
- * all its resources including embedded JAR files, belong to the same
- * <code>java.security.ProtectionDomain</code>; that is, they must share
- * the same set of permissions.
- *
- * @param permission The permission to verify.
- *
- * @return <code>true</code> if this bundle has the specified permission
- * or the permissions possessed by this bundle imply the specified
- * permission; <code>false</code> if this bundle does not have the
- * specified permission or <code>permission</code> is not an
- * <code>instanceof</code> <code>java.security.Permission</code>.
- *
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- */
- public abstract boolean hasPermission(Object permission);
-
- /**
- * Find the specified resource from this bundle.
- *
- * This bundle's class loader is called to search for the named resource. If
- * this bundle's state is <code>INSTALLED</code>, then only this bundle
- * must be searched for the specified resource. Imported packages cannot be
- * searched when a bundle has not been resolved. If this bundle is a
- * fragment bundle then <code>null</code> is returned.
- *
- * @param name The name of the resource. See
- * <code>java.lang.ClassLoader.getResource</code> for a description
- * of the format of a resource name.
- * @return a URL to the named resource, or <code>null</code> if the
- * resource could not be found or if this bundle is a fragment
- * bundle or if the caller does not have the appropriate
- * <code>AdminPermission[bundle, RESOURCE]</code>, and the Java
- * Runtime Environment supports permissions.
- *
- * @since 1.1
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- */
- public abstract URL getResource(String name);
-
- /**
- * Returns this bundle's Manifest headers and values localized to the
- * specifed locale.
- *
- * <p>
- * This method performs the same function as
- * <code>Bundle.getHeaders()</code> except the manifest header values are
- * localized to the specified locale.
- *
- * If a Manifest header value starts with "%", it must be
- * localized according to the specified locale. If the specified locale
- * cannot be found, then the header values must be returned using the
- * default locale.
- *
- * If <code>null</code> is specified as the locale string, the header
- * values must be localized using the default locale. If the empty string
- * ("") is specified as the locale string, the header values must
- * not be localized and the raw (unlocalized) header values, including any
- * leading "%", must be returned.
- *
- * <p>
- * This method must continue to return Manifest header information while
- * this bundle is in the <code>UNINSTALLED</code> state, however the
- * header values must only be available in the raw and default locale
- * values.
- *
- * @param locale The locale name into which the header values are to be
- * localized. If the specified locale is <code>null</code> then the
- * locale returned by <code>java.util.Locale.getDefault</code> is
- * used. If the specified locale is the empty string, this method
- * will return the raw (unlocalized) manifest headers including any
- * leading "%".
- * @return A <code>Dictionary</code> object containing this bundle's
- * Manifest headers and values.
- *
- * @exception java.lang.SecurityException If the caller does not have the appropriate
- * <code>AdminPermission[bundle, METADATA]</code>, and the
- * Java Runtime Environment supports permissions.
- *
- * @see #getHeaders()
- * @see Constants#BUNDLE_LOCALIZATION
- * @since 1.3
- */
- public Dictionary getHeaders(String locale);
-
- /**
- * Returns the symbolic name of this bundle as specified by its
- * <code>Bundle-SymbolicName</code> manifest header. The name must be
- * unique, it is recommended to use a reverse domain name naming convention
- * like that used for java packages. If the bundle does not have a specified
- * symbolic name then <code>null</code> is returned.
- *
- * <p>
- * This method must continue to return this bundle's symbolic name while
- * this bundle is in the <code>UNINSTALLED</code> state.
- *
- * @return The symbolic name of this bundle.
- * @since 1.3
- */
- public String getSymbolicName();
-
- /**
- *
- * Loads the specified class using this bundle's classloader.
- *
- * <p>
- * If the bundle is a fragment bundle then this method must throw a
- * <code>ClassNotFoundException</code>.
- *
- * <p>
- * If this bundle's state is <code>INSTALLED</code>, this method must
- * attempt to resolve the bundle before attempting to load the class.
- *
- * <p>
- * If the bundle cannot be resolved, a Framework event of type
- * {@link FrameworkEvent#ERROR}is broadcast containing a
- * <code>BundleException</code> with details of the reason the bundle
- * could not be resolved. This method must then throw a
- * <code>ClassNotFoundException</code>.
- *
- * <p>
- * If this bundle's state is <code>UNINSTALLED</code>, then an
- * <code>IllegalStateException</code> is thrown.
- *
- * @param name The name of the class to load.
- * @return The Class object for the requested class.
- * @exception java.lang.ClassNotFoundException If no such class can be found
- * or if this bundle is a fragment bundle or if the caller does
- * not have the appropriate <code>AdminPermission[bundle, CLASS]</code>,
- * and the Java Runtime Environment supports permissions.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- * @since 1.3
- */
- public Class loadClass(String name) throws ClassNotFoundException;
-
- /**
- * Find the specified resources from this bundle.
- *
- * This bundle's class loader is called to search for the named resource. If
- * this bundle's state is <code>INSTALLED</code>, then only this bundle
- * must be searched for the specified resource. Imported packages cannot be
- * searched when a bundle has not been resolved. If this bundle is a
- * fragment bundle then <code>null</code> is returned.
- *
- * @param name The name of the resource. See
- * <code>java.lang.ClassLoader.getResources</code> for a
- * description of the format of a resource name.
- * @return an Enumeration of URLs to the named resources, or
- * <code>null</code> if the resource could not be found or if this
- * bundle is a fragment bundle or if the caller does not have the appropriate
- * <code>AdminPermission[bundle, RESOURCE]</code>, and the Java
- * Runtime Environment supports permissions.
- *
- * @since 1.3
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- * @throws java.io.IOException If there is an I/O error.
- */
- public Enumeration getResources(String name) throws IOException;
-
- /**
- * Returns an Enumeration of all the paths (<code>String</code>) objects) to
- * entries within the bundle whose longest sub-path matches the supplied path
- * argument. The bundle's classloader is not used to search for entries. Only
- * the contents of the bundle is searched. A specified path of "/"
- * indicates the root of the bundle.
- *
- * <p>
- * Returned paths indicating subdirectory paths end with a "/".
- * The returned paths are all relative to the root of the bundle.
- *
- * <p>
- * This method returns <code>null</code> if no entries could be found that
- * match the specified path or if the caller does not have the appropriate
- * <code>AdminPermission[bundle, RESOURCE]</code> and the Java
- * Runtime Environment supports permissions.
- *
- * @param path the path name to get the entry path for.
- * @return An Enumeration of the entry paths (<code>String</code> objects)
- * or <code>null</code> if an entry could not be found or if the
- * caller does not have the appropriate <code>AdminPermission[bundle, RESOURCE]</code>
- * and the Java Runtime Environment supports permissions.
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- * @since 1.3
- */
- public Enumeration getEntryPaths(String path);
-
- /**
- * Returns a URL to the specified entry in this bundle. The bundle's
- * classloader is not used to search for the specified entry. Only the
- * contents of the bundle is searched for the specified entry. A specified
- * path of "/" indicates the root of the bundle.
- *
- * <p>
- * This method returns a URL to the specified entry, or <code>null</code>
- * if the entry could not be found or if the caller does not have the appropriate
- * <code>AdminPermission[bundle, RESOURCE]</code> and the Java Runtime
- * Environment supports permissions.
- *
- * @param name The name of the entry. See
- * <code>java.lang.ClassLoader.getResource</code> for a description
- * of the format of a resource name.
- * @return A URL to the specified entry, or <code>null</code> if the entry
- * could not be found or if the caller does not have the appropriate
- * <code>AdminPermission[bundle, RESOURCE]</code> and the Java
- * Runtime Environment supports permissions.
- *
- * @exception java.lang.IllegalStateException If this bundle has been
- * uninstalled.
- * @since 1.3
- */
- public URL getEntry(String name);
-
- /**
- * Returns the time when this bundle was last modified. A bundle is
- * considered to be modified when it is installed, updated or uninstalled.
- *
- * <p>
- * The time value is the number of milliseconds since January 1, 1970,
- * 00:00:00 GMT.
- *
- * @return The time when this bundle was last modified.
- * @since 1.3
- */
- public long getLastModified();
-
- /**
- * Returns entries in this bundle and its attached fragments. The bundle's
- * classloader is not used to search for entries. Only the contents of the
- * bundle and its attached fragments are searched for the specified
- * entries.
- *
- * If this bundle's state is <code>INSTALLED</code>, this method must
- * attempt to resolve the bundle before attempting to find entries.<p>
- *
- * This method is intended to be used to obtain configuration, setup,
- * localization and other information from this bundle. This method takes
- * into account that the "contents" of this bundle can be extended
- * with fragments. This "bundle space" is not a namespace with
- * unique members; the same entry name can be present multiple times. This
- * method therefore returns an enumeration of URL objects. These URLs can
- * come from different JARs but have the same path name. This method can
- * either return only entries in the specified path or recurse into
- * subdirectories returning entries in the directory tree beginning at the
- * specified path. Fragments can be attached after this bundle is resolved,
- * possibly changing the set of URLs returned by this method. If this bundle
- * is not resolved, only the entries in the JAR file of this bundle are
- * returned.
- * <p>
- * Examples:
- * <pre>
- * // List all XML files in the OSGI-INF directory and below
- * Enumeration e = b.findEntries("OSGI-INF", "*.xml", true);
- *
- * // Find a specific localization file
- * Enumeration e = b.findEntries("OSGI-INF/l10n",
- * "bundle_nl_DU.properties", false);
- * if (e.hasMoreElements())
- * return (URL) e.nextElement();
- * </pre>
- *
- * @param path The path name in which to look. A specified path of
- * "/" indicates the root of the bundle. Path is relative
- * to the root of the bundle and must not be null.
- * @param filePattern The file name pattern for selecting entries in the
- * specified path. The pattern is only matched against the last
- * element of the entry path and it supports substring matching, as
- * specified in the Filter specification, using the wildcard
- * character ("*"). If null is specified, this is
- * equivalent to "*" and matches all files.
- * @param recurse If <code>true</code>, recurse into subdirectories.
- * Otherwise only return entries from the given directory.
- * @return An enumeration of URL objects for each matching entry, or
- * <code>null</code> if an entry could not be found or if the
- * caller does not have the appropriate
- * <code>AdminPermission[bundle, RESOURCE]</code>, and the Java
- * Runtime Environment supports permissions. The URLs are sorted
- * such that entries from this bundle are returned first followed by
- * the entries from attached fragments in ascending bundle id order.
- * If this bundle is a fragment, then only matching entries in this
- * fragment are returned.
- * @since 1.3
- */
- public Enumeration findEntries(String path, String filePattern,
- boolean recurse);
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Bundle.java,v 1.35 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+/**
+ * An installed bundle in the Framework.
+ *
+ * <p>
+ * A <code>Bundle</code> object is the access point to define the lifecycle of
+ * an installed bundle. Each bundle installed in the OSGi environment must have
+ * an associated <code>Bundle</code> object.
+ *
+ * <p>
+ * A bundle must have a unique identity, a <code>long</code>, chosen by the
+ * Framework. This identity must not change during the lifecycle of a bundle,
+ * even when the bundle is updated. Uninstalling and then reinstalling the
+ * bundle must create a new unique identity.
+ *
+ * <p>
+ * A bundle can be in one of six states:
+ * <ul>
+ * <li>{@link #UNINSTALLED}
+ * <li>{@link #INSTALLED}
+ * <li>{@link #RESOLVED}
+ * <li>{@link #STARTING}
+ * <li>{@link #STOPPING}
+ * <li>{@link #ACTIVE}
+ * </ul>
+ * <p>
+ * Values assigned to these states have no specified ordering; they represent
+ * bit values that may be ORed together to determine if a bundle is in one of
+ * the valid states.
+ *
+ * <p>
+ * A bundle should only execute code when its state is one of
+ * <code>STARTING</code>,<code>ACTIVE</code>, or <code>STOPPING</code>.
+ * An <code>UNINSTALLED</code> bundle can not be set to another state; it is a
+ * zombie and can only be reached because references are kept somewhere.
+ *
+ * <p>
+ * The Framework is the only entity that is allowed to create
+ * <code>Bundle</code> objects, and these objects are only valid within the
+ * Framework that created them.
+ *
+ * @version $Revision: 1.35 $
+ */
+public interface Bundle {
+ /**
+ * This bundle is uninstalled and may not be used.
+ *
+ * <p>
+ * The <code>UNINSTALLED</code> state is only visible after a bundle is
+ * uninstalled; the bundle is in an unusable state but references to the
+ * <code>Bundle</code> object may still be available and used for
+ * introspection.
+ * <p>
+ * The value of <code>UNINSTALLED</code> is 0x00000001.
+ */
+ public static final int UNINSTALLED = 0x00000001;
+
+ /**
+ * This bundle is installed but not yet resolved.
+ *
+ * <p>
+ * A bundle is in the <code>INSTALLED</code> state when it has been
+ * installed in the Framework but cannot run.
+ * <p>
+ * This state is visible if the bundle's code dependencies are not resolved.
+ * The Framework may attempt to resolve an <code>INSTALLED</code> bundle's
+ * code dependencies and move the bundle to the <code>RESOLVED</code>
+ * state.
+ * <p>
+ * The value of <code>INSTALLED</code> is 0x00000002.
+ */
+ public static final int INSTALLED = 0x00000002;
+
+ /**
+ * This bundle is resolved and is able to be started.
+ *
+ * <p>
+ * A bundle is in the <code>RESOLVED</code> state when the Framework has
+ * successfully resolved the bundle's dependencies. These dependencies
+ * include:
+ * <ul>
+ * <li>The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH}
+ * Manifest header.
+ * <li>The bundle's package dependencies from its
+ * {@link Constants#EXPORT_PACKAGE} and {@link Constants#IMPORT_PACKAGE}
+ * Manifest headers.
+ * <li>The bundle's required bundle dependencies from its
+ * {@link Constants#REQUIRE_BUNDLE} Manifest header.
+ * <li>A fragment bundle's host dependency from its
+ * {@link Constants#FRAGMENT_HOST} Manifest header.
+ * </ul>
+ * <p>
+ * Note that the bundle is not active yet. A bundle must be put in the
+ * <code>RESOLVED</code> state before it can be started. The Framework may
+ * attempt to resolve a bundle at any time.
+ * <p>
+ * The value of <code>RESOLVED</code> is 0x00000004.
+ */
+ public static final int RESOLVED = 0x00000004;
+
+ /**
+ * This bundle is in the process of starting.
+ *
+ * <p>
+ * A bundle is in the <code>STARTING</code> state when the {@link #start}
+ * method is active. A bundle must be in this state when the bundle's
+ * {@link BundleActivator#start} is called. If this method completes without
+ * exception, then the bundle has successfully started and must move to the
+ * <code>ACTIVE</code> state.
+ * <p>
+ * The value of <code>STARTING</code> is 0x00000008.
+ */
+ public static final int STARTING = 0x00000008;
+
+ /**
+ * This bundle is in the process of stopping.
+ *
+ * <p>
+ * A bundle is in the <code>STOPPING</code> state when the {@link #stop}
+ * method is active. A bundle must be in this state when the bundle's
+ * {@link BundleActivator#stop} method is called. When this method completes
+ * the bundle is stopped and must move to the <code>RESOLVED</code> state.
+ * <p>
+ * The value of <code>STOPPING</code> is 0x00000010.
+ */
+ public static final int STOPPING = 0x00000010;
+
+ /**
+ * This bundle is now running.
+ *
+ * <p>
+ * A bundle is in the <code>ACTIVE</code> state when it has been
+ * successfully started.
+ * <p>
+ * The value of <code>ACTIVE</code> is 0x00000020.
+ */
+ public static final int ACTIVE = 0x00000020;
+
+ /**
+ * Returns this bundle's current state.
+ *
+ * <p>
+ * A bundle can be in only one state at any time.
+ *
+ * @return An element of <code>UNINSTALLED</code>,<code>INSTALLED</code>,
+ * <code>RESOLVED</code>,<code>STARTING</code>,
+ * <code>STOPPING</code>,<code>ACTIVE</code>.
+ */
+ public int getState();
+
+ /**
+ * Starts this bundle.
+ *
+ * <p>
+ * If the Framework implements the optional Start Level service and the
+ * current start level is less than this bundle's start level, then the
+ * Framework must persistently mark this bundle as started and delay the
+ * starting of this bundle until the Framework's current start level becomes
+ * equal or more than the bundle's start level.
+ * <p>
+ * Otherwise, the following steps are required to start a bundle:
+ * <ol>
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
+ *
+ * <li>If this bundle's state is <code>STARTING</code> or
+ * <code>STOPPING</code> then this method must wait for this bundle to
+ * change state before continuing. If this does not occur in a reasonable
+ * time, a <code>BundleException</code> is thrown to indicate this bundle
+ * was unable to be started.
+ *
+ * <li>If this bundle's state is <code>ACTIVE</code> then this method
+ * returns immediately.
+ *
+ * <li>Persistently record that this bundle has been started. When the
+ * Framework is restarted, this bundle must be automatically started.
+ *
+ * <li>If this bundle's state is not <code>RESOLVED</code>, an attempt
+ * is made to resolve this bundle's package dependencies. If the Framework
+ * cannot resolve this bundle, a <code>BundleException</code> is thrown.
+ *
+ * <li>This bundle's state is set to <code>STARTING</code>.
+ *
+ * <li>A bundle event of type {@link BundleEvent#STARTING} is fired. This event is only delivered to
+ * <code>SynchronousBundleListener</code>s. It is not delivered to <code>BundleListener</code>s.
+ *
+ * <li>The {@link BundleActivator#start} method of this bundle's
+ * <code>BundleActivator</code>, if one is specified, is called. If the
+ * <code>BundleActivator</code> is invalid or throws an exception, this
+ * bundle's state is set back to <code>RESOLVED</code>.<br>
+ * Any services registered by the bundle must be unregistered. <br>
+ * Any services used by the bundle must be released. <br>
+ * Any listeners registered by the bundle must be removed. <br>
+ * A <code>BundleException</code> is then thrown.
+ *
+ * <li>If this bundle's state is <code>UNINSTALLED</code>, because the
+ * bundle was uninstalled while the <code>BundleActivator.start</code>
+ * method was running, a <code>BundleException</code> is thrown.
+ *
+ * <li>This bundle's state is set to <code>ACTIVE</code>.
+ *
+ * <li>A bundle event of type {@link BundleEvent#STARTED} is fired.
+ * </ol>
+ *
+ * <b>Preconditions </b>
+ * <ul>
+ * <li><code>getState()</code> in {<code>INSTALLED</code>}, {
+ * <code>RESOLVED</code>}.
+ * </ul>
+ * <b>Postconditions, no exceptions thrown </b>
+ * <ul>
+ * <li>Bundle persistent state is marked as active.
+ * <li><code>getState()</code> in {<code>ACTIVE</code>}.
+ * <li><code>BundleActivator.start()</code> has been called and did not
+ * throw an exception.
+ * </ul>
+ * <b>Postconditions, when an exception is thrown </b>
+ * <ul>
+ * <li>Depending on when the exception occurred, bundle persistent state is
+ * marked as active.
+ * <li><code>getState()</code> not in {<code>STARTING</code>}, {
+ * <code>ACTIVE</code>}.
+ * </ul>
+ *
+ * @throws BundleException If this bundle could not be started. This could
+ * be because a code dependency could not be resolved or the
+ * specified <code>BundleActivator</code> could not be loaded or
+ * threw an exception.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled or this bundle tries to change its own state.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,EXECUTE]</code>, and the
+ * Java Runtime Environment supports permissions.
+ */
+ public void start() throws BundleException;
+
+ /**
+ * Stops this bundle.
+ *
+ * <p>
+ * The following steps are required to stop a bundle:
+ * <ol>
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
+ *
+ * <li>If this bundle's state is <code>STARTING</code> or
+ * <code>STOPPING</code> then this method must wait for this bundle to
+ * change state before continuing. If this does not occur in a reasonable
+ * time, a <code>BundleException</code> is thrown to indicate this bundle
+ * was unable to be stopped.
+ *
+ * <li>Persistently record that this bundle has been stopped. When the
+ * Framework is restarted, this bundle must not be automatically started.
+ *
+ * <li>If this bundle's state is not <code>ACTIVE</code> then this method
+ * returns immediately.
+ *
+ * <li>This bundle's state is set to <code>STOPPING</code>.
+ *
+ * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired. This event is only delivered to
+ * <code>SynchronousBundleListener</code>s. It is not delivered to <code>BundleListener</code>s.
+ *
+ * <li>The {@link BundleActivator#stop} method of this bundle's
+ * <code>BundleActivator</code>, if one is specified, is called. If that
+ * method throws an exception, this method must continue to stop this
+ * bundle. A <code>BundleException</code> must be thrown after completion
+ * of the remaining steps.
+ *
+ * <li>Any services registered by this bundle must be unregistered.
+ * <li>Any services used by this bundle must be released.
+ * <li>Any listeners registered by this bundle must be removed.
+ *
+ * <li>If this bundle's state is <code>UNINSTALLED</code>, because the
+ * bundle was uninstalled while the <code>BundleActivator.stop</code>
+ * method was running, a <code>BundleException</code> must be thrown.
+ *
+ * <li>This bundle's state is set to <code>RESOLVED</code>.
+ *
+ * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
+ * </ol>
+ *
+ * <b>Preconditions </b>
+ * <ul>
+ * <li><code>getState()</code> in {<code>ACTIVE</code>}.
+ * </ul>
+ * <b>Postconditions, no exceptions thrown </b>
+ * <ul>
+ * <li>Bundle persistent state is marked as stopped.
+ * <li><code>getState()</code> not in {<code>ACTIVE</code>,
+ * <code>STOPPING</code>}.
+ * <li><code>BundleActivator.stop</code> has been called and did not
+ * throw an exception.
+ * </ul>
+ * <b>Postconditions, when an exception is thrown </b>
+ * <ul>
+ * <li>Bundle persistent state is marked as stopped.
+ * </ul>
+ *
+ * @throws BundleException If this bundle's <code>BundleActivator</code>
+ * could not be loaded or threw an exception.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled or this bundle tries to change its own state.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,EXECUTE]</code>, and the
+ * Java Runtime Environment supports permissions.
+ */
+ public void stop() throws BundleException;
+
+ /**
+ * Updates this bundle.
+ *
+ * <p>
+ * If this bundle's state is <code>ACTIVE</code>, it must be stopped
+ * before the update and started after the update successfully completes.
+ *
+ * <p>
+ * If the bundle being updated has exported any packages, these packages
+ * must not be updated. Instead, the previous package version must remain
+ * exported until the <code>PackageAdmin.refreshPackages</code> method has
+ * been has been called or the Framework is relaunched.
+ *
+ * <p>
+ * The following steps are required to update a bundle:
+ * <ol>
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
+ *
+ * <li>If this bundle's state is <code>ACTIVE</code>,
+ * <code>STARTING</code> or <code>STOPPING</code>, the bundle is
+ * stopped as described in the <code>Bundle.stop</code> method. If
+ * <code>Bundle.stop</code> throws an exception, the exception is rethrown
+ * terminating the update.
+ *
+ * <li>The download location of the new version of this bundle is
+ * determined from either the bundle's
+ * {@link Constants#BUNDLE_UPDATELOCATION} Manifest header (if available) or
+ * the bundle's original location.
+ *
+ * <li>The location is interpreted in an implementation dependent manner,
+ * typically as a URL, and the new version of this bundle is obtained from
+ * this location.
+ *
+ * <li>The new version of this bundle is installed. If the Framework is
+ * unable to install the new version of this bundle, the original version of
+ * this bundle must be restored and a <code>BundleException</code> must be
+ * thrown after completion of the remaining steps.
+ *
+ * <li>If the bundle has declared an Bundle-RequiredExecutionEnvironment
+ * header, then the listed execution environments must be verified against
+ * the installed execution environments. If they do not all match, the
+ * original version of this bundle must be restored and a
+ * <code>BundleException</code> must be thrown after completion of the
+ * remaining steps.
+ *
+ * <li>This bundle's state is set to <code>INSTALLED</code>.
+ *
+ * <li>If the new version of this bundle was successfully installed, a
+ * bundle event of type {@link BundleEvent#UPDATED} is fired.
+ *
+ * <li>If this bundle's state was originally <code>ACTIVE</code>, the
+ * updated bundle is started as described in the <code>Bundle.start</code>
+ * method. If <code>Bundle.start</code> throws an exception, a Framework
+ * event of type {@link FrameworkEvent#ERROR} is fired containing the
+ * exception.
+ * </ol>
+ *
+ * <b>Preconditions </b>
+ * <ul>
+ * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
+ * </ul>
+ * <b>Postconditions, no exceptions thrown </b>
+ * <ul>
+ * <li><code>getState()</code> in {<code>INSTALLED</code>,
+ * <code>RESOLVED</code>,<code>ACTIVE</code>}.
+ * <li>This bundle has been updated.
+ * </ul>
+ * <b>Postconditions, when an exception is thrown </b>
+ * <ul>
+ * <li><code>getState()</code> in {<code>INSTALLED</code>,
+ * <code>RESOLVED</code>,<code>ACTIVE</code>}.
+ * <li>Original bundle is still used; no update occurred.
+ * </ul>
+ *
+ * @throws BundleException If the update fails.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled or this bundle tries to change its own state.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,LIFECYCLE]</code> for both
+ * the current bundle and the updated bundle, and the Java Runtime
+ * Environment supports permissions.
+ * @see #stop()
+ * @see #start()
+ */
+ public void update() throws BundleException;
+
+ /**
+ * Updates this bundle from an <code>InputStream</code>.
+ *
+ * <p>
+ * This method performs all the steps listed in <code>Bundle.update()</code>,
+ * except the bundle must be read from the supplied <code>InputStream</code>,
+ * rather than a <code>URL</code>.
+ * <p>
+ * This method must always close the <code>InputStream</code> when it is
+ * done, even if an exception is thrown.
+ *
+ * @param in The <code>InputStream</code> from which to read the new
+ * bundle.
+ * @throws BundleException If the provided stream cannot be read or the
+ * update fails.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled or this bundle tries to change its own state.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,LIFECYCLE]</code> for both
+ * the current bundle and the updated bundle, and the Java Runtime
+ * Environment supports permissions.
+ * @see #update()
+ */
+ public void update(InputStream in) throws BundleException;
+
+ /**
+ * Uninstalls this bundle.
+ *
+ * <p>
+ * This method causes the Framework to notify other bundles that this bundle
+ * is being uninstalled, and then puts this bundle into the
+ * <code>UNINSTALLED</code> state. The Framework must remove any resources
+ * related to this bundle that it is able to remove.
+ *
+ * <p>
+ * If this bundle has exported any packages, the Framework must continue to
+ * make these packages available to their importing bundles until the
+ * <code>PackageAdmin.refreshPackages</code> method has been called or the
+ * Framework is relaunched.
+ *
+ * <p>
+ * The following steps are required to uninstall a bundle:
+ * <ol>
+ * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+ * <code>IllegalStateException</code> is thrown.
+ *
+ * <li>If this bundle's state is <code>ACTIVE</code>,
+ * <code>STARTING</code> or <code>STOPPING</code>, this bundle is
+ * stopped as described in the <code>Bundle.stop</code> method. If
+ * <code>Bundle.stop</code> throws an exception, a Framework event of type
+ * {@link FrameworkEvent#ERROR} is fired containing the exception.
+ *
+ * <li>This bundle's state is set to <code>UNINSTALLED</code>.
+ *
+ * <li>A bundle event of type {@link BundleEvent#UNINSTALLED} is fired.
+ *
+ * <li>This bundle and any persistent storage area provided for this bundle
+ * by the Framework are removed.
+ * </ol>
+ *
+ * <b>Preconditions </b>
+ * <ul>
+ * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
+ * </ul>
+ * <b>Postconditions, no exceptions thrown </b>
+ * <ul>
+ * <li><code>getState()</code> in {<code>UNINSTALLED</code>}.
+ * <li>This bundle has been uninstalled.
+ * </ul>
+ * <b>Postconditions, when an exception is thrown </b>
+ * <ul>
+ * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
+ * <li>This Bundle has not been uninstalled.
+ * </ul>
+ *
+ * @throws BundleException If the uninstall failed. This can occur if
+ * another thread is attempting to change the bundle's state and
+ * does not complete in a timely manner.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled or this bundle tries to change its own state.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,LIFECYCLE]</code>, and the
+ * Java Runtime Environment supports permissions.
+ * @see #stop()
+ */
+ public void uninstall() throws BundleException;
+
+ /**
+ * Returns this bundle's Manifest headers and values. This method returns
+ * all the Manifest headers and values from the main section of the bundle's
+ * Manifest file; that is, all lines prior to the first blank line.
+ *
+ * <p>
+ * Manifest header names are case-insensitive. The methods of the returned
+ * <code>Dictionary</code> object must operate on header names in a
+ * case-insensitive manner.
+ *
+ * If a Manifest header value starts with "%", it must be
+ * localized according to the default locale.
+ *
+ * <p>
+ * For example, the following Manifest headers and values are included if
+ * they are present in the Manifest file:
+ *
+ * <pre>
+ * Bundle-Name
+ * Bundle-Vendor
+ * Bundle-Version
+ * Bundle-Description
+ * Bundle-DocURL
+ * Bundle-ContactAddress
+ * </pre>
+ *
+ * <p>
+ * This method must continue to return Manifest header information while
+ * this bundle is in the <code>UNINSTALLED</code> state.
+ *
+ * @return A <code>Dictionary</code> object containing this bundle's
+ * Manifest headers and values.
+ *
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,METADATA]</code>, and the
+ * Java Runtime Environment supports permissions.
+ *
+ * @see Constants#BUNDLE_LOCALIZATION
+ */
+ public Dictionary getHeaders();
+
+ /**
+ * Returns this bundle's identifier. The bundle is assigned a unique
+ * identifier by the Framework when it is installed in the OSGi environment.
+ *
+ * <p>
+ * A bundle's unique identifier has the following attributes:
+ * <ul>
+ * <li>Is unique and persistent.
+ * <li>Is a <code>long</code>.
+ * <li>Its value is not reused for another bundle, even after the bundle is
+ * uninstalled.
+ * <li>Does not change while the bundle remains installed.
+ * <li>Does not change when the bundle is updated.
+ * </ul>
+ *
+ * <p>
+ * This method must continue to return this bundle's unique identifier while
+ * this bundle is in the <code>UNINSTALLED</code> state.
+ *
+ * @return The unique identifier of this bundle.
+ */
+ public long getBundleId();
+
+ /**
+ * Returns this bundle's location identifier.
+ *
+ * <p>
+ * The bundle location identifier is the location passed to
+ * <code>BundleContext.installBundle</code> when a bundle is installed.
+ * The bundle location identifier does not change while the bundle remains
+ * installed, even if the bundle is updated.
+ *
+ * <p>
+ * This method must continue to return this bundle's location identifier
+ * while this bundle is in the <code>UNINSTALLED</code> state.
+ *
+ * @return The string representation of this bundle's location identifier.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,METADATA]</code>, and the
+ * Java Runtime Environment supports permissions.
+ */
+ public String getLocation();
+
+ /**
+ * Returns this bundle's <code>ServiceReference</code> list for all
+ * services it has registered or <code>null</code> if this bundle has no
+ * registered services.
+ *
+ * <p>
+ * If the Java runtime supports permissions, a <code>ServiceReference</code>
+ * object to a service is included in the returned list only if the caller
+ * has the <code>ServicePermission</code> to get the service using at
+ * least one of the named classes the service was registered under.
+ *
+ * <p>
+ * The list is valid at the time of the call to this method, however, as the
+ * Framework is a very dynamic environment, services can be modified or
+ * unregistered at anytime.
+ *
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code>.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ * @see ServiceRegistration
+ * @see ServiceReference
+ * @see ServicePermission
+ */
+ public ServiceReference[] getRegisteredServices();
+
+ /**
+ * Returns this bundle's <code>ServiceReference</code> list for all
+ * services it is using or returns <code>null</code> if this bundle is not
+ * using any services. A bundle is considered to be using a service if its
+ * use count for that service is greater than zero.
+ *
+ * <p>
+ * If the Java Runtime Environment supports permissions, a
+ * <code>ServiceReference</code> object to a service is included in the
+ * returned list only if the caller has the <code>ServicePermission</code>
+ * to get the service using at least one of the named classes the service
+ * was registered under.
+ * <p>
+ * The list is valid at the time of the call to this method, however, as the
+ * Framework is a very dynamic environment, services can be modified or
+ * unregistered at anytime.
+ *
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code>.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ * @see ServiceReference
+ * @see ServicePermission
+ */
+ public ServiceReference[] getServicesInUse();
+
+ /**
+ * Determines if this bundle has the specified permissions.
+ *
+ * <p>
+ * If the Java Runtime Environment does not support permissions, this method
+ * always returns <code>true</code>.
+ * <p>
+ * <code>permission</code> is of type <code>Object</code> to avoid
+ * referencing the <code>java.security.Permission</code> class directly.
+ * This is to allow the Framework to be implemented in Java environments
+ * which do not support permissions.
+ *
+ * <p>
+ * If the Java Runtime Environment does support permissions, this bundle and
+ * all its resources including embedded JAR files, belong to the same
+ * <code>java.security.ProtectionDomain</code>; that is, they must share
+ * the same set of permissions.
+ *
+ * @param permission The permission to verify.
+ *
+ * @return <code>true</code> if this bundle has the specified permission
+ * or the permissions possessed by this bundle imply the specified
+ * permission; <code>false</code> if this bundle does not have the
+ * specified permission or <code>permission</code> is not an
+ * <code>instanceof</code> <code>java.security.Permission</code>.
+ *
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ */
+ public boolean hasPermission(Object permission);
+
+ /**
+ * Find the specified resource from this bundle.
+ *
+ * This bundle's class loader is called to search for the specified resource.
+ * If this bundle's state is <code>INSTALLED</code>, this method must
+ * attempt to resolve the bundle before attempting to get the specified resource.
+ * If this bundle cannot be resolved, then only this bundle
+ * must be searched for the specified resource. Imported packages cannot be
+ * searched when a bundle has not been resolved. If this bundle is a
+ * fragment bundle then <code>null</code> is returned.
+ *
+ * @param name The name of the resource. See
+ * <code>java.lang.ClassLoader.getResource</code> for a description
+ * of the format of a resource name.
+ * @return A URL to the named resource, or <code>null</code> if the
+ * resource could not be found or if this bundle is a fragment
+ * bundle or if the caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code>, and the Java Runtime
+ * Environment supports permissions.
+ *
+ * @since 1.1
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ */
+ public URL getResource(String name);
+
+ /**
+ * Returns this bundle's Manifest headers and values localized to the
+ * specified locale.
+ *
+ * <p>
+ * This method performs the same function as
+ * <code>Bundle.getHeaders()</code> except the manifest header values are
+ * localized to the specified locale.
+ *
+ * <p>If a Manifest header value starts with "%", it must be
+ * localized according to the specified locale. If a locale is specified and
+ * cannot be found, then the header values must be returned using the
+ * default locale. Localizations are searched for in the following order:
+ * <pre>
+ * bn + "_" + Ls + "_" + Cs + "_" + Vs
+ * bn + "_" + Ls + "_" + Cs
+ * bn + "_" + Ls
+ * bn + "_" + Ld + "_" + Cd + "_" + Vd
+ * bn + "_" + Ld + "_" + Cd
+ * bn + "_" + Ld
+ * bn
+ * </pre>
+ * Where <code>bn</code> is the bundle localization basename, <code>Ls</code>,
+ * <code>Cs</code> and <code>Vs</code> are the specified locale (language,
+ * country, variant) and <code>Ld</code>, <code>Cd</code> and <code>Vd</code>
+ * are the default locale (language, country, variant).
+ *
+ * If <code>null</code> is specified as the locale string, the header
+ * values must be localized using the default locale. If the empty string
+ * ("") is specified as the locale string, the header values must
+ * not be localized and the raw (unlocalized) header values, including any
+ * leading "%", must be returned.
+ *
+ * <p>
+ * This method must continue to return Manifest header information while
+ * this bundle is in the <code>UNINSTALLED</code> state, however the
+ * header values must only be available in the raw and default locale
+ * values.
+ *
+ * @param locale The locale name into which the header values are to be
+ * localized. If the specified locale is <code>null</code> then the
+ * locale returned by <code>java.util.Locale.getDefault</code> is
+ * used. If the specified locale is the empty string, this method
+ * will return the raw (unlocalized) manifest headers including any
+ * leading "%".
+ * @return A <code>Dictionary</code> object containing this bundle's
+ * Manifest headers and values.
+ *
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[this,METADATA]</code>, and the
+ * Java Runtime Environment supports permissions.
+ *
+ * @see #getHeaders()
+ * @see Constants#BUNDLE_LOCALIZATION
+ * @since 1.3
+ */
+ public Dictionary getHeaders(String locale);
+
+ /**
+ * Returns the symbolic name of this bundle as specified by its
+ * <code>Bundle-SymbolicName</code> manifest header. The name must be
+ * unique, it is recommended to use a reverse domain name naming convention
+ * like that used for java packages. If the bundle does not have a specified
+ * symbolic name then <code>null</code> is returned.
+ *
+ * <p>
+ * This method must continue to return this bundle's symbolic name while
+ * this bundle is in the <code>UNINSTALLED</code> state.
+ *
+ * @return The symbolic name of this bundle.
+ * @since 1.3
+ */
+ public String getSymbolicName();
+
+ /**
+ *
+ * Loads the specified class using this bundle's classloader.
+ *
+ * <p>
+ * If the bundle is a fragment bundle then this method must throw a
+ * <code>ClassNotFoundException</code>.
+ *
+ * <p>
+ * If this bundle's state is <code>INSTALLED</code>, this method must
+ * attempt to resolve the bundle before attempting to load the class.
+ *
+ * <p>
+ * If the bundle cannot be resolved, a Framework event of type
+ * {@link FrameworkEvent#ERROR} is fired containing a
+ * <code>BundleException</code> with details of the reason the bundle
+ * could not be resolved. This method must then throw a
+ * <code>ClassNotFoundException</code>.
+ *
+ * <p>
+ * If this bundle's state is <code>UNINSTALLED</code>, then an
+ * <code>IllegalStateException</code> is thrown.
+ *
+ * @param name The name of the class to load.
+ * @return The Class object for the requested class.
+ * @throws java.lang.ClassNotFoundException If no such class can be found or
+ * if this bundle is a fragment bundle or if the caller does not
+ * have the appropriate <code>AdminPermission[this,CLASS]</code>, and
+ * the Java Runtime Environment supports permissions.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ * @since 1.3
+ */
+ public Class loadClass(String name) throws ClassNotFoundException;
+
+ /**
+ * Find the specified resources from this bundle.
+ *
+ * This bundle's class loader is called to search for the specified resources.
+ * If this bundle's state is <code>INSTALLED</code>, this method must
+ * attempt to resolve the bundle before attempting to get the specified resources.
+ * If this bundle cannot be resolved, then only this bundle
+ * must be searched for the specified resources. Imported packages cannot be
+ * searched when a bundle has not been resolved. If this bundle is a
+ * fragment bundle then <code>null</code> is returned.
+ *
+ * @param name The name of the resource. See
+ * <code>java.lang.ClassLoader.getResources</code> for a
+ * description of the format of a resource name.
+ * @return An enumeration of URLs to the named resources, or
+ * <code>null</code> if the resource could not be found or if this
+ * bundle is a fragment bundle or if the caller does not have the
+ * appropriate <code>AdminPermission[this,RESOURCE]</code>, and the
+ * Java Runtime Environment supports permissions.
+ *
+ * @since 1.3
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ * @throws java.io.IOException If there is an I/O error.
+ */
+ public Enumeration getResources(String name) throws IOException;
+
+ /**
+ * Returns an Enumeration of all the paths (<code>String</code> objects)
+ * to entries within the bundle whose longest sub-path matches the supplied
+ * path argument. The bundle's classloader is not used to search for
+ * entries. Only the contents of the bundle is searched. A specified path of
+ * "/" indicates the root of the bundle.
+ *
+ * <p>
+ * Returned paths indicating subdirectory paths end with a "/".
+ * The returned paths are all relative to the root of the bundle.
+ *
+ * @param path The path name for which to return entry paths.
+ * @return An Enumeration of the entry paths (<code>String</code>
+ * objects) or <code>null</code> if no entry could be found or if
+ * the caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code> and the Java Runtime
+ * Environment supports permissions.
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ * @since 1.3
+ */
+ public Enumeration getEntryPaths(String path);
+
+ /**
+ * Returns a URL to the specified entry in this bundle. The bundle's
+ * classloader is not used to search for the specified entry. Only the
+ * contents of the bundle is searched for the specified entry. A specified
+ * path of "/" indicates the root of the bundle.
+ *
+ * @param name The name of the entry. See
+ * <code>java.lang.ClassLoader.getResource</code> for a description
+ * of the format of a resource name.
+ * @return A URL to the specified entry, or <code>null</code> if no entry
+ * could be found or if the caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code> and the Java Runtime
+ * Environment supports permissions.
+ *
+ * @throws java.lang.IllegalStateException If this bundle has been
+ * uninstalled.
+ * @since 1.3
+ */
+ public URL getEntry(String name);
+
+ /**
+ * Returns the time when this bundle was last modified. A bundle is
+ * considered to be modified when it is installed, updated or uninstalled.
+ *
+ * <p>
+ * The time value is the number of milliseconds since January 1, 1970,
+ * 00:00:00 GMT.
+ *
+ * @return The time when this bundle was last modified.
+ * @since 1.3
+ */
+ public long getLastModified();
+
+ /**
+ * Returns entries in this bundle and its attached fragments. The bundle's
+ * classloader is not used to search for entries. Only the contents of the
+ * bundle and its attached fragments are searched for the specified entries.
+ *
+ * If this bundle's state is <code>INSTALLED</code>, this method must
+ * attempt to resolve the bundle before attempting to find entries.
+ *
+ * <p>
+ * This method is intended to be used to obtain configuration, setup,
+ * localization and other information from this bundle. This method takes
+ * into account that the "contents" of this bundle can be extended
+ * with fragments. This "bundle space" is not a namespace with
+ * unique members; the same entry name can be present multiple times. This
+ * method therefore returns an enumeration of URL objects. These URLs can
+ * come from different JARs but have the same path name. This method can
+ * either return only entries in the specified path or recurse into
+ * subdirectories returning entries in the directory tree beginning at the
+ * specified path. Fragments can be attached after this bundle is resolved,
+ * possibly changing the set of URLs returned by this method. If this bundle
+ * is not resolved, only the entries in the JAR file of this bundle are
+ * returned.
+ * <p>
+ * Examples:
+ *
+ * <pre>
+ * // List all XML files in the OSGI-INF directory and below
+ * Enumeration e = b.findEntries("OSGI-INF", "*.xml", true);
+ *
+ * // Find a specific localization file
+ * Enumeration e = b.findEntries("OSGI-INF/l10n",
+ * "bundle_nl_DU.properties",
+ * false);
+ * if (e.hasMoreElements())
+ * return (URL) e.nextElement();
+ * </pre>
+ *
+ * @param path The path name in which to look. A specified path of
+ * "/" indicates the root of the bundle. Path is relative
+ * to the root of the bundle and must not be null.
+ * @param filePattern The file name pattern for selecting entries in the
+ * specified path. The pattern is only matched against the last
+ * element of the entry path and it supports substring matching, as
+ * specified in the Filter specification, using the wildcard
+ * character ("*"). If null is specified, this is
+ * equivalent to "*" and matches all files.
+ * @param recurse If <code>true</code>, recurse into subdirectories.
+ * Otherwise only return entries from the given directory.
+ * @return An enumeration of URL objects for each matching entry, or
+ * <code>null</code> if an entry could not be found or if the
+ * caller does not have the appropriate
+ * <code>AdminPermission[this,RESOURCE]</code>, and the Java Runtime
+ * Environment supports permissions. The URLs are sorted such that
+ * entries from this bundle are returned first followed by the
+ * entries from attached fragments in ascending bundle id order. If
+ * this bundle is a fragment, then only matching entries in this
+ * fragment are returned.
+ * @since 1.3
+ */
+ public Enumeration findEntries(String path, String filePattern,
+ boolean recurse);
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/framework/BundleActivator.java b/org.osgi/src/main/java/org/osgi/framework/BundleActivator.java
index 8be4194..477647c 100644
--- a/org.osgi/src/main/java/org/osgi/framework/BundleActivator.java
+++ b/org.osgi/src/main/java/org/osgi/framework/BundleActivator.java
@@ -1,82 +1,89 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleActivator.java,v 1.8 2005/06/21 16:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * Customizes the starting and stopping of a bundle.
- * <p>
- * <code>BundleActivator</code> is an interface that may be implemented when a
- * bundle is started or stopped. The Framework can create instances of a
- * bundle's <code>BundleActivator</code> as required. If an instance's
- * <code>BundleActivator.start</code> method executes successfully, it is
- * guaranteed that the same instance's <code>BundleActivator.stop</code> method
- * will be called when the bundle is to be stopped.
- *
- * <p>
- * <code>BundleActivator</code> is specified through the <code>Bundle-Activator</code>
- * Manifest header. A bundle can only specify a single <code>BundleActivator</code>
- * in the Manifest file. Fragment bundles must not have a <code>BundleActivator</code>.
- * The form of the Manifest header is:
- *
- * <pre>
- * Bundle-Activator: <i>class-name</i>
- * </pre>
- *
- * where <code>class-name</code> is a fully qualified Java classname.
- * <p>
- * The specified <code>BundleActivator</code> class must have a public constructor
- * that takes no parameters so that a <code>BundleActivator</code> object can be
- * created by <code>Class.newInstance()</code>.
- *
- * @version $Revision: 1.8 $
- */
-
-public abstract interface BundleActivator {
- /**
- * Called when this bundle is started so the Framework can perform the
- * bundle-specific activities necessary to start this bundle. This method
- * can be used to register services or to allocate any resources that this
- * bundle needs.
- *
- * <p>
- * This method must complete and return to its caller in a timely manner.
- *
- * @param context The execution context of the bundle being started.
- * @exception java.lang.Exception If this method throws an exception, this
- * bundle is marked as stopped and the Framework will remove this
- * bundle's listeners, unregister all services registered by this
- * bundle, and release all services used by this bundle.
- * @see Bundle#start
- */
- public abstract void start(BundleContext context) throws Exception;
-
- /**
- * Called when this bundle is stopped so the Framework can perform the
- * bundle-specific activities necessary to stop the bundle. In general, this
- * method should undo the work that the <code>BundleActivator.start</code>
- * method started. There should be no active threads that were started by
- * this bundle when this bundle returns. A stopped bundle must
- * not call any Framework objects.
- *
- * <p>
- * This method must complete and return to its caller in a timely manner.
- *
- * @param context The execution context of the bundle being stopped.
- * @exception java.lang.Exception If this method throws an exception, the
- * bundle is still marked as stopped, and the Framework will
- * remove the bundle's listeners, unregister all services
- * registered by the bundle, and release all services used by the
- * bundle.
- * @see Bundle#stop
- */
- public abstract void stop(BundleContext context) throws Exception;
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleActivator.java,v 1.10 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * Customizes the starting and stopping of a bundle.
+ * <p>
+ * <code>BundleActivator</code> is an interface that may be implemented when a
+ * bundle is started or stopped. The Framework can create instances of a
+ * bundle's <code>BundleActivator</code> as required. If an instance's
+ * <code>BundleActivator.start</code> method executes successfully, it is
+ * guaranteed that the same instance's <code>BundleActivator.stop</code>
+ * method will be called when the bundle is to be stopped.
+ *
+ * <p>
+ * <code>BundleActivator</code> is specified through the
+ * <code>Bundle-Activator</code> Manifest header. A bundle can only specify a
+ * single <code>BundleActivator</code> in the Manifest file. Fragment bundles
+ * must not have a <code>BundleActivator</code>. The form of the Manifest
+ * header is:
+ *
+ * <pre>
+ * Bundle-Activator: <i>class-name</i>
+ * </pre>
+ *
+ * where <code>class-name</code> is a fully qualified Java classname.
+ * <p>
+ * The specified <code>BundleActivator</code> class must have a public
+ * constructor that takes no parameters so that a <code>BundleActivator</code>
+ * object can be created by <code>Class.newInstance()</code>.
+ *
+ * @version $Revision: 1.10 $
+ */
+
+public interface BundleActivator {
+ /**
+ * Called when this bundle is started so the Framework can perform the
+ * bundle-specific activities necessary to start this bundle. This method
+ * can be used to register services or to allocate any resources that this
+ * bundle needs.
+ *
+ * <p>
+ * This method must complete and return to its caller in a timely manner.
+ *
+ * @param context The execution context of the bundle being started.
+ * @throws java.lang.Exception If this method throws an exception, this
+ * bundle is marked as stopped and the Framework will remove this
+ * bundle's listeners, unregister all services registered by this
+ * bundle, and release all services used by this bundle.
+ * @see Bundle#start
+ */
+ public void start(BundleContext context) throws Exception;
+
+ /**
+ * Called when this bundle is stopped so the Framework can perform the
+ * bundle-specific activities necessary to stop the bundle. In general, this
+ * method should undo the work that the <code>BundleActivator.start</code>
+ * method started. There should be no active threads that were started by
+ * this bundle when this bundle returns. A stopped bundle must not call any
+ * Framework objects.
+ *
+ * <p>
+ * This method must complete and return to its caller in a timely manner.
+ *
+ * @param context The execution context of the bundle being stopped.
+ * @throws java.lang.Exception If this method throws an exception, the
+ * bundle is still marked as stopped, and the Framework will remove
+ * the bundle's listeners, unregister all services registered by the
+ * bundle, and release all services used by the bundle.
+ * @see Bundle#stop
+ */
+ public void stop(BundleContext context) throws Exception;
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/BundleContext.java b/org.osgi/src/main/java/org/osgi/framework/BundleContext.java
index 91fa559..05eeaa2 100644
--- a/org.osgi/src/main/java/org/osgi/framework/BundleContext.java
+++ b/org.osgi/src/main/java/org/osgi/framework/BundleContext.java
@@ -1,790 +1,823 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleContext.java,v 1.13 2005/06/21 16:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Dictionary;
-
-/**
- * A bundle's execution context within the Framework. The context is used to
- * grant access to other methods so that this bundle can interact with the
- * Framework.
- *
- * <p>
- * <code>BundleContext</code> methods allow a bundle to:
- * <ul>
- * <li>Subscribe to events published by the Framework.
- * <li>Register service objects with the Framework service registry.
- * <li>Retrieve <code>ServiceReferences</code> from the Framework service
- * registry.
- * <li>Get and release service objects for a referenced service.
- * <li>Install new bundles in the Framework.
- * <li>Get the list of bundles installed in the Framework.
- * <li>Get the {@link Bundle} object for a bundle.
- * <li>Create <code>File</code> objects for files in a persistent storage area
- * provided for the bundle by the Framework.
- * </ul>
- *
- * <p>
- * A <code>BundleContext</code> object will be created and provided to the bundle
- * associated with this context when it is started using the
- * {@link BundleActivator#start} method. The same <code>BundleContext</code>
- * object will be passed to the bundle associated with this context when it is
- * stopped using the {@link BundleActivator#stop} method. A <code>BundleContext</code>
- * object is generally for the private use of its associated bundle and is not
- * meant to be shared with other bundles in the OSGi environment.
- *
- * <p>
- * The <code>Bundle</code> object associated with a <code>BundleContext</code> object
- * is called the <em>context bundle</em>.
- *
- * <p>
- * The <code>BundleContext</code> object is only valid during the execution
- * of its context bundle; that is, during the period from when the context
- * bundle is in the <code>STARTING</code>, <code>STOPPING</code>, and
- * <code>ACTIVE</code> bundle states. If the <code>BundleContext</code> object
- * is used subsequently, an <code>IllegalStateException</code> must be thrown.
- * The <code>BundleContext</code> object must never be reused after its
- * context bundle is stopped.
- *
- * <p>
- * The Framework is the only entity that can create <code>BundleContext</code>
- * objects and they are only valid within the Framework that created them.
- *
- * @version $Revision: 1.13 $
- */
-
-public abstract interface BundleContext {
- /**
- * Returns the value of the specified property. If the key is not found in
- * the Framework properties, the system properties are then searched. The
- * method returns <code>null</code> if the property is not found.
- *
- * <p>
- * The Framework defines the following standard property keys:
- * </p>
- * <ul>
- * <li>{@link Constants#FRAMEWORK_VERSION}- The OSGi Framework version.
- * </li>
- * <li>{@link Constants#FRAMEWORK_VENDOR}- The Framework implementation
- * vendor.</li>
- * <li>{@link Constants#FRAMEWORK_LANGUAGE}- The language being used. See
- * ISO 639 for possible values.</li>
- * <li>{@link Constants#FRAMEWORK_OS_NAME}- The host computer operating
- * system.</li>
- * <li>{@link Constants#FRAMEWORK_OS_VERSION}- The host computer operating
- * system version number.</li>
- * <li>{@link Constants#FRAMEWORK_PROCESSOR}- The host computer processor
- * name.</li>
- * </ul>
- * <p>
- * All bundles must have permission to read these properties.
- *
- * <p>
- * Note: The last four standard properties are used by the
- * {@link Constants#BUNDLE_NATIVECODE} <code>Manifest</code> header's matching
- * algorithm for selecting native language code.
- *
- * @param key The name of the requested property.
- * @return The value of the requested property, or <code>null</code> if the
- * property is undefined.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>PropertyPermission</code> to read the
- * property, and the Java Runtime Environment supports
- * permissions.
- */
- public abstract String getProperty(String key);
-
- /**
- * Returns the <code>Bundle</code> object associated with this
- * <code>BundleContext</code>. This bundle is called the context bundle.
- *
- * @return The <code>Bundle</code> object associated with this
- * <code>BundleContext</code>.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract Bundle getBundle();
-
- /**
- * Installs a bundle from the specified location string. A bundle is
- * obtained from <code>location</code> as interpreted by the Framework in an
- * implementation dependent manner.
- * <p>
- * Every installed bundle is uniquely identified by its location string,
- * typically in the form of a URL.
- *
- * <p>
- * The following steps are required to install a bundle:
- * <ol>
- * <li>If a bundle containing the same location string is already
- * installed, the <code>Bundle</code> object for that bundle is returned.
- *
- * <li>The bundle's content is read from the location string. If this
- * fails, a {@link BundleException} is thrown.
- *
- * <li>The bundle's <code>Bundle-NativeCode</code> dependencies are resolved.
- * If this fails, a <code>BundleException</code> is thrown.
- *
- * <li>The bundle's associated resources are allocated. The associated
- * resources minimally consist of a unique identifier and a persistent
- * storage area if the platform has file system support. If this step fails,
- * a <code>BundleException</code> is thrown.
- *
- * <li>If the bundle has declared an Bundle-RequiredExecutionEnvironment
- * header, then the listed execution environments must be verified against
- * the installed execution environments. If they are not all present, a
- * <code>BundleException</code> must be thrown.
- *
- * <li>The bundle's state is set to <code>INSTALLED</code>.
- *
- * <li>A bundle event of type {@link BundleEvent#INSTALLED} is broadcast.
- *
- * <li>The <code>Bundle</code> object for the newly or previously installed
- * bundle is returned.
- * </ol>
- *
- * <b>Postconditions, no exceptions thrown </b>
- * <ul>
- * <li><code>getState()</code> in {<code>INSTALLED</code>,<code>RESOLVED</code>}.
- * <li>Bundle has a unique ID.
- * </ul>
- * <b>Postconditions, when an exception is thrown </b>
- * <ul>
- * <li>Bundle is not installed and no trace of the bundle exists.
- * </ul>
- *
- * @param location The location identifier of the bundle to install.
- * @return The <code>Bundle</code> object of the installed bundle.
- * @exception BundleException If the installation failed.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission</code>, and the Java Runtime
- * Environment supports permissions.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract Bundle installBundle(String location)
- throws BundleException;
-
- /**
- * Installs a bundle from the specified <code>InputStream</code> object.
- *
- * <p>
- * This method performs all of the steps listed in
- * <code>BundleContext.installBundle(String location)</code>, except that the
- * bundle's content will be read from the <code>InputStream</code> object. The
- * location identifier string specified will be used as the identity of the
- * bundle.
- *
- * <p>
- * This method must always close the <code>InputStream</code> object, even if
- * an exception is thrown.
- *
- * @param location The location identifier of the bundle to install.
- * @param input The <code>InputStream</code> object from which this bundle
- * will be read.
- * @return The <code>Bundle</code> object of the installed bundle.
- * @exception BundleException If the provided stream cannot be read or the
- * installation failed.
- * @exception java.lang.SecurityException If the caller does not have the
- * appropriate <code>AdminPermission</code>, and the Java Runtime
- * Environment supports permissions.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- * @see #installBundle(java.lang.String)
- */
- public abstract Bundle installBundle(String location, InputStream input)
- throws BundleException;
-
- /**
- * Returns the bundle with the specified identifier.
- *
- * @param id The identifier of the bundle to retrieve.
- * @return A <code>Bundle</code> object or <code>null</code> if the identifier
- * does not match any installed bundle.
- */
- public abstract Bundle getBundle(long id);
-
- /**
- * Returns a list of all installed bundles.
- * <p>
- * This method returns a list of all bundles installed in the OSGi
- * environment at the time of the call to this method. However, since the
- * Framework is a very dynamic environment, bundles can be installed or
- * uninstalled at anytime.
- *
- * @return An array of <code>Bundle</code> objects, one object per installed
- * bundle.
- */
- public abstract Bundle[] getBundles();
-
- /**
- * Adds the specified <code>ServiceListener</code> object with the specified
- * <code>filter</code> to the context bundle's list of listeners.
- * See {@link Filter} for a description of the filter syntax.
- * <code>ServiceListener</code> objects are notified when a service has a
- * lifecycle state change.
- *
- * <p>
- * If the context bundle's list of listeners already contains a listener
- * <code>l</code> such that <code>(l==listener)</code>, then this method replaces
- * that listener's filter (which may be <code>null</code>) with the specified
- * one (which may be <code>null</code>).
- *
- * <p>
- * The listener is called if the filter criteria is met. To filter based
- * upon the class of the service, the filter should reference the
- * {@link Constants#OBJECTCLASS} property. If <code>filter</code> is
- * <code>null</code>, all services are considered to match the filter.
- *
- * <p>
- * When using a <code>filter</code>, it is possible that the
- * <code>ServiceEvent</code>s for the complete lifecycle of a service will
- * not be delivered to the listener. For example, if the <code>filter</code>
- * only matches when the property <code>x</code> has the value <code>1</code>,
- * the listener will not be called if the service is registered with the
- * property <code>x</code> not set to the value <code>1</code>. Subsequently,
- * when the service is modified setting property <code>x</code> to the value
- * <code>1</code>, the filter will match and the listener will be called with
- * a <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the
- * listener will not be called with a <code>ServiceEvent</code> of type
- * <code>REGISTERED</code>.
- *
- * <p>
- * If the Java Runtime Environment supports permissions, the
- * <code>ServiceListener</code> object will be notified of a service event
- * only if the bundle that is registering it has the
- * <code>ServicePermission</code> to get the service using at least one of the
- * named classes the service was registered under.
- *
- * @param listener The <code>ServiceListener</code> object to be added.
- * @param filter The filter criteria.
- *
- * @exception InvalidSyntaxException If <code>filter</code> contains an
- * invalid filter string that cannot be parsed.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- *
- * @see ServiceEvent
- * @see ServiceListener
- * @see ServicePermission
- */
- public abstract void addServiceListener(ServiceListener listener,
- String filter) throws InvalidSyntaxException;
-
- /**
- * Adds the specified <code>ServiceListener</code> object to the context
- * bundle's list of listeners.
- *
- * <p>
- * This method is the same as calling
- * <code>BundleContext.addServiceListener(ServiceListener listener,
- * String filter)</code>
- * with <code>filter</code> set to <code>null</code>.
- *
- * @param listener The <code>ServiceListener</code> object to be added.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- *
- * @see #addServiceListener(ServiceListener, String)
- */
- public abstract void addServiceListener(ServiceListener listener);
-
- /**
- * Removes the specified <code>ServiceListener</code> object from the context
- * bundle's list of listeners.
- *
- * <p>
- * If <code>listener</code> is not contained in this context bundle's list of
- * listeners, this method does nothing.
- *
- * @param listener The <code>ServiceListener</code> to be removed.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract void removeServiceListener(ServiceListener listener);
-
- /**
- * Adds the specified <code>BundleListener</code> object to the context
- * bundle's list of listeners if not already present. BundleListener
- * objects are notified when a bundle has a lifecycle state change.
- *
- * <p>
- * If the context bundle's list of listeners already contains a listener
- * <code>l</code> such that <code>(l==listener)</code>, this method does
- * nothing.
- *
- * @param listener The <code>BundleListener</code> to be added.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- *
- * @see BundleEvent
- * @see BundleListener
- */
- public abstract void addBundleListener(BundleListener listener);
-
- /**
- * Removes the specified <code>BundleListener</code> object from the context
- * bundle's list of listeners.
- *
- * <p>
- * If <code>listener</code> is not contained in the context bundle's list of
- * listeners, this method does nothing.
- *
- * @param listener The <code>BundleListener</code> object to be removed.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract void removeBundleListener(BundleListener listener);
-
- /**
- * Adds the specified <code>FrameworkListener</code> object to the context
- * bundle's list of listeners if not already present.
- * FrameworkListeners are notified of general Framework events.
- *
- * <p>
- * If the context bundle's list of listeners already contains a listener
- * <code>l</code> such that <code>(l==listener)</code>, this method does
- * nothing.
- *
- * @param listener The <code>FrameworkListener</code> object to be added.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- *
- * @see FrameworkEvent
- * @see FrameworkListener
- */
- public abstract void addFrameworkListener(FrameworkListener listener);
-
- /**
- * Removes the specified <code>FrameworkListener</code> object from the
- * context bundle's list of listeners.
- *
- * <p>
- * If <code>listener</code> is not contained in the context bundle's list of
- * listeners, this method does nothing.
- *
- * @param listener The <code>FrameworkListener</code> object to be removed.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract void removeFrameworkListener(FrameworkListener listener);
-
- /**
- * Registers the specified service object with the specified properties
- * under the specified class names into the Framework. A
- * <code>ServiceRegistration</code> object is returned. The
- * <code>ServiceRegistration</code> object is for the private use of the
- * bundle registering the service and should not be shared with other
- * bundles. The registering bundle is defined to be the context bundle.
- * Other bundles can locate the service by using either the
- * {@link #getServiceReferences} or {@link #getServiceReference} method.
- *
- * <p>
- * A bundle can register a service object that implements the
- * {@link ServiceFactory} interface to have more flexibility in providing
- * service objects to other bundles.
- *
- * <p>
- * The following steps are required to register a service:
- * <ol>
- * <li>If <code>service</code> is not a <code>ServiceFactory</code>, an
- * <code>IllegalArgumentException</code> is thrown if <code>service</code> is
- * not an <code>instanceof</code> all the classes named.
- * <li>The Framework adds these service properties to the specified
- * <code>Dictionary</code> (which may be <code>null</code>): a property named
- * {@link Constants#SERVICE_ID} identifying the registration number of the
- * service and a property named {@link Constants#OBJECTCLASS} containing
- * all the specified classes. If any of these properties have already been
- * specified by the registering bundle, their values will be overwritten by
- * the Framework.
- * <li>The service is added to the Framework service registry and may now
- * be used by other bundles.
- * <li>A service event of type {@link ServiceEvent#REGISTERED} is
- * synchronously sent.
- * <li>A <code>ServiceRegistration</code> object for this registration is
- * returned.
- * </ol>
- *
- * @param clazzes The class names under which the service can be located.
- * The class names in this array will be stored in the service's
- * properties under the key {@link Constants#OBJECTCLASS}.
- * @param service The service object or a <code>ServiceFactory</code> object.
- * @param properties The properties for this service. The keys in the
- * properties object must all be <code>String</code> objects. See
- * {@link Constants} for a list of standard service property keys.
- * Changes should not be made to this object after calling this
- * method. To update the service's properties the
- * {@link ServiceRegistration#setProperties} method must be called.
- * The set of properties may be <code>null</code> if the service has no
- * properties.
- *
- * @return A <code>ServiceRegistration</code> object for use by the bundle
- * registering the service to update the service's properties or to
- * unregister the service.
- *
- * @exception java.lang.IllegalArgumentException If one of the following is
- * true:
- * <ul>
- * <li><code>service</code> is <code>null</code>.
- * <li><code>service</code> is not a <code>ServiceFactory</code>
- * object and is not an instance of all the named classes in
- * <code>clazzes</code>.
- * <li><code>properties</code> contains case variants of the same
- * key name.
- * </ul>
- *
- * @exception java.lang.SecurityException If the caller does not have the
- * <code>ServicePermission</code> to register the service for all
- * the named classes and the Java Runtime Environment supports
- * permissions.
- *
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- *
- * @see ServiceRegistration
- * @see ServiceFactory
- */
- public abstract ServiceRegistration registerService(String[] clazzes,
- Object service, Dictionary properties);
-
- /**
- * Registers the specified service object with the specified properties
- * under the specified class name with the Framework.
- *
- * <p>
- * This method is otherwise identical to
- * {@link #registerService(java.lang.String[], java.lang.Object,
- * java.util.Dictionary)} and is provided as a convenience when
- * <code>service</code> will only be registered under a single class name.
- * Note that even in this case the value of the service's
- * {@link Constants#OBJECTCLASS} property will be an array of strings,
- * rather than just a single string.
- *
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- * @see #registerService(java.lang.String[], java.lang.Object,
- * java.util.Dictionary)
- */
- public abstract ServiceRegistration registerService(String clazz,
- Object service, Dictionary properties);
-
- /**
- * Returns an array of <code>ServiceReference</code> objects. The returned
- * array of <code>ServiceReference</code> objects contains services that
- * were registered under the specified class, match the specified filter
- * criteria, and the packages for the class names under which the services
- * were registered match the context bundle's packages as defined in
- * {@link ServiceReference#isAssignableTo(Bundle, String)}.
- *
- * <p>
- * The list is valid at the time of the call to this method, however since the
- * Framework is a very dynamic environment, services can be modified or
- * unregistered at anytime.
- *
- * <p>
- * <code>filter</code> is used to select the registered service whose
- * properties objects contain keys and values which satisfy the filter. See
- * {@link Filter} for a description of the filter string syntax.
- *
- * <p>
- * If <code>filter</code> is <code>null</code>, all registered services are
- * considered to match the filter.
- * If <code>filter</code> cannot be parsed, an {@link InvalidSyntaxException}
- * will be thrown with a human readable message where the filter became
- * unparsable.
- *
- * <p>
- * The following steps are required to select a set of
- * <code>ServiceReference</code> objects:
- * <ol>
- * <li>If the filter string is not <code>null</code>, the filter string is
- * parsed and the set <code>ServiceReference</code> objects of registered
- * services that satisfy the filter is produced. If the filter string is
- * <code>null</code>, then all registered
- * services are considered to satisfy the filter.
- * <li>If the Java Runtime Environment supports permissions, the
- * set of <code>ServiceReference</code> objects produced by the
- * previous step is reduced by checking that the caller has
- * the <code>ServicePermission</code> to get at least one
- * of the class names under which the service was registered. If the caller
- * does not have the correct permission for a particular
- * <code>ServiceReference</code> object, then it is removed from the set.
- * <li>If <code>clazz</code> is not <code>null</code>, the set is further
- * reduced to those services that are an <code>instanceof</code> and were
- * registered under the specified class. The complete list of classes of
- * which a service is an instance and which were specified when the service
- * was registered is available from the service's
- * {@link Constants#OBJECTCLASS} property.
- * <li>The set is reduced one final time by cycling through each
- * <code>ServiceReference</code> object and calling
- * {@link ServiceReference#isAssignableTo(Bundle, String)} with the
- * context bundle and each class name under which the
- * <code>ServiceReference</code> object was registered. For any
- * given <code>ServiceReference</code> object, if any call to
- * {@link ServiceReference#isAssignableTo(Bundle, String)} returns
- * <code>false</code>, then it is removed from the set of
- * <code>ServiceReference</code> objects.
- * <li>An array of the remaining <code>ServiceReference</code> objects
- * is returned.
- * </ol>
- *
- * @param clazz The class name with which the service was registered or
- * <code>null</code> for all services.
- * @param filter The filter criteria.
- * @return An array of <code>ServiceReference</code> objects or <code>null</code>
- * if no services are registered which satisfy the search.
- * @exception InvalidSyntaxException If <code>filter</code> contains an
- * invalid filter string that cannot be parsed.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract ServiceReference[] getServiceReferences(String clazz,
- String filter) throws InvalidSyntaxException;
-
- /**
- * Returns an array of <code>ServiceReference</code> objects. The returned
- * array of <code>ServiceReference</code> objects contains services that
- * were registered under the specified class and match the
- * specified filter criteria.
- *
- * <p>
- * The list is valid at the time of the call to this method, however since the
- * Framework is a very dynamic environment, services can be modified or
- * unregistered at anytime.
- *
- * <p>
- * <code>filter</code> is used to select the registered service whose
- * properties objects contain keys and values which satisfy the filter. See
- * {@link Filter} for a description of the filter string syntax.
- *
- * <p>
- * If <code>filter</code> is <code>null</code>, all registered services are
- * considered to match the filter.
- * If <code>filter</code> cannot be parsed, an {@link InvalidSyntaxException}
- * will be thrown with a human readable message where the filter became
- * unparsable.
- *
- * <p>
- * The following steps are required to select a set of
- * <code>ServiceReference</code> objects:
- * <ol>
- * <li>If the filter string is not <code>null</code>, the filter string is
- * parsed and the set <code>ServiceReference</code> objects of registered
- * services that satisfy the filter is produced. If the filter string is
- * <code>null</code>, then all registered
- * services are considered to satisfy the filter.
- * <li>If the Java Runtime Environment supports permissions, the
- * set of <code>ServiceReference</code> objects produced by the
- * previous step is reduced by checking that the caller has
- * the <code>ServicePermission</code> to get at least one
- * of the class names under which the service was registered. If the caller
- * does not have the correct permission for a particular
- * <code>ServiceReference</code> object, then it is removed from the set.
- * <li>If <code>clazz</code> is not <code>null</code>, the set is further
- * reduced to those services that are an <code>instanceof</code> and were
- * registered under the specified class. The complete list of classes of
- * which a service is an instance and which were specified when the service
- * was registered is available from the service's
- * {@link Constants#OBJECTCLASS} property.
- * <li>An array of the remaining <code>ServiceReference</code> objects
- * is returned.
- * </ol>
- *
- * @param clazz The class name with which the service was registered or
- * <code>null</code> for all services.
- * @param filter The filter criteria.
- * @return An array of <code>ServiceReference</code> objects or <code>null</code>
- * if no services are registered which satisfy the search.
- * @exception InvalidSyntaxException If <code>filter</code> contains an
- * invalid filter string that cannot be parsed.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract ServiceReference[] getAllServiceReferences(String clazz,
- String filter) throws InvalidSyntaxException;
-
- /**
- * Returns a <code>ServiceReference</code> object for a service that
- * implements and was registered under the specified class.
- *
- * <p>
- * This <code>ServiceReference</code> object is valid at the time of the call
- * to this method, however as the Framework is a very dynamic environment,
- * services can be modified or unregistered at anytime.
- *
- * <p>
- * This method is the same as calling
- * {@link BundleContext#getServiceReferences(String, String)} with a
- * <code>null</code> filter string. It is provided as a convenience for when
- * the caller is interested in any service that implements the specified
- * class.
- * <p>
- * If multiple such services exist, the service with the highest ranking (as
- * specified in its {@link Constants#SERVICE_RANKING} property) is returned.
- * <p>
- * If there is a tie in ranking, the service with the lowest service ID (as
- * specified in its {@link Constants#SERVICE_ID} property); that is, the
- * service that was registered first is returned.
- *
- * @param clazz The class name with which the service was registered.
- * @return A <code>ServiceReference</code> object, or <code>null</code> if no
- * services are registered which implement the named class.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- * @see #getServiceReferences(String, String)
- */
- public abstract ServiceReference getServiceReference(String clazz);
-
- /**
- * Returns the specified service object for a service.
- * <p>
- * A bundle's use of a service is tracked by the bundle's use count of that
- * service. Each time a service's service object is returned by
- * {@link #getService(ServiceReference)} the context bundle's use count for
- * that service is incremented by one. Each time the service is released by
- * {@link #ungetService(ServiceReference)} the context bundle's use count
- * for that service is decremented by one.
- * <p>
- * When a bundle's use count for a service drops to zero, the bundle should
- * no longer use that service.
- *
- * <p>
- * This method will always return <code>null</code> when the service
- * associated with this <code>reference</code> has been unregistered.
- *
- * <p>
- * The following steps are required to get the service object:
- * <ol>
- * <li>If the service has been unregistered, <code>null</code> is returned.
- * <li>The context bundle's use count for this service is incremented by
- * one.
- * <li>If the context bundle's use count for the service is currently one
- * and the service was registered with an object implementing the
- * <code>ServiceFactory</code> interface, the
- * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method
- * is called to create a service object for the context bundle. This service
- * object is cached by the Framework. While the context bundle's use count
- * for the service is greater than zero, subsequent calls to get the
- * services's service object for the context bundle will return the cached
- * service object.
- * <br>
- * If the service object returned by the <code>ServiceFactory</code> object is
- * not an <code>instanceof</code> all the classes named when the service was
- * registered or the <code>ServiceFactory</code> object throws an exception,
- * <code>null</code> is returned and a Framework event of type
- * {@link FrameworkEvent#ERROR} is broadcast.
- * <li>The service object for the service is returned.
- * </ol>
- *
- * @param reference A reference to the service.
- * @return A service object for the service associated with
- * <code>reference</code> or <code>null</code> if the service is not
- * registered or does not implement the classes under which it was
- * registered in the case of a <code>ServiceFactory</code>.
- * @exception java.lang.SecurityException If the caller does not have the
- * <code>ServicePermission</code> to get the service using at least
- * one of the named classes the service was registered under and
- * the Java Runtime Environment supports permissions.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- * @see #ungetService(ServiceReference)
- * @see ServiceFactory
- */
- public abstract Object getService(ServiceReference reference);
-
- /**
- * Releases the service object referenced by the specified
- * <code>ServiceReference</code> object. If the context bundle's use count for
- * the service is zero, this method returns <code>false</code>. Otherwise,
- * the context bundle's use count for the service is decremented by one.
- *
- * <p>
- * The service's service object should no longer be used and all references
- * to it should be destroyed when a bundle's use count for the service drops
- * to zero.
- *
- * <p>
- * The following steps are required to unget the service object:
- * <ol>
- * <li>If the context bundle's use count for the service is zero or the
- * service has been unregistered, <code>false</code> is returned.
- * <li>The context bundle's use count for this service is decremented by
- * one.
- * <li>If the context bundle's use count for the service is currently zero
- * and the service was registered with a <code>ServiceFactory</code> object,
- * the {@link ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
- * method is called to release the service object for the context bundle.
- * <li><code>true</code> is returned.
- * </ol>
- *
- * @param reference A reference to the service to be released.
- * @return <code>false</code> if the context bundle's use count for the
- * service is zero or if the service has been unregistered;
- * <code>true</code> otherwise.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- * @see #getService
- * @see ServiceFactory
- */
- public abstract boolean ungetService(ServiceReference reference);
-
- /**
- * Creates a <code>File</code> object for a file in the persistent storage
- * area provided for the bundle by the Framework. This method will return
- * <code>null</code> if the platform does not have file system support.
- *
- * <p>
- * A <code>File</code> object for the base directory of the persistent storage
- * area provided for the context bundle by the Framework can be obtained by
- * calling this method with an empty string as <code>filename</code>.
- *
- * <p>
- * If the Java Runtime Environment supports permissions, the Framework will
- * ensure that the bundle has the <code>java.io.FilePermission</code> with
- * actions <code>read</code>,<code>write</code>,<code>delete</code> for all
- * files (recursively) in the persistent storage area provided for the
- * context bundle.
- *
- * @param filename A relative name to the file to be accessed.
- * @return A <code>File</code> object that represents the requested file or
- * <code>null</code> if the platform does not have file system
- * support.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- */
- public abstract File getDataFile(String filename);
-
- /**
- * Creates a <code>Filter</code> object. This <code>Filter</code> object may be
- * used to match a <code>ServiceReference</code> object or a
- * <code>Dictionary</code> object.
- *
- * <p>
- * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
- * thrown with a human readable message where the filter became unparsable.
- *
- * @param filter The filter string.
- * @return A <code>Filter</code> object encapsulating the filter string.
- * @exception InvalidSyntaxException If <code>filter</code> contains an
- * invalid filter string that cannot be parsed.
- * @exception NullPointerException If <code>filter</code> is null.
- * @exception java.lang.IllegalStateException If this BundleContext is no
- * longer valid.
- *
- * @since 1.1
- * @see "Framework specification for a description of the filter string syntax."
- */
- public abstract Filter createFilter(String filter)
- throws InvalidSyntaxException;
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleContext.java,v 1.18 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Dictionary;
+
+/**
+ * A bundle's execution context within the Framework. The context is used to
+ * grant access to other methods so that this bundle can interact with the
+ * Framework.
+ *
+ * <p>
+ * <code>BundleContext</code> methods allow a bundle to:
+ * <ul>
+ * <li>Subscribe to events published by the Framework.
+ * <li>Register service objects with the Framework service registry.
+ * <li>Retrieve <code>ServiceReferences</code> from the Framework service
+ * registry.
+ * <li>Get and release service objects for a referenced service.
+ * <li>Install new bundles in the Framework.
+ * <li>Get the list of bundles installed in the Framework.
+ * <li>Get the {@link Bundle} object for a bundle.
+ * <li>Create <code>File</code> objects for files in a persistent storage
+ * area provided for the bundle by the Framework.
+ * </ul>
+ *
+ * <p>
+ * A <code>BundleContext</code> object will be created and provided to the
+ * bundle associated with this context when it is started using the
+ * {@link BundleActivator#start} method. The same <code>BundleContext</code>
+ * object will be passed to the bundle associated with this context when it is
+ * stopped using the {@link BundleActivator#stop} method. A
+ * <code>BundleContext</code> object is generally for the private use of its
+ * associated bundle and is not meant to be shared with other bundles in the
+ * OSGi environment.
+ *
+ * <p>
+ * The <code>Bundle</code> object associated with a <code>BundleContext</code>
+ * object is called the <em>context bundle</em>.
+ *
+ * <p>
+ * The <code>BundleContext</code> object is only valid during the execution of
+ * its context bundle; that is, during the period from when the context bundle
+ * is in the <code>STARTING</code>, <code>STOPPING</code>, and
+ * <code>ACTIVE</code> bundle states. If the <code>BundleContext</code>
+ * object is used subsequently, an <code>IllegalStateException</code> must be
+ * thrown. The <code>BundleContext</code> object must never be reused after
+ * its context bundle is stopped.
+ *
+ * <p>
+ * The Framework is the only entity that can create <code>BundleContext</code>
+ * objects and they are only valid within the Framework that created them.
+ *
+ * @version $Revision: 1.18 $
+ */
+
+public interface BundleContext {
+ /**
+ * Returns the value of the specified property. If the key is not found in
+ * the Framework properties, the system properties are then searched. The
+ * method returns <code>null</code> if the property is not found.
+ *
+ * <p>
+ * The Framework defines the following standard property keys:
+ * </p>
+ * <ul>
+ * <li>{@link Constants#FRAMEWORK_VERSION} - The OSGi Framework version.
+ * </li>
+ * <li>{@link Constants#FRAMEWORK_VENDOR} - The Framework implementation
+ * vendor.</li>
+ * <li>{@link Constants#FRAMEWORK_LANGUAGE} - The language being used. See
+ * ISO 639 for possible values.</li>
+ * <li>{@link Constants#FRAMEWORK_OS_NAME} - The host computer operating
+ * system.</li>
+ * <li>{@link Constants#FRAMEWORK_OS_VERSION} - The host computer
+ * operating system version number.</li>
+ * <li>{@link Constants#FRAMEWORK_PROCESSOR} - The host computer processor
+ * name.</li>
+ * </ul>
+ * <p>
+ * All bundles must have permission to read these properties.
+ *
+ * <p>
+ * Note: The last four standard properties are used by the
+ * {@link Constants#BUNDLE_NATIVECODE} <code>Manifest</code> header's
+ * matching algorithm for selecting native language code.
+ *
+ * @param key The name of the requested property.
+ * @return The value of the requested property, or <code>null</code> if
+ * the property is undefined.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>PropertyPermission</code> to read the
+ * property, and the Java Runtime Environment supports permissions.
+ */
+ public String getProperty(String key);
+
+ /**
+ * Returns the <code>Bundle</code> object associated with this
+ * <code>BundleContext</code>. This bundle is called the context bundle.
+ *
+ * @return The <code>Bundle</code> object associated with this
+ * <code>BundleContext</code>.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ */
+ public Bundle getBundle();
+
+ /**
+ * Installs a bundle from the specified location string. A bundle is
+ * obtained from <code>location</code> as interpreted by the Framework in
+ * an implementation dependent manner.
+ * <p>
+ * Every installed bundle is uniquely identified by its location string,
+ * typically in the form of a URL.
+ *
+ * <p>
+ * The following steps are required to install a bundle:
+ * <ol>
+ * <li>If a bundle containing the same location string is already
+ * installed, the <code>Bundle</code> object for that bundle is returned.
+ *
+ * <li>The bundle's content is read from the location string. If this
+ * fails, a {@link BundleException} is thrown.
+ *
+ * <li>The bundle's <code>Bundle-NativeCode</code> dependencies are
+ * resolved. If this fails, a <code>BundleException</code> is thrown.
+ *
+ * <li>The bundle's associated resources are allocated. The associated
+ * resources minimally consist of a unique identifier and a persistent
+ * storage area if the platform has file system support. If this step fails,
+ * a <code>BundleException</code> is thrown.
+ *
+ * <li>If the bundle has declared an Bundle-RequiredExecutionEnvironment
+ * header, then the listed execution environments must be verified against
+ * the installed execution environments. If they are not all present, a
+ * <code>BundleException</code> must be thrown.
+ *
+ * <li>The bundle's state is set to <code>INSTALLED</code>.
+ *
+ * <li>A bundle event of type {@link BundleEvent#INSTALLED} is fired.
+ *
+ * <li>The <code>Bundle</code> object for the newly or previously
+ * installed bundle is returned.
+ * </ol>
+ *
+ * <b>Postconditions, no exceptions thrown </b>
+ * <ul>
+ * <li><code>getState()</code> in {<code>INSTALLED</code>,<code>RESOLVED</code>}.
+ * <li>Bundle has a unique ID.
+ * </ul>
+ * <b>Postconditions, when an exception is thrown </b>
+ * <ul>
+ * <li>Bundle is not installed and no trace of the bundle exists.
+ * </ul>
+ *
+ * @param location The location identifier of the bundle to install.
+ * @return The <code>Bundle</code> object of the installed bundle.
+ * @throws BundleException If the installation failed.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
+ * Java Runtime Environment supports permissions.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ */
+ public Bundle installBundle(String location)
+ throws BundleException;
+
+ /**
+ * Installs a bundle from the specified <code>InputStream</code> object.
+ *
+ * <p>
+ * This method performs all of the steps listed in
+ * <code>BundleContext.installBundle(String location)</code>, except that
+ * the bundle's content will be read from the <code>InputStream</code>
+ * object. The location identifier string specified will be used as the
+ * identity of the bundle.
+ *
+ * <p>
+ * This method must always close the <code>InputStream</code> object, even
+ * if an exception is thrown.
+ *
+ * @param location The location identifier of the bundle to install.
+ * @param input The <code>InputStream</code> object from which this bundle
+ * will be read.
+ * @return The <code>Bundle</code> object of the installed bundle.
+ * @throws BundleException If the provided stream cannot be read or the
+ * installation failed.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * appropriate <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
+ * Java Runtime Environment supports permissions.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @see #installBundle(java.lang.String)
+ */
+ public Bundle installBundle(String location, InputStream input)
+ throws BundleException;
+
+ /**
+ * Returns the bundle with the specified identifier.
+ *
+ * @param id The identifier of the bundle to retrieve.
+ * @return A <code>Bundle</code> object or <code>null</code> if the
+ * identifier does not match any installed bundle.
+ */
+ public Bundle getBundle(long id);
+
+ /**
+ * Returns a list of all installed bundles.
+ * <p>
+ * This method returns a list of all bundles installed in the OSGi
+ * environment at the time of the call to this method. However, since the
+ * Framework is a very dynamic environment, bundles can be installed or
+ * uninstalled at anytime.
+ *
+ * @return An array of <code>Bundle</code> objects, one object per
+ * installed bundle.
+ */
+ public Bundle[] getBundles();
+
+ /**
+ * Adds the specified <code>ServiceListener</code> object with the
+ * specified <code>filter</code> to the context bundle's list of
+ * listeners. See {@link Filter} for a description of the filter syntax.
+ * <code>ServiceListener</code> objects are notified when a service has a
+ * lifecycle state change.
+ *
+ * <p>
+ * If the context bundle's list of listeners already contains a listener
+ * <code>l</code> such that <code>(l==listener)</code>, then this
+ * method replaces that listener's filter (which may be <code>null</code>)
+ * with the specified one (which may be <code>null</code>).
+ *
+ * <p>
+ * The listener is called if the filter criteria is met. To filter based
+ * upon the class of the service, the filter should reference the
+ * {@link Constants#OBJECTCLASS} property. If <code>filter</code> is
+ * <code>null</code>, all services are considered to match the filter.
+ *
+ * <p>
+ * When using a <code>filter</code>, it is possible that the
+ * <code>ServiceEvent</code>s for the complete lifecycle of a service
+ * will not be delivered to the listener. For example, if the
+ * <code>filter</code> only matches when the property <code>x</code> has
+ * the value <code>1</code>, the listener will not be called if the
+ * service is registered with the property <code>x</code> not set to the
+ * value <code>1</code>. Subsequently, when the service is modified
+ * setting property <code>x</code> to the value <code>1</code>, the
+ * filter will match and the listener will be called with a
+ * <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the
+ * listener will not be called with a <code>ServiceEvent</code> of type
+ * <code>REGISTERED</code>.
+ *
+ * <p>
+ * If the Java Runtime Environment supports permissions, the
+ * <code>ServiceListener</code> object will be notified of a service event
+ * only if the bundle that is registering it has the
+ * <code>ServicePermission</code> to get the service using at least one of
+ * the named classes the service was registered under.
+ *
+ * @param listener The <code>ServiceListener</code> object to be added.
+ * @param filter The filter criteria.
+ *
+ * @throws InvalidSyntaxException If <code>filter</code> contains an
+ * invalid filter string that cannot be parsed.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ *
+ * @see ServiceEvent
+ * @see ServiceListener
+ * @see ServicePermission
+ */
+ public void addServiceListener(ServiceListener listener,
+ String filter) throws InvalidSyntaxException;
+
+ /**
+ * Adds the specified <code>ServiceListener</code> object to the context
+ * bundle's list of listeners.
+ *
+ * <p>
+ * This method is the same as calling
+ * <code>BundleContext.addServiceListener(ServiceListener listener,
+ * String filter)</code>
+ * with <code>filter</code> set to <code>null</code>.
+ *
+ * @param listener The <code>ServiceListener</code> object to be added.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ *
+ * @see #addServiceListener(ServiceListener, String)
+ */
+ public void addServiceListener(ServiceListener listener);
+
+ /**
+ * Removes the specified <code>ServiceListener</code> object from the
+ * context bundle's list of listeners.
+ *
+ * <p>
+ * If <code>listener</code> is not contained in this context bundle's list
+ * of listeners, this method does nothing.
+ *
+ * @param listener The <code>ServiceListener</code> to be removed.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ */
+ public void removeServiceListener(ServiceListener listener);
+
+ /**
+ * Adds the specified <code>BundleListener</code> object to the context
+ * bundle's list of listeners if not already present. BundleListener objects
+ * are notified when a bundle has a lifecycle state change.
+ *
+ * <p>
+ * If the context bundle's list of listeners already contains a listener
+ * <code>l</code> such that <code>(l==listener)</code>, this method
+ * does nothing.
+ *
+ * @param listener The <code>BundleListener</code> to be added.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @throws java.lang.SecurityException If listener is a
+ * <code>SynchronousBundleListener</code> and the caller does not
+ * have the appropriate <code>AdminPermission[context bundle,LISTENER]</code>,
+ * and the Java Runtime Environment supports permissions.
+ *
+ * @see BundleEvent
+ * @see BundleListener
+ */
+ public void addBundleListener(BundleListener listener);
+
+ /**
+ * Removes the specified <code>BundleListener</code> object from the
+ * context bundle's list of listeners.
+ *
+ * <p>
+ * If <code>listener</code> is not contained in the context bundle's list
+ * of listeners, this method does nothing.
+ *
+ * @param listener The <code>BundleListener</code> object to be removed.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @throws java.lang.SecurityException If listener is a
+ * <code>SynchronousBundleListener</code> and the caller does not
+ * have the appropriate <code>AdminPermission[context bundle,LISTENER]</code>,
+ * and the Java Runtime Environment supports permissions.
+ */
+ public void removeBundleListener(BundleListener listener);
+
+ /**
+ * Adds the specified <code>FrameworkListener</code> object to the context
+ * bundle's list of listeners if not already present. FrameworkListeners are
+ * notified of general Framework events.
+ *
+ * <p>
+ * If the context bundle's list of listeners already contains a listener
+ * <code>l</code> such that <code>(l==listener)</code>, this method
+ * does nothing.
+ *
+ * @param listener The <code>FrameworkListener</code> object to be added.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ *
+ * @see FrameworkEvent
+ * @see FrameworkListener
+ */
+ public void addFrameworkListener(FrameworkListener listener);
+
+ /**
+ * Removes the specified <code>FrameworkListener</code> object from the
+ * context bundle's list of listeners.
+ *
+ * <p>
+ * If <code>listener</code> is not contained in the context bundle's list
+ * of listeners, this method does nothing.
+ *
+ * @param listener The <code>FrameworkListener</code> object to be
+ * removed.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ */
+ public void removeFrameworkListener(FrameworkListener listener);
+
+ /**
+ * Registers the specified service object with the specified properties
+ * under the specified class names into the Framework. A
+ * <code>ServiceRegistration</code> object is returned. The
+ * <code>ServiceRegistration</code> object is for the private use of the
+ * bundle registering the service and should not be shared with other
+ * bundles. The registering bundle is defined to be the context bundle.
+ * Other bundles can locate the service by using either the
+ * {@link #getServiceReferences} or {@link #getServiceReference} method.
+ *
+ * <p>
+ * A bundle can register a service object that implements the
+ * {@link ServiceFactory} interface to have more flexibility in providing
+ * service objects to other bundles.
+ *
+ * <p>
+ * The following steps are required to register a service:
+ * <ol>
+ * <li>If <code>service</code> is not a <code>ServiceFactory</code>,
+ * an <code>IllegalArgumentException</code> is thrown if
+ * <code>service</code> is not an <code>instanceof</code> all the
+ * classes named.
+ * <li>The Framework adds these service properties to the specified
+ * <code>Dictionary</code> (which may be <code>null</code>): a property
+ * named {@link Constants#SERVICE_ID} identifying the registration number of
+ * the service and a property named {@link Constants#OBJECTCLASS} containing
+ * all the specified classes. If any of these properties have already been
+ * specified by the registering bundle, their values will be overwritten by
+ * the Framework.
+ * <li>The service is added to the Framework service registry and may now
+ * be used by other bundles.
+ * <li>A service event of type {@link ServiceEvent#REGISTERED} is
+ * fired.
+ * <li>A <code>ServiceRegistration</code> object for this registration is
+ * returned.
+ * </ol>
+ *
+ * @param clazzes The class names under which the service can be located.
+ * The class names in this array will be stored in the service's
+ * properties under the key {@link Constants#OBJECTCLASS}.
+ * @param service The service object or a <code>ServiceFactory</code>
+ * object.
+ * @param properties The properties for this service. The keys in the
+ * properties object must all be <code>String</code> objects. See
+ * {@link Constants} for a list of standard service property keys.
+ * Changes should not be made to this object after calling this
+ * method. To update the service's properties the
+ * {@link ServiceRegistration#setProperties} method must be called.
+ * The set of properties may be <code>null</code> if the service
+ * has no properties.
+ *
+ * @return A <code>ServiceRegistration</code> object for use by the bundle
+ * registering the service to update the service's properties or to
+ * unregister the service.
+ *
+ * @throws java.lang.IllegalArgumentException If one of the following is
+ * true:
+ * <ul>
+ * <li><code>service</code> is <code>null</code>.
+ * <li><code>service</code> is not a <code>ServiceFactory</code>
+ * object and is not an instance of all the named classes in
+ * <code>clazzes</code>.
+ * <li><code>properties</code> contains case variants of the same
+ * key name.
+ * </ul>
+ *
+ * @throws java.lang.SecurityException If the caller does not have the
+ * <code>ServicePermission</code> to register the service for all
+ * the named classes and the Java Runtime Environment supports
+ * permissions.
+ *
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ *
+ * @see ServiceRegistration
+ * @see ServiceFactory
+ */
+ public ServiceRegistration registerService(String[] clazzes,
+ Object service, Dictionary properties);
+
+ /**
+ * Registers the specified service object with the specified properties
+ * under the specified class name with the Framework.
+ *
+ * <p>
+ * This method is otherwise identical to
+ * {@link #registerService(java.lang.String[], java.lang.Object,
+ * java.util.Dictionary)} and is provided as a convenience when
+ * <code>service</code> will only be registered under a single class name.
+ * Note that even in this case the value of the service's
+ * {@link Constants#OBJECTCLASS} property will be an array of strings,
+ * rather than just a single string.
+ *
+ * @param clazz The class name under which the service can be located.
+ * @param service The service object or a <code>ServiceFactory</code>
+ * object.
+ * @param properties The properties for this service.
+ *
+ * @return A <code>ServiceRegistration</code> object for use by the bundle
+ * registering the service to update the service's properties or to
+ * unregister the service.
+ *
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @see #registerService(java.lang.String[], java.lang.Object,
+ * java.util.Dictionary)
+ */
+ public ServiceRegistration registerService(String clazz,
+ Object service, Dictionary properties);
+
+ /**
+ * Returns an array of <code>ServiceReference</code> objects. The returned
+ * array of <code>ServiceReference</code> objects contains services that
+ * were registered under the specified class, match the specified filter
+ * criteria, and the packages for the class names under which the services
+ * were registered match the context bundle's packages as defined in
+ * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+ *
+ * <p>
+ * The list is valid at the time of the call to this method, however since
+ * the Framework is a very dynamic environment, services can be modified or
+ * unregistered at anytime.
+ *
+ * <p>
+ * <code>filter</code> is used to select the registered service whose
+ * properties objects contain keys and values which satisfy the filter. See
+ * {@link Filter} for a description of the filter string syntax.
+ *
+ * <p>
+ * If <code>filter</code> is <code>null</code>, all registered services
+ * are considered to match the filter. If <code>filter</code> cannot be
+ * parsed, an {@link InvalidSyntaxException} will be thrown with a human
+ * readable message where the filter became unparsable.
+ *
+ * <p>
+ * The following steps are required to select a set of
+ * <code>ServiceReference</code> objects:
+ * <ol>
+ * <li>If the filter string is not <code>null</code>, the filter string
+ * is parsed and the set <code>ServiceReference</code> objects of
+ * registered services that satisfy the filter is produced. If the filter
+ * string is <code>null</code>, then all registered services are
+ * considered to satisfy the filter.
+ * <li>If the Java Runtime Environment supports permissions, the set of
+ * <code>ServiceReference</code> objects produced by the previous step is
+ * reduced by checking that the caller has the
+ * <code>ServicePermission</code> to get at least one of the class names
+ * under which the service was registered. If the caller does not have the
+ * correct permission for a particular <code>ServiceReference</code>
+ * object, then it is removed from the set.
+ * <li>If <code>clazz</code> is not <code>null</code>, the set is
+ * further reduced to those services that are an <code>instanceof</code>
+ * and were registered under the specified class. The complete list of
+ * classes of which a service is an instance and which were specified when
+ * the service was registered is available from the service's
+ * {@link Constants#OBJECTCLASS} property.
+ * <li>The set is reduced one final time by cycling through each
+ * <code>ServiceReference</code> object and calling
+ * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
+ * bundle and each class name under which the <code>ServiceReference</code>
+ * object was registered. For any given <code>ServiceReference</code>
+ * object, if any call to
+ * {@link ServiceReference#isAssignableTo(Bundle, String)} returns
+ * <code>false</code>, then it is removed from the set of
+ * <code>ServiceReference</code> objects.
+ * <li>An array of the remaining <code>ServiceReference</code> objects is
+ * returned.
+ * </ol>
+ *
+ * @param clazz The class name with which the service was registered or
+ * <code>null</code> for all services.
+ * @param filter The filter criteria.
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code> if no services are registered which satisfy
+ * the search.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an
+ * invalid filter string that cannot be parsed.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ */
+ public ServiceReference[] getServiceReferences(String clazz,
+ String filter) throws InvalidSyntaxException;
+
+ /**
+ * Returns an array of <code>ServiceReference</code> objects. The returned
+ * array of <code>ServiceReference</code> objects contains services that
+ * were registered under the specified class and match the specified filter
+ * criteria.
+ *
+ * <p>
+ * The list is valid at the time of the call to this method, however since
+ * the Framework is a very dynamic environment, services can be modified or
+ * unregistered at anytime.
+ *
+ * <p>
+ * <code>filter</code> is used to select the registered service whose
+ * properties objects contain keys and values which satisfy the filter. See
+ * {@link Filter} for a description of the filter string syntax.
+ *
+ * <p>
+ * If <code>filter</code> is <code>null</code>, all registered services
+ * are considered to match the filter. If <code>filter</code> cannot be
+ * parsed, an {@link InvalidSyntaxException} will be thrown with a human
+ * readable message where the filter became unparsable.
+ *
+ * <p>
+ * The following steps are required to select a set of
+ * <code>ServiceReference</code> objects:
+ * <ol>
+ * <li>If the filter string is not <code>null</code>, the filter string
+ * is parsed and the set <code>ServiceReference</code> objects of
+ * registered services that satisfy the filter is produced. If the filter
+ * string is <code>null</code>, then all registered services are
+ * considered to satisfy the filter.
+ * <li>If the Java Runtime Environment supports permissions, the set of
+ * <code>ServiceReference</code> objects produced by the previous step is
+ * reduced by checking that the caller has the
+ * <code>ServicePermission</code> to get at least one of the class names
+ * under which the service was registered. If the caller does not have the
+ * correct permission for a particular <code>ServiceReference</code>
+ * object, then it is removed from the set.
+ * <li>If <code>clazz</code> is not <code>null</code>, the set is
+ * further reduced to those services that are an <code>instanceof</code>
+ * and were registered under the specified class. The complete list of
+ * classes of which a service is an instance and which were specified when
+ * the service was registered is available from the service's
+ * {@link Constants#OBJECTCLASS} property.
+ * <li>An array of the remaining <code>ServiceReference</code> objects is
+ * returned.
+ * </ol>
+ *
+ * @param clazz The class name with which the service was registered or
+ * <code>null</code> for all services.
+ * @param filter The filter criteria.
+ * @return An array of <code>ServiceReference</code> objects or
+ * <code>null</code> if no services are registered which satisfy
+ * the search.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an
+ * invalid filter string that cannot be parsed.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @since 1.3
+ */
+ public ServiceReference[] getAllServiceReferences(String clazz,
+ String filter) throws InvalidSyntaxException;
+
+ /**
+ * Returns a <code>ServiceReference</code> object for a service that
+ * implements and was registered under the specified class.
+ *
+ * <p>
+ * This <code>ServiceReference</code> object is valid at the time of the
+ * call to this method, however as the Framework is a very dynamic
+ * environment, services can be modified or unregistered at anytime.
+ *
+ * <p>
+ * This method is the same as calling
+ * {@link BundleContext#getServiceReferences(String, String)} with a
+ * <code>null</code> filter string. It is provided as a convenience for
+ * when the caller is interested in any service that implements the
+ * specified class.
+ * <p>
+ * If multiple such services exist, the service with the highest ranking (as
+ * specified in its {@link Constants#SERVICE_RANKING} property) is returned.
+ * <p>
+ * If there is a tie in ranking, the service with the lowest service ID (as
+ * specified in its {@link Constants#SERVICE_ID} property); that is, the
+ * service that was registered first is returned.
+ *
+ * @param clazz The class name with which the service was registered.
+ * @return A <code>ServiceReference</code> object, or <code>null</code>
+ * if no services are registered which implement the named class.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @see #getServiceReferences(String, String)
+ */
+ public ServiceReference getServiceReference(String clazz);
+
+ /**
+ * Returns the specified service object for a service.
+ * <p>
+ * A bundle's use of a service is tracked by the bundle's use count of that
+ * service. Each time a service's service object is returned by
+ * {@link #getService(ServiceReference)} the context bundle's use count for
+ * that service is incremented by one. Each time the service is released by
+ * {@link #ungetService(ServiceReference)} the context bundle's use count
+ * for that service is decremented by one.
+ * <p>
+ * When a bundle's use count for a service drops to zero, the bundle should
+ * no longer use that service.
+ *
+ * <p>
+ * This method will always return <code>null</code> when the service
+ * associated with this <code>reference</code> has been unregistered.
+ *
+ * <p>
+ * The following steps are required to get the service object:
+ * <ol>
+ * <li>If the service has been unregistered, <code>null</code> is
+ * returned.
+ * <li>The context bundle's use count for this service is incremented by
+ * one.
+ * <li>If the context bundle's use count for the service is currently one
+ * and the service was registered with an object implementing the
+ * <code>ServiceFactory</code> interface, the
+ * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
+ * called to create a service object for the context bundle. This service
+ * object is cached by the Framework. While the context bundle's use count
+ * for the service is greater than zero, subsequent calls to get the
+ * services's service object for the context bundle will return the cached
+ * service object. <br>
+ * If the service object returned by the <code>ServiceFactory</code>
+ * object is not an <code>instanceof</code> all the classes named when the
+ * service was registered or the <code>ServiceFactory</code> object throws
+ * an exception, <code>null</code> is returned and a Framework event of
+ * type {@link FrameworkEvent#ERROR} is fired.
+ * <li>The service object for the service is returned.
+ * </ol>
+ *
+ * @param reference A reference to the service.
+ * @return A service object for the service associated with
+ * <code>reference</code> or <code>null</code> if the service is
+ * not registered or does not implement the classes under which it
+ * was registered in the case of a <code>ServiceFactory</code>.
+ * @throws java.lang.SecurityException If the caller does not have the
+ * <code>ServicePermission</code> to get the service using at
+ * least one of the named classes the service was registered under
+ * and the Java Runtime Environment supports permissions.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @see #ungetService(ServiceReference)
+ * @see ServiceFactory
+ */
+ public Object getService(ServiceReference reference);
+
+ /**
+ * Releases the service object referenced by the specified
+ * <code>ServiceReference</code> object. If the context bundle's use count
+ * for the service is zero, this method returns <code>false</code>.
+ * Otherwise, the context bundle's use count for the service is decremented
+ * by one.
+ *
+ * <p>
+ * The service's service object should no longer be used and all references
+ * to it should be destroyed when a bundle's use count for the service drops
+ * to zero.
+ *
+ * <p>
+ * The following steps are required to unget the service object:
+ * <ol>
+ * <li>If the context bundle's use count for the service is zero or the
+ * service has been unregistered, <code>false</code> is returned.
+ * <li>The context bundle's use count for this service is decremented by
+ * one.
+ * <li>If the context bundle's use count for the service is currently zero
+ * and the service was registered with a <code>ServiceFactory</code>
+ * object, the
+ * {@link ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
+ * method is called to release the service object for the context bundle.
+ * <li><code>true</code> is returned.
+ * </ol>
+ *
+ * @param reference A reference to the service to be released.
+ * @return <code>false</code> if the context bundle's use count for the
+ * service is zero or if the service has been unregistered;
+ * <code>true</code> otherwise.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ * @see #getService
+ * @see ServiceFactory
+ */
+ public boolean ungetService(ServiceReference reference);
+
+ /**
+ * Creates a <code>File</code> object for a file in the persistent storage
+ * area provided for the bundle by the Framework. This method will return
+ * <code>null</code> if the platform does not have file system support.
+ *
+ * <p>
+ * A <code>File</code> object for the base directory of the persistent
+ * storage area provided for the context bundle by the Framework can be
+ * obtained by calling this method with an empty string as
+ * <code>filename</code>.
+ *
+ * <p>
+ * If the Java Runtime Environment supports permissions, the Framework will
+ * ensure that the bundle has the <code>java.io.FilePermission</code> with
+ * actions <code>read</code>,<code>write</code>,<code>delete</code>
+ * for all files (recursively) in the persistent storage area provided for
+ * the context bundle.
+ *
+ * @param filename A relative name to the file to be accessed.
+ * @return A <code>File</code> object that represents the requested file
+ * or <code>null</code> if the platform does not have file system
+ * support.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ */
+ public File getDataFile(String filename);
+
+ /**
+ * Creates a <code>Filter</code> object. This <code>Filter</code> object
+ * may be used to match a <code>ServiceReference</code> object or a
+ * <code>Dictionary</code> object.
+ *
+ * <p>
+ * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
+ * thrown with a human readable message where the filter became unparsable.
+ *
+ * @param filter The filter string.
+ * @return A <code>Filter</code> object encapsulating the filter string.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an
+ * invalid filter string that cannot be parsed.
+ * @throws NullPointerException If <code>filter</code> is null.
+ * @throws java.lang.IllegalStateException If this BundleContext is no
+ * longer valid.
+ *
+ * @since 1.1
+ * @see "Framework specification for a description of the filter string syntax."
+ * @see FrameworkUtil#createFilter(String)
+ */
+ public Filter createFilter(String filter)
+ throws InvalidSyntaxException;
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/BundleEvent.java b/org.osgi/src/main/java/org/osgi/framework/BundleEvent.java
index dcd6e8e..a06ea40 100644
--- a/org.osgi/src/main/java/org/osgi/framework/BundleEvent.java
+++ b/org.osgi/src/main/java/org/osgi/framework/BundleEvent.java
@@ -1,146 +1,177 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleEvent.java,v 1.10 2005/05/13 20:32:54 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.EventObject;
-
-/**
- * A Framework event describing a bundle lifecycle change.
- * <p>
- * <code>BundleEvent</code> objects are delivered to <code>BundleListener</code>
- * objects when a change occurs in a bundle's lifecycle. A type code is used to
- * identify the event type for future extendability.
- *
- * <p>
- * OSGi Alliance reserves the right to extend the set of types.
- *
- * @version $Revision: 1.10 $
- */
-
-public class BundleEvent extends EventObject {
- static final long serialVersionUID = 4080640865971756012L;
- /**
- * Bundle that had a change occur in its lifecycle.
- */
- private Bundle bundle;
-
- /**
- * Type of bundle lifecycle change.
- */
- private int type;
-
- /**
- * The bundle has been installed.
- * <p>
- * The value of <code>INSTALLED</code> is 0x00000001.
- *
- * @see BundleContext#installBundle(String)
- */
- public final static int INSTALLED = 0x00000001;
-
- /**
- * The bundle has been started.
- * <p>
- * The value of <code>STARTED</code> is 0x00000002.
- *
- * @see Bundle#start
- */
- public final static int STARTED = 0x00000002;
-
- /**
- * The bundle has been stopped.
- * <p>
- * The value of <code>STOPPED</code> is 0x00000004.
- *
- * @see Bundle#stop
- */
- public final static int STOPPED = 0x00000004;
-
- /**
- * The bundle has been updated.
- * <p>
- * The value of <code>UPDATED</code> is 0x00000008.
- *
- * @see Bundle#update()
- */
- public final static int UPDATED = 0x00000008;
-
- /**
- * The bundle has been uninstalled.
- * <p>
- * The value of <code>UNINSTALLED</code> is 0x00000010.
- *
- * @see Bundle#uninstall
- */
- public final static int UNINSTALLED = 0x00000010;
-
- /**
- * The bundle has been resolved.
- * <p>
- * The value of <code>RESOLVED</code> is 0x00000020.
- *
- * @see Bundle#RESOLVED
- * @since 1.3
- */
- public final static int RESOLVED = 0x00000020;
-
- /**
- * The bundle has been unresolved.
- * <p>
- * The value of <code>UNRESOLVED</code> is 0x00000040.
- *
- * @see Bundle#INSTALLED
- * @since 1.3
- */
- public final static int UNRESOLVED = 0x00000040;
-
- /**
- * Creates a bundle event of the specified type.
- *
- * @param type The event type.
- * @param bundle The bundle which had a lifecycle change.
- */
-
- public BundleEvent(int type, Bundle bundle) {
- super(bundle);
- this.bundle = bundle;
- this.type = type;
- }
-
- /**
- * Returns the bundle which had a lifecycle change. This bundle is the
- * source of the event.
- *
- * @return The bundle that had a change occur in its lifecycle.
- */
- public Bundle getBundle() {
- return bundle;
- }
-
- /**
- * Returns the type of lifecyle event. The type values are:
- * <ul>
- * <li>{@link #INSTALLED}
- * <li>{@link #STARTED}
- * <li>{@link #STOPPED}
- * <li>{@link #UPDATED}
- * <li>{@link #UNINSTALLED}
- * <li>{@link #RESOLVED}
- * <li>{@link #UNRESOLVED}
- * </ul>
- *
- * @return The type of lifecycle event.
- */
-
- public int getType() {
- return type;
- }
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleEvent.java,v 1.14 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.EventObject;
+
+/**
+ * An event from the Framework describing a bundle lifecycle change.
+ * <p>
+ * <code>BundleEvent</code> objects are delivered to
+ * <code>BundleListener</code> objects when a change occurs in a bundle's
+ * lifecycle. A type code is used to identify the event type for future
+ * extendability.
+ *
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ *
+ * @version $Revision: 1.14 $
+ */
+
+public class BundleEvent extends EventObject {
+ static final long serialVersionUID = 4080640865971756012L;
+ /**
+ * Bundle that had a change occur in its lifecycle.
+ */
+ private Bundle bundle;
+
+ /**
+ * Type of bundle lifecycle change.
+ */
+ private int type;
+
+ /**
+ * The bundle has been installed.
+ * <p>
+ * The value of <code>INSTALLED</code> is 0x00000001.
+ *
+ * @see BundleContext#installBundle(String)
+ */
+ public final static int INSTALLED = 0x00000001;
+
+ /**
+ * The bundle has been started.
+ * <p>
+ * The value of <code>STARTED</code> is 0x00000002.
+ *
+ * @see Bundle#start
+ */
+ public final static int STARTED = 0x00000002;
+
+ /**
+ * The bundle has been stopped.
+ * <p>
+ * The value of <code>STOPPED</code> is 0x00000004.
+ *
+ * @see Bundle#stop
+ */
+ public final static int STOPPED = 0x00000004;
+
+ /**
+ * The bundle has been updated.
+ * <p>
+ * The value of <code>UPDATED</code> is 0x00000008.
+ *
+ * @see Bundle#update()
+ */
+ public final static int UPDATED = 0x00000008;
+
+ /**
+ * The bundle has been uninstalled.
+ * <p>
+ * The value of <code>UNINSTALLED</code> is 0x00000010.
+ *
+ * @see Bundle#uninstall
+ */
+ public final static int UNINSTALLED = 0x00000010;
+
+ /**
+ * The bundle has been resolved.
+ * <p>
+ * The value of <code>RESOLVED</code> is 0x00000020.
+ *
+ * @see Bundle#RESOLVED
+ * @since 1.3
+ */
+ public final static int RESOLVED = 0x00000020;
+
+ /**
+ * The bundle has been unresolved.
+ * <p>
+ * The value of <code>UNRESOLVED</code> is 0x00000040.
+ *
+ * @see Bundle#INSTALLED
+ * @since 1.3
+ */
+ public final static int UNRESOLVED = 0x00000040;
+
+ /**
+ * The bundle is about to start.
+ * <p>
+ * The value of <code>STARTING</code> is 0x00000080.
+ *
+ * @see Bundle#start()
+ * @since 1.3
+ */
+ public final static int STARTING = 0x00000080;
+
+ /**
+ * The bundle is about to stop.
+ * <p>
+ * The value of <code>STOPPING</code> is 0x00000100.
+ *
+ * @see Bundle#stop()
+ * @since 1.3
+ */
+ public final static int STOPPING = 0x00000100;
+
+ /**
+ * Creates a bundle event of the specified type.
+ *
+ * @param type The event type.
+ * @param bundle The bundle which had a lifecycle change.
+ */
+
+ public BundleEvent(int type, Bundle bundle) {
+ super(bundle);
+ this.bundle = bundle;
+ this.type = type;
+ }
+
+ /**
+ * Returns the bundle which had a lifecycle change. This bundle is the
+ * source of the event.
+ *
+ * @return The bundle that had a change occur in its lifecycle.
+ */
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ /**
+ * Returns the type of lifecyle event. The type values are:
+ * <ul>
+ * <li>{@link #INSTALLED}
+ * <li>{@link #RESOLVED}
+ * <li>{@link #STARTING}
+ * <li>{@link #STARTED}
+ * <li>{@link #STOPPING}
+ * <li>{@link #STOPPED}
+ * <li>{@link #UPDATED}
+ * <li>{@link #UNRESOLVED}
+ * <li>{@link #UNINSTALLED}
+ * </ul>
+ *
+ * @return The type of lifecycle event.
+ */
+
+ public int getType() {
+ return type;
+ }
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/framework/BundleException.java b/org.osgi/src/main/java/org/osgi/framework/BundleException.java
index c6cade1..442c673 100644
--- a/org.osgi/src/main/java/org/osgi/framework/BundleException.java
+++ b/org.osgi/src/main/java/org/osgi/framework/BundleException.java
@@ -1,95 +1,106 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleException.java,v 1.10 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * A Framework exception used to indicate that a bundle lifecycle problem
- * occurred.
- *
- * <p>
- * <code>BundleException</code> object is created by the Framework to denote an
- * exception condition in the lifecycle of a bundle. <code>BundleException</code>s
- * should not be created by bundle developers.
- *
- * <p>
- * This exception is updated to conform to the general purpose exception
- * chaining mechanism.
- *
- * @version $Revision: 1.10 $
- */
-
-public class BundleException extends Exception {
- static final long serialVersionUID = 3571095144220455665L;
- /**
- * Nested exception.
- */
- private Throwable cause;
-
- /**
- * Creates a <code>BundleException</code> that wraps another exception.
- *
- * @param msg The associated message.
- * @param cause The cause of this exception.
- */
- public BundleException(String msg, Throwable cause) {
- super(msg);
- this.cause = cause;
- }
-
- /**
- * Creates a <code>BundleException</code> object with the specified message.
- *
- * @param msg The message.
- */
- public BundleException(String msg) {
- super(msg);
- this.cause = null;
- }
-
- /**
- * Returns any nested exceptions included in this exception.
- *
- * <p>
- * This method predates the general purpose exception chaining mechanism.
- * The {@link #getCause()} method is now the preferred means of obtaining
- * this information.
- *
- * @return The nested exception; <code>null</code> if there is no nested
- * exception.
- */
- public Throwable getNestedException() {
- return 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.3
- */
- public Throwable getCause() {
- return cause;
- }
-
- /**
- * The cause of this exception can only be set when constructed.
- *
- * @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.3
- */
- public Throwable initCause(Throwable cause) {
- throw new IllegalStateException();
- }
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleException.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * A Framework exception used to indicate that a bundle lifecycle problem
+ * occurred.
+ *
+ * <p>
+ * <code>BundleException</code> object is created by the Framework to denote
+ * an exception condition in the lifecycle of a bundle.
+ * <code>BundleException</code>s should not be created by bundle developers.
+ *
+ * <p>
+ * This exception is updated to conform to the general purpose exception
+ * chaining mechanism.
+ *
+ * @version $Revision: 1.13 $
+ */
+
+public class BundleException extends Exception {
+ static final long serialVersionUID = 3571095144220455665L;
+ /**
+ * Nested exception.
+ */
+ private Throwable cause;
+
+ /**
+ * Creates a <code>BundleException</code> that wraps another exception.
+ *
+ * @param msg The associated message.
+ * @param cause The cause of this exception.
+ */
+ public BundleException(String msg, Throwable cause) {
+ super(msg);
+ this.cause = cause;
+ }
+
+ /**
+ * Creates a <code>BundleException</code> object with the specified
+ * message.
+ *
+ * @param msg The message.
+ */
+ public BundleException(String msg) {
+ super(msg);
+ this.cause = null;
+ }
+
+ /**
+ * Returns any nested exceptions included in this exception.
+ *
+ * <p>
+ * This method predates the general purpose exception chaining mechanism.
+ * The {@link #getCause()} method is now the preferred means of obtaining
+ * this information.
+ *
+ * @return The nested exception; <code>null</code> if there is no nested
+ * exception.
+ */
+ public Throwable getNestedException() {
+ return 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.3
+ */
+ 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.3
+ */
+ public Throwable initCause(Throwable cause) {
+ throw new IllegalStateException();
+ }
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/framework/BundleListener.java b/org.osgi/src/main/java/org/osgi/framework/BundleListener.java
index 88c38aa..e5418de 100644
--- a/org.osgi/src/main/java/org/osgi/framework/BundleListener.java
+++ b/org.osgi/src/main/java/org/osgi/framework/BundleListener.java
@@ -1,38 +1,48 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleListener.java,v 1.7 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.EventListener;
-
-/**
- * A <code>BundleEvent</code> listener.
- *
- * <p>
- * <code>BundleListener</code> is a listener interface that may be implemented by
- * a bundle developer.
- * <p>
- * A <code>BundleListener</code> object is registered with the Framework using the
- * {@link BundleContext#addBundleListener} method. <code>BundleListener</code>s
- * are called with a <code>BundleEvent</code> object when a bundle has been
- * installed, resolved, started, stopped, updated, unresolved, or uninstalled.
- *
- * @version $Revision: 1.7 $
- * @see BundleEvent
- */
-
-public abstract interface BundleListener extends EventListener {
- /**
- * Receives notification that a bundle has had a lifecycle change.
- *
- * @param event The <code>BundleEvent</code>.
- */
- public abstract void bundleChanged(BundleEvent event);
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundleListener.java,v 1.10 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.EventListener;
+
+/**
+ * A <code>BundleEvent</code> listener. When a <code>BundleEvent</code> is
+ * fired, it is asynchronously delivered to a <code>BundleListener</code>.
+ *
+ * <p>
+ * <code>BundleListener</code> is a listener interface that may be implemented
+ * by a bundle developer.
+ * <p>
+ * A <code>BundleListener</code> object is registered with the Framework using
+ * the {@link BundleContext#addBundleListener} method.
+ * <code>BundleListener</code>s are called with a <code>BundleEvent</code>
+ * object when a bundle has been installed, resolved, started, stopped, updated,
+ * unresolved, or uninstalled.
+ *
+ * @version $Revision: 1.10 $
+ * @see BundleEvent
+ */
+
+public interface BundleListener extends EventListener {
+ /**
+ * Receives notification that a bundle has had a lifecycle change.
+ *
+ * @param event The <code>BundleEvent</code>.
+ */
+ public void bundleChanged(BundleEvent event);
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/BundlePermission.java b/org.osgi/src/main/java/org/osgi/framework/BundlePermission.java
index 8548b81..ccf8e1e 100644
--- a/org.osgi/src/main/java/org/osgi/framework/BundlePermission.java
+++ b/org.osgi/src/main/java/org/osgi/framework/BundlePermission.java
@@ -1,579 +1,583 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundlePermission.java,v 1.10 2005/06/21 16:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.io.IOException;
-import java.security.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-/**
- * A bundle's authority to require or provide a bundle or to receive or attach
- * fragments.
- *
- * <p>
- * A bundle symbolic name defines a unique fully qualified name.
- * <p>
- * For example:
- *
- * <pre>
- * <code>
- * org.osgi.example.bundle
- * </code>
- * </pre>
- *
- * <p>
- * <code>BundlePermission</code> has four actions: <code>PROVIDE</code>,
- * <code>REQUIRE</code>,<code>HOST</code>, and <code>FRAGMENT</code>.
- * The <code>PROVIDE</code> action implies the <code>REQUIRE</code> action.
- *
- * @since 1.3
- */
-
-public final class BundlePermission extends BasicPermission {
-
- private static final long serialVersionUID = 3257846601685873716L;
-
- /**
- * The action string <code>provide</code>.
- */
- public final static String PROVIDE = "provide";
-
- /**
- * The action string <code>require</code>.
- */
- public final static String REQUIRE = "require";
-
- /**
- * The action string <code>host</code>.
- */
- public final static String HOST = "host";
-
- /**
- * The action string <code>fragment</code>.
- */
- public final static String FRAGMENT = "fragment";
-
- private final static int ACTION_PROVIDE = 0x00000001;
- private final static int ACTION_REQUIRE = 0x00000002;
- private final static int ACTION_HOST = 0x00000004;
- private final static int ACTION_FRAGMENT = 0x00000008;
- private final static int ACTION_ALL = ACTION_PROVIDE
- | ACTION_REQUIRE
- | ACTION_HOST
- | ACTION_FRAGMENT;
- private final static int ACTION_NONE = 0;
-// NOT USED!!!
-// private final static int ACTION_ERROR = 0x80000000;
-
- /**
- * The actions mask.
- */
- private transient int action_mask = ACTION_NONE;
-
- /**
- * The actions in canonical form.
- *
- * @serial
- */
- private String actions = null;
-
- /**
- * Defines the authority to provide and/or require and or specify a host
- * fragment symbolic name within the OSGi environment.
- * <p>
- * Bundle Permissions are granted over all possible versions of a bundle.
- *
- * A bundle that needs to provide a bundle must have the appropriate
- * <code>BundlePermission</code> for the symbolic name; a bundle that
- * requires a bundle must have the appropriate <code>BundlePermssion</code>
- * for that symbolic name; a bundle that specifies a fragment host must have
- * the appropriate <code>BundlePermission</code> for that symbolic name.
- *
- * @param symbolicName the bundle symbolic name.
- * @param actions <code>PROVIDE</code>,<code>REQUIRE</code>,
- * <code>HOST</code>,<code>FRAGMENT</code> (canonical order).
- */
-
- public BundlePermission(String symbolicName, String actions) {
- this(symbolicName, getMask(actions));
- }
-
- /**
- * Bundle private constructor used by BundlePermissionCollection.
- *
- * @param symbolicName the bundle symbolic name
- * @param mask the action mask
- */
- BundlePermission(String symbolicName, int mask) {
- super(symbolicName);
- init(mask);
- }
-
- /**
- * Called by constructors and when deserialized.
- *
- * @param mask
- */
- private void init(int mask) {
- if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
- throw new IllegalArgumentException("invalid action string");
- }
-
- action_mask = mask;
- }
-
- /**
- * Parse action string into 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 >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
- && (a[i - 5] == 'r' || a[i - 5] == 'R')
- && (a[i - 4] == 'o' || a[i - 4] == 'O')
- && (a[i - 3] == 'v' || a[i - 3] == 'V')
- && (a[i - 2] == 'i' || a[i - 2] == 'I')
- && (a[i - 1] == 'd' || a[i - 1] == 'D')
- && (a[i] == 'e' || a[i] == 'E')) {
- matchlen = 7;
- mask |= ACTION_PROVIDE | ACTION_REQUIRE;
- }
- else
- if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
- && (a[i - 5] == 'e' || a[i - 5] == 'E')
- && (a[i - 4] == 'q' || a[i - 4] == 'Q')
- && (a[i - 3] == 'u' || a[i - 3] == 'U')
- && (a[i - 2] == 'i' || a[i - 2] == 'I')
- && (a[i - 1] == 'r' || a[i - 1] == 'R')
- && (a[i] == 'e' || a[i] == 'E')) {
- matchlen = 7;
- mask |= ACTION_REQUIRE;
- }
- else
- if (i >= 3 && (a[i - 3] == 'h' || a[i - 3] == 'H')
- && (a[i - 2] == 'o' || a[i - 2] == 'O')
- && (a[i - 1] == 's' || a[i - 1] == 'S')
- && (a[i] == 't' || a[i] == 'T')) {
- matchlen = 4;
- mask |= ACTION_HOST;
- }
- else
- if (i >= 7 && (a[i - 7] == 'f' || a[i - 7] == 'F')
- && (a[i - 6] == 'r' || a[i - 6] == 'R')
- && (a[i - 5] == 'a' || a[i - 5] == 'A')
- && (a[i - 4] == 'g' || a[i - 4] == 'G')
- && (a[i - 3] == 'm' || a[i - 3] == 'M')
- && (a[i - 2] == 'e' || a[i - 2] == 'E')
- && (a[i - 1] == 'n' || a[i - 1] == 'N')
- && (a[i] == 't' || a[i] == 'T')) {
- matchlen = 8;
- mask |= ACTION_FRAGMENT;
- }
- else {
- // parse error
- throw new IllegalArgumentException(
- "invalid permission: " + actions);
- }
-
- // make sure we didn't just match the tail of a word
- // like "ackbarfrequire". 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);
- }
-
- /**
- * Determines if the specified permission is implied by this object.
- *
- * <p>
- * This method checks that the symbolic name of the target is implied by the
- * symbolic name of this object. The list of <code>BundlePermission</code>
- * actions must either match or allow for the list of the target object to
- * imply the target <code>BundlePermission</code> action.
- * <p>
- * The permission to provide a bundle implies the permission to require the
- * named symbolic name.
- *
- * <pre>
- * x.y.*,"provide" -> x.y.z,"provide" is true
- * *,"require" -> x.y, "require" is true
- * *,"provide" -> x.y, "require" is true
- * x.y,"provide" -> x.y.z, "provide" is false
- * </pre>
- *
- * @param p The target permission to interrogate.
- * @return <code>true</code> if the specified
- * <code>BundlePermission</code> action is implied by this object;
- * <code>false</code> otherwise.
- */
-
- public boolean implies(Permission p) {
- if (p instanceof BundlePermission) {
- BundlePermission target = (BundlePermission) p;
-
- return (((action_mask & target.action_mask) == target.action_mask) && super
- .implies(p));
- }
-
- return (false);
- }
-
- /**
- * Returns the canonical string representation of the
- * <code>BundlePermission</code> actions.
- *
- * <p>
- * Always returns present <code>BundlePermission</code> actions in the
- * following order: <code>PROVIDE</code>,<code>REQUIRE</code>,
- * <code>HOST</code>,<code>FRAGMENT.
- * @return Canonical string representation of the <code>BundlePermission</code> actions.
- */
-
- public String getActions() {
- if (actions == null) {
- StringBuffer sb = new StringBuffer();
- boolean comma = false;
-
- if ((action_mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
- sb.append(PROVIDE);
- comma = true;
- }
-
- if ((action_mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
- if (comma)
- sb.append(',');
- sb.append(REQUIRE);
- comma = true;
- }
-
- if ((action_mask & ACTION_HOST) == ACTION_HOST) {
- if (comma)
- sb.append(',');
- sb.append(HOST);
- }
-
- if ((action_mask & ACTION_FRAGMENT) == ACTION_FRAGMENT) {
- if (comma)
- sb.append(',');
- sb.append(FRAGMENT);
- }
-
- actions = sb.toString();
- }
-
- return (actions);
- }
-
- /**
- * Returns a new <code>PermissionCollection</code> object suitable for
- * storing <code>BundlePermission</code> objects.
- *
- * @return A new <code>PermissionCollection</code> object.
- */
- public PermissionCollection newPermissionCollection() {
- return (new BundlePermissionCollection());
- }
-
- /**
- * Determines the equality of two <code>BundlePermission</code> objects.
- *
- * This method checks that specified bundle has the same bundle symbolic
- * name and <code>BundlePermission</code> actions as this
- * <code>BundlePermission</code> object.
- *
- * @param obj The object to test for equality with this
- * <code>BundlePermission</code> object.
- * @return <code>true</code> if <code>obj</code> is a
- * <code>BundlePermission</code>, and has the same bundle
- * symbolic name and actions as this <code>BundlePermission</code>
- * object; <code>false</code> otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return (true);
- }
-
- if (!(obj instanceof BundlePermission)) {
- return (false);
- }
-
- BundlePermission p = (BundlePermission) obj;
-
- return ((action_mask == p.action_mask) && getName().equals(p.getName()));
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return A hash code value for this object.
- */
-
- public int hashCode() {
- return (getName().hashCode() ^ getActions().hashCode());
- }
-
- /**
- * Returns the current action mask.
- * <p>
- * Used by the BundlePermissionCollection class.
- *
- * @return Current action mask.
- */
- int getMask() {
- return (action_mask);
- }
-
- /**
- * WriteObject is called to save the state of the
- * <code>BundlePermission</code> 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();
- }
-
- /**
- * readObject is called to restore the state of the BundlePermission from a
- * stream.
- */
- private synchronized void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- // Read in the action, then initialize the rest
- s.defaultReadObject();
- init(getMask(actions));
- }
-}
-
-/**
- * Stores a set of <code>BundlePermission</code> permissions.
- *
- * @see java.security.Permission
- * @see java.security.Permissions
- * @see java.security.PermissionCollection
- */
-
-final class BundlePermissionCollection extends PermissionCollection {
-
- /**
- * Comment for <code>serialVersionUID</code>
- */
- private static final long serialVersionUID = 3258407326846433079L;
-
- /**
- * Table of permissions.
- *
- * @serial
- */
- private Hashtable permissions;
-
- /**
- * Boolean saying if "*" is in the collection.
- *
- * @serial
- */
- private boolean all_allowed;
-
- /**
- * Create an empty BundlePermissions object.
- *
- */
-
- public BundlePermissionCollection() {
- permissions = new Hashtable();
- all_allowed = false;
- }
-
- /**
- * Adds a permission to the <code>BundlePermission</code> objects. The key
- * for the hash is the symbolic name.
- *
- * @param permission The <code>BundlePermission</code> object to add.
- *
- * @exception IllegalArgumentException If the permission is not a
- * <code>BundlePermission</code> instance.
- *
- * @exception SecurityException If this
- * <code>BundlePermissionCollection</code> object has been
- * marked read-only.
- */
-
- public void add(Permission permission) {
- if (!(permission instanceof BundlePermission))
- throw new IllegalArgumentException("invalid permission: "
- + permission);
- if (isReadOnly())
- throw new SecurityException("attempt to add a Permission to a "
- + "readonly PermissionCollection");
-
- BundlePermission bp = (BundlePermission) permission;
- String name = bp.getName();
-
- BundlePermission existing = (BundlePermission) permissions.get(name);
-
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = bp.getMask();
- if (oldMask != newMask) {
- permissions.put(name, new BundlePermission(name, oldMask
- | newMask));
-
- }
- }
- else {
- permissions.put(name, permission);
- }
-
- if (!all_allowed) {
- if (name.equals("*"))
- all_allowed = true;
- }
- }
-
- /**
- * Determines if the specified permissions implies the permissions expressed
- * in <code>permission</code>.
- *
- * @param permission The Permission object to compare with this
- * <code>BundlePermission</code> object.
- *
- * @return <code>true</code> if <code>permission</code> is a proper
- * subset of a permission in the set; <code>false</code>
- * otherwise.
- */
-
- public boolean implies(Permission permission) {
- if (!(permission instanceof BundlePermission))
- return (false);
-
- BundlePermission bp = (BundlePermission) permission;
- BundlePermission x;
-
- int desired = bp.getMask();
- int effective = 0;
-
- // short circuit if the "*" Permission was added
- if (all_allowed) {
- x = (BundlePermission) 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 = bp.getName();
-
- x = (BundlePermission) 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, offset;
-
- offset = name.length() - 1;
-
- while ((last = name.lastIndexOf(".", offset)) != -1) {
-
- name = name.substring(0, last + 1) + "*";
- x = (BundlePermission) 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 <code>BundlePermission</code> objects in
- * the container.
- *
- * @return Enumeration of all <code>BundlePermission</code> objects.
- */
-
- public Enumeration elements() {
- return (permissions.elements());
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/BundlePermission.java,v 1.14 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.framework;
+
+import java.io.IOException;
+import java.security.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * A bundle's authority to require or provide a bundle or to receive or attach
+ * fragments.
+ *
+ * <p>
+ * A bundle symbolic name defines a unique fully qualified name.
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * <code>
+ * org.osgi.example.bundle
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * <code>BundlePermission</code> has four actions: <code>PROVIDE</code>,
+ * <code>REQUIRE</code>,<code>HOST</code>, and <code>FRAGMENT</code>.
+ * The <code>PROVIDE</code> action implies the <code>REQUIRE</code> action.
+ *
+ * @since 1.3
+ */
+
+public final class BundlePermission extends BasicPermission {
+
+ private static final long serialVersionUID = 3257846601685873716L;
+
+ /**
+ * The action string <code>provide</code>.
+ */
+ public final static String PROVIDE = "provide";
+
+ /**
+ * The action string <code>require</code>.
+ */
+ public final static String REQUIRE = "require";
+
+ /**
+ * The action string <code>host</code>.
+ */
+ public final static String HOST = "host";
+
+ /**
+ * The action string <code>fragment</code>.
+ */
+ public final static String FRAGMENT = "fragment";
+
+ private final static int ACTION_PROVIDE = 0x00000001;
+ private final static int ACTION_REQUIRE = 0x00000002;
+ private final static int ACTION_HOST = 0x00000004;
+ private final static int ACTION_FRAGMENT = 0x00000008;
+ private final static int ACTION_ALL = ACTION_PROVIDE
+ | ACTION_REQUIRE
+ | ACTION_HOST
+ | ACTION_FRAGMENT;
+ private final static int ACTION_NONE = 0;
+ /**
+ * The actions mask.
+ */
+ private transient int action_mask = ACTION_NONE;
+
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private String actions = null;
+
+ /**
+ * Defines the authority to provide and/or require and or specify a host
+ * fragment symbolic name within the OSGi environment.
+ * <p>
+ * Bundle Permissions are granted over all possible versions of a bundle.
+ *
+ * A bundle that needs to provide a bundle must have the appropriate
+ * <code>BundlePermission</code> for the symbolic name; a bundle that
+ * requires a bundle must have the appropriate <code>BundlePermssion</code>
+ * for that symbolic name; a bundle that specifies a fragment host must have
+ * the appropriate <code>BundlePermission</code> for that symbolic name.
+ *
+ * @param symbolicName the bundle symbolic name.
+ * @param actions <code>PROVIDE</code>,<code>REQUIRE</code>,
+ * <code>HOST</code>,<code>FRAGMENT</code> (canonical order).
+ */
+
+ public BundlePermission(String symbolicName, String actions) {
+ this(symbolicName, getMask(actions));
+ }
+
+ /**
+ * Bundle private constructor used by BundlePermissionCollection.
+ *
+ * @param symbolicName the bundle symbolic name
+ * @param mask the action mask
+ */
+ BundlePermission(String symbolicName, int mask) {
+ super(symbolicName);
+ init(mask);
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param mask
+ */
+ private void init(int mask) {
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+
+ action_mask = mask;
+ }
+
+ /**
+ * Parse action string into 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 >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
+ && (a[i - 5] == 'r' || a[i - 5] == 'R')
+ && (a[i - 4] == 'o' || a[i - 4] == 'O')
+ && (a[i - 3] == 'v' || a[i - 3] == 'V')
+ && (a[i - 2] == 'i' || a[i - 2] == 'I')
+ && (a[i - 1] == 'd' || a[i - 1] == 'D')
+ && (a[i] == 'e' || a[i] == 'E')) {
+ matchlen = 7;
+ mask |= ACTION_PROVIDE | ACTION_REQUIRE;
+ }
+ else
+ if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
+ && (a[i - 5] == 'e' || a[i - 5] == 'E')
+ && (a[i - 4] == 'q' || a[i - 4] == 'Q')
+ && (a[i - 3] == 'u' || a[i - 3] == 'U')
+ && (a[i - 2] == 'i' || a[i - 2] == 'I')
+ && (a[i - 1] == 'r' || a[i - 1] == 'R')
+ && (a[i] == 'e' || a[i] == 'E')) {
+ matchlen = 7;
+ mask |= ACTION_REQUIRE;
+ }
+ else
+ if (i >= 3 && (a[i - 3] == 'h' || a[i - 3] == 'H')
+ && (a[i - 2] == 'o' || a[i - 2] == 'O')
+ && (a[i - 1] == 's' || a[i - 1] == 'S')
+ && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 4;
+ mask |= ACTION_HOST;
+ }
+ else
+ if (i >= 7 && (a[i - 7] == 'f' || a[i - 7] == 'F')
+ && (a[i - 6] == 'r' || a[i - 6] == 'R')
+ && (a[i - 5] == 'a' || a[i - 5] == 'A')
+ && (a[i - 4] == 'g' || a[i - 4] == 'G')
+ && (a[i - 3] == 'm' || a[i - 3] == 'M')
+ && (a[i - 2] == 'e' || a[i - 2] == 'E')
+ && (a[i - 1] == 'n' || a[i - 1] == 'N')
+ && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 8;
+ mask |= ACTION_FRAGMENT;
+ }
+ else {
+ // parse error
+ throw new IllegalArgumentException(
+ "invalid permission: " + actions);
+ }
+
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfrequire". 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);
+ }
+
+ /**
+ * Determines if the specified permission is implied by this object.
+ *
+ * <p>
+ * This method checks that the symbolic name of the target is implied by the
+ * symbolic name of this object. The list of <code>BundlePermission</code>
+ * actions must either match or allow for the list of the target object to
+ * imply the target <code>BundlePermission</code> action.
+ * <p>
+ * The permission to provide a bundle implies the permission to require the
+ * named symbolic name.
+ *
+ * <pre>
+ * x.y.*,"provide" -> x.y.z,"provide" is true
+ * *,"require" -> x.y, "require" is true
+ * *,"provide" -> x.y, "require" is true
+ * x.y,"provide" -> x.y.z, "provide" is false
+ * </pre>
+ *
+ * @param p The target permission to interrogate.
+ * @return <code>true</code> if the specified
+ * <code>BundlePermission</code> action is implied by this object;
+ * <code>false</code> otherwise.
+ */
+
+ public boolean implies(Permission p) {
+ if (p instanceof BundlePermission) {
+ BundlePermission target = (BundlePermission) p;
+
+ return (((action_mask & target.action_mask) == target.action_mask) && super
+ .implies(p));
+ }
+
+ return (false);
+ }
+
+ /**
+ * Returns the canonical string representation of the
+ * <code>BundlePermission</code> actions.
+ *
+ * <p>
+ * Always returns present <code>BundlePermission</code> actions in the
+ * following order: <code>PROVIDE</code>,<code>REQUIRE</code>,
+ * <code>HOST</code>,<code>FRAGMENT.
+ * @return Canonical string representation of the <code>BundlePermission</code> actions.
+ */
+
+ public String getActions() {
+ if (actions == null) {
+ StringBuffer sb = new StringBuffer();
+ boolean comma = false;
+
+ if ((action_mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
+ sb.append(PROVIDE);
+ comma = true;
+ }
+
+ if ((action_mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
+ if (comma)
+ sb.append(',');
+ sb.append(REQUIRE);
+ comma = true;
+ }
+
+ if ((action_mask & ACTION_HOST) == ACTION_HOST) {
+ if (comma)
+ sb.append(',');
+ sb.append(HOST);
+ comma = true;
+ }
+
+ if ((action_mask & ACTION_FRAGMENT) == ACTION_FRAGMENT) {
+ if (comma)
+ sb.append(',');
+ sb.append(FRAGMENT);
+ }
+
+ actions = sb.toString();
+ }
+
+ return (actions);
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>BundlePermission</code> objects.
+ *
+ * @return A new <code>PermissionCollection</code> object.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return (new BundlePermissionCollection());
+ }
+
+ /**
+ * Determines the equality of two <code>BundlePermission</code> objects.
+ *
+ * This method checks that specified bundle has the same bundle symbolic
+ * name and <code>BundlePermission</code> actions as this
+ * <code>BundlePermission</code> object.
+ *
+ * @param obj The object to test for equality with this
+ * <code>BundlePermission</code> object.
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>BundlePermission</code>, and has the same bundle
+ * symbolic name and actions as this <code>BundlePermission</code>
+ * object; <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return (true);
+ }
+
+ if (!(obj instanceof BundlePermission)) {
+ return (false);
+ }
+
+ BundlePermission p = (BundlePermission) obj;
+
+ return ((action_mask == p.action_mask) && getName().equals(p.getName()));
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+
+ public int hashCode() {
+ return (getName().hashCode() ^ getActions().hashCode());
+ }
+
+ /**
+ * Returns the current action mask.
+ * <p>
+ * Used by the BundlePermissionCollection class.
+ *
+ * @return Current action mask.
+ */
+ int getMask() {
+ return (action_mask);
+ }
+
+ /**
+ * WriteObject is called to save the state of the
+ * <code>BundlePermission</code> 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();
+ }
+
+ /**
+ * readObject is called to restore the state of the BundlePermission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ init(getMask(actions));
+ }
+}
+
+/**
+ * Stores a set of <code>BundlePermission</code> permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class BundlePermissionCollection extends PermissionCollection {
+
+ /**
+ * Comment for <code>serialVersionUID</code>
+ */
+ private static final long serialVersionUID = 3258407326846433079L;
+
+ /**
+ * Table of permissions.
+ *
+ * @serial
+ */
+ private Hashtable permissions;
+
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ */
+ private boolean all_allowed;
+
+ /**
+ * Create an empty BundlePermissions object.
+ *
+ */
+
+ public BundlePermissionCollection() {
+ permissions = new Hashtable();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to the <code>BundlePermission</code> objects. The key
+ * for the hash is the symbolic name.
+ *
+ * @param permission The <code>BundlePermission</code> object to add.
+ *
+ * @throws IllegalArgumentException If the permission is not a
+ * <code>BundlePermission</code> instance.
+ * @throws SecurityException If this <code>BundlePermissionCollection</code>
+ * object has been marked read-only.
+ */
+
+ public void add(Permission permission) {
+ if (!(permission instanceof BundlePermission))
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ if (isReadOnly())
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+
+ BundlePermission bp = (BundlePermission) permission;
+ String name = bp.getName();
+
+ BundlePermission existing = (BundlePermission) permissions.get(name);
+
+ if (existing != null) {
+ int oldMask = existing.getMask();
+ int newMask = bp.getMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new BundlePermission(name, oldMask
+ | newMask));
+
+ }
+ }
+ else {
+ permissions.put(name, permission);
+ }
+
+ if (!all_allowed) {
+ if (name.equals("*"))
+ all_allowed = true;
+ }
+ }
+
+ /**
+ * Determines if the specified permissions implies the permissions expressed
+ * in <code>permission</code>.
+ *
+ * @param permission The Permission object to compare with this
+ * <code>BundlePermission</code> object.
+ *
+ * @return <code>true</code> if <code>permission</code> is a proper
+ * subset of a permission in the set; <code>false</code>
+ * otherwise.
+ */
+
+ public boolean implies(Permission permission) {
+ if (!(permission instanceof BundlePermission))
+ return (false);
+
+ BundlePermission bp = (BundlePermission) permission;
+ BundlePermission x;
+
+ int desired = bp.getMask();
+ int effective = 0;
+
+ // short circuit if the "*" Permission was added
+ if (all_allowed) {
+ x = (BundlePermission) 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 = bp.getName();
+
+ x = (BundlePermission) 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, offset;
+
+ offset = name.length() - 1;
+
+ while ((last = name.lastIndexOf(".", offset)) != -1) {
+
+ name = name.substring(0, last + 1) + "*";
+ x = (BundlePermission) 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 <code>BundlePermission</code> objects in
+ * the container.
+ *
+ * @return Enumeration of all <code>BundlePermission</code> objects.
+ */
+
+ public Enumeration elements() {
+ return (permissions.elements());
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/Configurable.java b/org.osgi/src/main/java/org/osgi/framework/Configurable.java
index 27f5ec2..49b7796 100644
--- a/org.osgi/src/main/java/org/osgi/framework/Configurable.java
+++ b/org.osgi/src/main/java/org/osgi/framework/Configurable.java
@@ -1,44 +1,53 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Configurable.java,v 1.7 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * Supports a configuration object.
- *
- * <p><code>Configurable</code> is an interface that should be used by a bundle developer in support
- * of a configurable service.
- * Bundles that need to configure a service may test to determine
- * if the service object is an <code>instanceof Configurable</code>.
- *
- * @version $Revision: 1.7 $
- * @deprecated Please use the Configuration Admin
- */
-public abstract interface Configurable
-{
- /**
- * Returns this service's configuration object.
- *
- * <p>Services implementing <code>Configurable</code> should take care when returning a
- * service configuration object since this object is probably sensitive.
- * <p>If the Java Runtime Environment supports permissions, it is recommended that
- * the caller is checked for the appropriate permission before returning the configuration object.
- * It is recommended that callers possessing the appropriate
- * {@link AdminPermission} always be allowed to get the configuration object.
- *
- * @return The configuration object for this service.
- * @exception java.lang.SecurityException If the caller does not have
- * an appropriate permission and the Java Runtime Environment supports permissions.
- * @deprecated Please use the Configuration Admin
- */
- public abstract Object getConfigurationObject();
-}
-
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Configurable.java,v 1.9 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * Supports a configuration object.
+ *
+ * <p>
+ * <code>Configurable</code> is an interface that should be used by a bundle
+ * developer in support of a configurable service. Bundles that need to
+ * configure a service may test to determine if the service object is an
+ * <code>instanceof Configurable</code>.
+ *
+ * @version $Revision: 1.9 $
+ * @deprecated Since 1.2. Please use Configuration Admin service.
+ */
+public interface Configurable {
+ /**
+ * Returns this service's configuration object.
+ *
+ * <p>
+ * Services implementing <code>Configurable</code> should take care when
+ * returning a service configuration object since this object is probably
+ * sensitive.
+ * <p>
+ * If the Java Runtime Environment supports permissions, it is recommended
+ * that the caller is checked for some appropriate permission before
+ * returning the configuration object.
+ *
+ * @return The configuration object for this service.
+ * @throws java.lang.SecurityException If the caller does not have an
+ * appropriate permission and the Java Runtime Environment supports
+ * permissions.
+ * @deprecated Since 1.2. Please use Configuration Admin service.
+ */
+ public Object getConfigurationObject();
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/Constants.java b/org.osgi/src/main/java/org/osgi/framework/Constants.java
index d4b012f..bc3998b 100644
--- a/org.osgi/src/main/java/org/osgi/framework/Constants.java
+++ b/org.osgi/src/main/java/org/osgi/framework/Constants.java
@@ -1,1015 +1,1060 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Constants.java,v 1.18 2005/06/21 15:45:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.Dictionary;
-
-/**
- * Defines standard names for the OSGi environment property, service property,
- * and Manifest header attribute keys.
- *
- * <p>
- * The values associated with these keys are of type <code>java.lang.String</code>,
- * unless otherwise indicated.
- *
- * @version $Revision: 1.18 $
- * @since 1.1
- * @see Bundle#getHeaders()
- * @see BundleContext#getProperty
- * @see BundleContext#registerService(String[],Object,Dictionary)
- */
-
-public interface Constants {
- /**
- * Location identifier of the OSGi <i>system bundle </i>, which is defined
- * to be "System Bundle".
- */
- public static final String SYSTEM_BUNDLE_LOCATION = "System Bundle";
-
- /**
- * Alias for the symbolic name of the OSGi <i>system bundle </i>. It is defined
- * to be "system.bundle".
- * @since 1.3
- */
- public static final String SYSTEM_BUNDLE_SYMBOLICNAME = "system.bundle";
-
- /**
- * Manifest header (named "Bundle-Category") identifying the
- * bundle's category.
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_CATEGORY = "Bundle-Category";
-
- /**
- * Manifest header (named "Bundle-ClassPath") identifying a list
- * of directories and embedded JAR files, which are bundle resources used
- * to extend the bundle's classpath.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_CLASSPATH = "Bundle-ClassPath";
-
- /**
- * Manifest header (named "Bundle-Copyright") identifying the
- * bundle's copyright information.
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_COPYRIGHT = "Bundle-Copyright";
-
- /**
- * Manifest header (named "Bundle-Description") containing a brief
- * description of the bundle's functionality.
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_DESCRIPTION = "Bundle-Description";
-
- /**
- * Manifest header (named "Bundle-Name") identifying the bundle's
- * name.
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_NAME = "Bundle-Name";
-
- /**
- * Manifest header (named "Bundle-NativeCode") identifying a
- * number of hardware environments and the native language code libraries
- * that the bundle is carrying for each of these environments.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_NATIVECODE = "Bundle-NativeCode";
-
- /**
- * Manifest header (named "Export-Package") identifying
- * the packages that the bundle offers to the Framework for export.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String EXPORT_PACKAGE = "Export-Package";
-
- /**
- * Manifest header (named "Export-Service") identifying the fully
- * qualified class names of the services that the bundle may register (used
- * for informational purposes only).
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String EXPORT_SERVICE = "Export-Service";
-
- /**
- * Manifest header (named "Import-Package") identifying
- * the packages on which the bundle depends.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String IMPORT_PACKAGE = "Import-Package";
-
- /**
- * Manifest header (named "DynamicImport-Package") identifying
- * the packages that the bundle may dynamically import during
- * execution.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @since 1.2
- */
- public static final String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
-
- /**
- * Manifest header (named "Import-Service") identifying the fully
- * qualified class names of the services that the bundle requires (used for
- * informational purposes only).
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String IMPORT_SERVICE = "Import-Service";
-
- /**
- * Manifest header (named "Bundle-Vendor") identifying the
- * bundle's vendor.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_VENDOR = "Bundle-Vendor";
-
- /**
- * Manifest header (named "Bundle-Version") identifying the
- * bundle's version.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_VERSION = "Bundle-Version";
-
- /**
- * Manifest header (named "Bundle-DocURL") identifying the
- * bundle's documentation URL, from which further information about the
- * bundle may be obtained.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_DOCURL = "Bundle-DocURL";
-
- /**
- * Manifest header (named "Bundle-ContactAddress") identifying the
- * contact address where problems with the bundle may be reported; for
- * example, an email address.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
-
- /**
- * Manifest header attribute (named "Bundle-Activator")
- * identifying the bundle's activator class.
- *
- * <p>
- * If present, this header specifies the name of the bundle resource class
- * that implements the <code>BundleActivator</code> interface and whose
- * <code>start</code> and <code>stop</code> methods are called by the Framework
- * when the bundle is started and stopped, respectively.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_ACTIVATOR = "Bundle-Activator";
-
- /**
- * Manifest header (named "Bundle-UpdateLocation") identifying the
- * location from which a new bundle version is obtained during a bundle
- * update operation.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- */
- public static final String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
-
- /**
- * Manifest header attribute (named "specification-version")
- * identifying the version of a package specified in the Export-Package or
- * Import-Package manifest header.
- *
- * <p>
- * The attribute value is encoded in the Export-Package or Import-Package
- * manifest header like:
- *
- * <pre>
- * Import-Package: org.osgi.framework ; specification-version="1.1"
- * </pre>
- * @deprecated Since 1.3, this has been replaced by {@link #VERSION_ATTRIBUTE}.
- */
- public static final String PACKAGE_SPECIFICATION_VERSION = "specification-version";
-
- /**
- * Manifest header attribute (named "processor") identifying the
- * processor required to run native bundle code specified in the
- * Bundle-NativeCode manifest header).
- *
- * <p>
- * The attribute value is encoded in the Bundle-NativeCode manifest header
- * like:
- *
- * <pre>
- * Bundle-NativeCode: http.so ; processor=x86 ...
- * </pre>
- */
- public static final String BUNDLE_NATIVECODE_PROCESSOR = "processor";
-
- /**
- * Manifest header attribute (named "osname") identifying the
- * operating system required to run native bundle code specified in the
- * Bundle-NativeCode manifest header).
- * <p>
- * The attribute value is encoded in the Bundle-NativeCode manifest header
- * like:
- *
- * <pre>
- * Bundle-NativeCode: http.so ; osname=Linux ...
- * </pre>
- */
- public static final String BUNDLE_NATIVECODE_OSNAME = "osname";
-
- /**
- * Manifest header attribute (named "osversion") identifying the
- * operating system version required to run native bundle code specified in
- * the Bundle-NativeCode manifest header).
- * <p>
- * The attribute value is encoded in the Bundle-NativeCode manifest header
- * like:
- *
- * <pre>
- * Bundle-NativeCode: http.so ; osversion="2.34" ...
- * </pre>
- */
- public static final String BUNDLE_NATIVECODE_OSVERSION = "osversion";
-
- /**
- * Manifest header attribute (named "language") identifying the
- * language in which the native bundle code is written specified in the
- * Bundle-NativeCode manifest header. See ISO 639 for possible values.
- * <p>
- * The attribute value is encoded in the Bundle-NativeCode manifest header
- * like:
- *
- * <pre>
- * Bundle-NativeCode: http.so ; language=nl_be ...
- * </pre>
- */
- public static final String BUNDLE_NATIVECODE_LANGUAGE = "language";
-
- /**
- * Manifest header (named "Bundle-RequiredExecutionEnvironment")
- * identifying the required execution environment for the bundle. The
- * service platform may run this bundle if any of the execution environments
- * named in this header matches one of the execution environments it
- * implements.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @since 1.2
- */
- public static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
-
- /*
- * Framework environment properties.
- */
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.version") identifying the Framework
- * version.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- */
- public static final String FRAMEWORK_VERSION = "org.osgi.framework.version";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.vendor") identifying the Framework
- * implementation vendor.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- */
- public static final String FRAMEWORK_VENDOR = "org.osgi.framework.vendor";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.language") identifying the Framework
- * implementation language (see ISO 639 for possible values).
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- */
- public static final String FRAMEWORK_LANGUAGE = "org.osgi.framework.language";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.os.name") identifying the Framework
- * host-computer's operating system.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- */
- public static final String FRAMEWORK_OS_NAME = "org.osgi.framework.os.name";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.os.version") identifying the Framework
- * host-computer's operating system version number.
- *
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- */
- public static final String FRAMEWORK_OS_VERSION = "org.osgi.framework.os.version";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.processor") identifying the Framework
- * host-computer's processor name.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- */
- public static final String FRAMEWORK_PROCESSOR = "org.osgi.framework.processor";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.executionenvironment") identifying
- * execution environments provided by the Framework.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.2
- */
- public static final String FRAMEWORK_EXECUTIONENVIRONMENT = "org.osgi.framework.executionenvironment";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.bootdelegation") identifying
- * packages for which the Framework must delegate class loading to the boot class path.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.3
- */
- public static final String FRAMEWORK_BOOTDELEGATION = "org.osgi.framework.bootdelegation";
-
- /**
- * Framework environment property (named
- * "org.osgi.framework.system.packages") identifying
- * package which the system bundle must export.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.3
- */
- public static final String FRAMEWORK_SYSTEMPACKAGES = "org.osgi.framework.system.packages";
-
- /**
- * Framework environment property (named
- * "org.osgi.supports.framework.extension") identifying
- * whether the Framework supports framework extension bundles.
- * If the value of this property is <code>true</code>, then the Framework
- * supports framework extension bundles.
- * The default value is <code>false</code>.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.3
- */
- public static final String SUPPORTS_FRAMEWORK_EXTENSION = "org.osgi.supports.framework.extension";
-
- /**
- * Framework environment property (named
- * "org.osgi.supports.bootclasspath.extension") identifying
- * whether the Framework supports bootclasspath extension bundles.
- * If the value of this property is <code>true</code>, then the Framework
- * supports bootclasspath extension bundles.
- * The default value is <code>false</code>.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.3
- */
- public static final String SUPPORTS_BOOTCLASSPATH_EXTENSION = "org.osgi.supports.bootclasspath.extension";
-
- /**
- * Framework environment property (named
- * "org.osgi.supports.framework.fragment") identifying
- * whether the Framework supports fragment bundles.
- * If the value of this property is <code>true</code>, then the Framework
- * supports fragment bundles.
- * The default value is <code>false</code>.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.3
- */
- public static final String SUPPORTS_FRAMEWORK_FRAGMENT = "org.osgi.supports.framework.fragment";
-
- /**
- * Framework environment property (named
- * "org.osgi.supports.framework.requirebundle") identifying
- * whether the Framework supports the <code>Require-Bundle</code> manifest header.
- * If the value of this property is <code>true</code>, then the Framework
- * supports the <code>Require-Bundle</code> manifest header.
- * The default value is <code>false</code>.
- * <p>
- * The value of this property may be retrieved by calling the
- * <code>BundleContext.getProperty</code> method.
- *
- * @since 1.3
- */
- public static final String SUPPORTS_FRAMEWORK_REQUIREBUNDLE = "org.osgi.supports.framework.requirebundle";
-
- /*
- * Service properties.
- */
-
- /**
- * Service property (named "objectClass") identifying all of the
- * class names under which a service was registered in the Framework (of
- * type <code>java.lang.String[]</code>).
- *
- * <p>
- * This property is set by the Framework when a service is registered.
- */
- public static final String OBJECTCLASS = "objectClass";
-
- /**
- * Service property (named "service.id") identifying a service's
- * registration number (of type <code>java.lang.Long</code>).
- *
- * <p>
- * The value of this property is assigned by the Framework when a service is
- * registered. The Framework assigns a unique value that is larger than all
- * previously assigned values since the Framework was started. These values
- * are NOT persistent across restarts of the Framework.
- */
- public static final String SERVICE_ID = "service.id";
-
- /**
- * Service property (named "service.pid") identifying a service's
- * persistent identifier.
- *
- * <p>
- * This property may be supplied in the <code>properties</code>
- * <code>Dictionary</code>
- * object passed to the <code>BundleContext.registerService</code> method.
- *
- * <p>
- * A service's persistent identifier uniquely identifies the service and
- * persists across multiple Framework invocations.
- *
- * <p>
- * By convention, every bundle has its own unique namespace, starting with
- * the bundle's identifier (see {@link Bundle#getBundleId}) and followed by
- * a dot (.). A bundle may use this as the prefix of the persistent
- * identifiers for the services it registers.
- */
- public static final String SERVICE_PID = "service.pid";
-
- /**
- * Service property (named "service.ranking") identifying a
- * service's ranking number (of type <code>java.lang.Integer</code>).
- *
- * <p>
- * This property may be supplied in the <code>properties
- * Dictionary</code>
- * object passed to the <code>BundleContext.registerService</code> method.
- *
- * <p>
- * The service ranking is used by the Framework to determine the <i>default
- * </i> service to be returned from a call to the
- * {@link BundleContext#getServiceReference}method: If more than one
- * service implements the specified class, the <code>ServiceReference</code>
- * object with the highest ranking is returned.
- *
- * <p>
- * The default ranking is zero (0). A service with a ranking of
- * <code>Integer.MAX_VALUE</code> is very likely to be returned as the default
- * service, whereas a service with a ranking of <code>Integer.MIN_VALUE</code>
- * is very unlikely to be returned.
- *
- * <p>
- * If the supplied property value is not of type <code>java.lang.Integer</code>,
- * it is deemed to have a ranking value of zero.
- */
- public static final String SERVICE_RANKING = "service.ranking";
-
- /**
- * Service property (named "service.vendor") identifying a
- * service's vendor.
- *
- * <p>
- * This property may be supplied in the properties <code>Dictionary</code>
- * object passed to the <code>BundleContext.registerService</code> method.
- */
- public static final String SERVICE_VENDOR = "service.vendor";
-
- /**
- * Service property (named "service.description") identifying a
- * service's description.
- *
- * <p>
- * This property may be supplied in the properties <code>Dictionary</code>
- * object passed to the <code>BundleContext.registerService</code> method.
- */
- public static final String SERVICE_DESCRIPTION = "service.description";
-
- /**
- * Manifest header (named "Bundle-SymbolicName") identifying the
- * bundle's symbolic name.
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @since 1.3
- */
- public final static String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
-
- /**
- * Manifest header directive (named "singleton") identifying
- * whether a bundle is a singleton. The default value is <code>false</code>.
- *
- * <p>
- * The directive value is encoded in the Bundle-SymbolicName manifest header
- * like:
- *
- * <pre>
- * Bundle-SymbolicName: com.acme.module.test; singleton:=true
- * </pre>
- *
- * @since 1.3
- */
- public final static String SINGLETON_DIRECTIVE = "singleton";
-
- /**
- * Manifest header directive (named "fragment-attachment")
- * identifying if and when a fragment may attach to a host bundle. The
- * default value is <code>"always"</code>.
- *
- * <p>
- * The directive value is encoded in the Bundle-SymbolicName manifest header
- * like:
- *
- * <pre>
- * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="never"
- * </pre>
- *
- * @see Constants#FRAGMENT_ATTACHMENT_ALWAYS
- * @see Constants#FRAGMENT_ATTACHMENT_RESOLVETIME
- * @see Constants#FRAGMENT_ATTACHMENT_NEVER
- * @since 1.3
- */
- public final static String FRAGMENT_ATTACHMENT_DIRECTIVE = "fragment-attachment";
-
- /**
- * Manifest header directive value (named "always") identifying a
- * fragment attachment type of always. A fragment attachment type of always
- * indicates that fragments are allowed to attach to the host bundle at any
- * time (while the host is resolved or during the process of resolving the
- * host bundle).
- *
- * <p>
- * The directive value is encoded in the Bundle-SymbolicName manifest header
- * like:
- *
- * <pre>
- * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="always"
- * </pre>
- *
- * @see Constants#FRAGMENT_ATTACHMENT_DIRECTIVE
- * @since 1.3
- */
- public final static String FRAGMENT_ATTACHMENT_ALWAYS = "always";
-
- /**
- * Manifest header directive value (named "resolve-time")
- * identifying a fragment attachment type of resolve-time. A fragment
- * attachment type of resolve-time indicates that fragments are allowed to
- * attach to the host bundle only during the process of resolving the host
- * bundle.
- *
- * <p>
- * The directive value is encoded in the Bundle-SymbolicName manifest header
- * like:
- *
- * <pre>
- * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="resolve-time"
- * </pre>
- *
- * @see Constants#FRAGMENT_ATTACHMENT_DIRECTIVE
- * @since 1.3
- */
- public final static String FRAGMENT_ATTACHMENT_RESOLVETIME = "resolve-time";
-
- /**
- * Manifest header directive value (named "never") identifying a
- * fragment attachment type of never. A fragment attachment type of never
- * indicates that no fragments are allowed to attach to the host bundle at
- * any time.
- *
- * <p>
- * The directive value is encoded in the Bundle-SymbolicName manifest header
- * like:
- *
- * <pre>
- * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="never"
- * </pre>
- *
- * @see Constants#FRAGMENT_ATTACHMENT_DIRECTIVE
- * @since 1.3
- */
- public final static String FRAGMENT_ATTACHMENT_NEVER = "never";
-
- /**
- * Manifest header (named "Bundle-Localization") identifying the
- * base name of the bundle's localization entries.
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @see #BUNDLE_LOCALIZATION_DEFAULT_BASENAME
- * @since 1.3
- */
- public final static String BUNDLE_LOCALIZATION = "Bundle-Localization";
-
- /**
- * Default value for the <code>Bundle-Localization</code> manifest header.
- *
- * @see #BUNDLE_LOCALIZATION
- * @since 1.3
- */
- public final static String BUNDLE_LOCALIZATION_DEFAULT_BASENAME = "OSGI-INF/l10n/bundle";
-
- /**
- * Manifest header (named "Require-Bundle") identifying the
- * symbolic names of other bundles required by the bundle.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @since 1.3
- */
- public final static String REQUIRE_BUNDLE = "Require-Bundle";
-
- /**
- * Manifest header attribute (named "bundle-version") identifying
- * a range of versions for a bundle specified in the Require-Bundle or
- * Fragment-Host manifest headers. The default value is <code>0.0.0</code>.
- *
- * <p>
- * The attribute value is encoded in the Require-Bundle manifest header
- * like:
- *
- * <pre>
- * Require-Bundle: com.acme.module.test; bundle-version="1.1"
- * Require-Bundle: com.acme.module.test; bundle-version="[1.0,2.0)"
- * </pre>
- *
- * <p>
- * The bundle-version attribute value uses a mathematical interval notation
- * to specify a range of bundle versions. A bundle-version attribute value
- * specified as a single version means a version range that includes any
- * bundle version greater than or equal to the specified version.
- *
- * @since 1.3
- */
- public static final String BUNDLE_VERSION_ATTRIBUTE = "bundle-version";
-
- /**
- * Manifest header (named "Fragment-Host") identifying the
- * symbolic name of another bundle for which that the bundle is a fragment.
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @since 1.3
- */
- public final static String FRAGMENT_HOST = "Fragment-Host";
-
- /**
- * Manifest header directive (named "multiple-hosts") identifying
- * if the fragment should attach to each bundle selected by the
- * Fragment-Host manifest header. The default value is <code>false</code>.
- *
- * <p>
- * The directive value is encoded in the Fragment-Host manifest header like:
- *
- * <pre>
- * Fragment-Host: com.acme.module.test; multiple-hosts:="false"
- * </pre>
- *
- * @since 1.3
- */
- public final static String MULTIPLE_HOSTS_DIRECTIVE = "multiple-hosts";
-
- /**
- * Manifest header attribute (named "selection-filter") is used
- * for selection by filtering based upon system properties.
- *
- * <p>
- * The attribute value is encoded in manifest headers like:
- *
- * <pre>
- * Bundle-NativeCode: libgtk.so; selection-filter="(ws=gtk)"; ...
- * </pre>
- *
- * @since 1.3
- */
- public final static String SELECTION_FILTER_ATTRIBUTE = "selection-filter";
-
- /**
- * Manifest header (named "Bundle-ManifestVersion") identifying
- * the bundle manifest version. A bundle manifest may express the version of
- * the syntax in which it is written by specifying a bundle manifest
- * version. Bundles exploiting OSGi R4, or later, syntax must specify a
- * bundle manifest version.
- * <p>
- * The bundle manifest version defined by OSGi R4 or, more specifically, by
- * V1.3 of the OSGi Framework Specification is "2".
- *
- * <p>
- * The attribute value may be retrieved from the <code>Dictionary</code>
- * object returned by the <code>Bundle.getHeaders</code> method.
- *
- * @since 1.3
- */
- public final static String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
-
- /**
- * Manifest header attribute (named "version") identifying the
- * version of a package specified in the Export-Package or Import-Package
- * manifest header.
- *
- * <p>
- * The attribute value is encoded in the Export-Package or Import-Package
- * manifest header like:
- *
- * <pre>
- * Import-Package: org.osgi.framework; version="1.1"
- * </pre>
- *
- * @since 1.3
- */
- public final static String VERSION_ATTRIBUTE = "version";
-
- /**
- * Manifest header attribute (named "bundle-symbolic-name")
- * identifying the symbolic name of a bundle that exports a package
- * specified in the Import-Package manifest header.
- *
- * <p>
- * The attribute value is encoded in the Import-Package manifest header
- * like:
- *
- * <pre>
- * Import-Package: org.osgi.framework; bundle-symbolic-name="com.acme.module.test"
- * </pre>
- *
- * @since 1.3
- */
- public final static String BUNDLE_SYMBOLICNAME_ATTRIBUTE = "bundle-symbolic-name";
-
- /**
- * Manifest header directive (named "resolution") identifying the
- * resolution type in the Import-Package or Require-Bundle manifest header.
- *
- * <p>
- * The directive value is encoded in the Import-Package or Require-Bundle
- * manifest header like:
- *
- * <pre>
- * Import-Package: org.osgi.framework; resolution:="optional"
- * Require-Bundle: com.acme.module.test; resolution:="optional"
- * </pre>
- *
- * @see Constants#RESOLUTION_MANDATORY
- * @see Constants#RESOLUTION_OPTIONAL
- * @since 1.3
- */
- public final static String RESOLUTION_DIRECTIVE = "resolution";
-
- /**
- * Manifest header directive value (named "mandatory") identifying
- * a mandatory resolution type. A mandatory resolution type indicates that
- * the import package or require bundle must be resolved when the bundle is
- * resolved. If such an import or require bundle cannot be resolved, the
- * module fails to resolve.
- *
- * <p>
- * The directive value is encoded in the Import-Package or Require-Bundle
- * manifest header like:
- *
- * <pre>
- * Import-Package: org.osgi.framework; resolution:="manditory"
- * Require-Bundle: com.acme.module.test; resolution:="manditory"
- * </pre>
- *
- * @see Constants#RESOLUTION_DIRECTIVE
- * @since 1.3
- */
- public final static String RESOLUTION_MANDATORY = "mandatory";
-
- /**
- * Manifest header directive value (named "optional") identifying
- * an optional resolution type. An optional resolution type indicates that
- * the import or require bundle is optional and the bundle may be resolved
- * without the import or require bundle being resolved. If the import or
- * require bundle is not resolved when the bundle is resolved, the import or
- * require bundle may not be resolved before the bundle is refreshed.
- *
- * <p>
- * The directive value is encoded in the Import-Package or Require-Bundle
- * manifest header like:
- *
- * <pre>
- * Import-Package: org.osgi.framework; resolution:="optional"
- * Require-Bundle: com.acme.module.test; resolution:="optional"
- * </pre>
- *
- * @see Constants#RESOLUTION_DIRECTIVE
- * @since 1.3
- */
- public final static String RESOLUTION_OPTIONAL = "optional";
-
- /**
- * Manifest header directive (named "uses") identifying a list of
- * packages that an exported package uses.
- *
- * <p>
- * The directive value is encoded in the Export-Package manifest header like:
- *
- * <pre>
- * Export-Package: org.osgi.util.tracker; uses:="org.osgi.framework"
- * </pre>
- *
- * @since 1.3
- */
- public final static String USES_DIRECTIVE = "uses";
-
- /**
- * Manifest header directive (named "include") identifying a list
- * of classes and/or resources of the specified package which must be
- * allowed to be exported in the Export-Package manifest header.
- *
- * <p>
- * The directive value is encoded in the Export-Package manifest header
- * like:
- *
- * <pre>
- * Export-Package: org.osgi.framework; include:="MyStuff*"
- * </pre>
- *
- * @since 1.3
- */
- public final static String INCLUDE_DIRECTIVE = "include";
-
- /**
- * Manifest header directive (named "exclude") identifying a list
- * of classes and/or resources of the specified package which must not be
- * allowed to be exported in the Export-Package manifest header.
- *
- * <p>
- * The directive value is encoded in the Export-Package manifest header
- * like:
- *
- * <pre>
- * Export-Package: org.osgi.framework; exclude:="MyStuff*"
- * </pre>
- *
- * @since 1.3
- */
- public final static String EXCLUDE_DIRECTIVE = "exclude";
-
- /**
- * Manifest header directive (named "mandatory") identifying names
- * of matching attributes which must be specified by matching Import-Package
- * statements in the Export-Package manifest header.
- *
- * <p>
- * The directive value is encoded in the Export-Package manifest header
- * like:
- *
- * <pre>
- * Export-Package: org.osgi.framework; mandatory:="bundle-symbolic-name"
- * </pre>
- *
- * @since 1.3
- */
- public final static String MANDATORY_DIRECTIVE = "mandatory";
-
- /**
- * Manifest header directive (named "visibility") identifying the
- * visibility of a reqiured bundle in the Require-Bundle manifest header.
- *
- * <p>
- * The directive value is encoded in the Require-Bundle manifest header
- * like:
- *
- * <pre>
- * Require-Bundle: com.acme.module.test; visibility:="reexport"
- * </pre>
- *
- * @see Constants#VISIBILITY_PRIVATE
- * @see Constants#VISIBILITY_REEXPORT
- * @since 1.3
- */
- public final static String VISIBILITY_DIRECTIVE = "visibility";
-
- /**
- * Manifest header directive value (named "private") identifying a
- * private visibility type. A private visibility type indicates that any
- * packages that are exported by the required bundle are not made visible on
- * the export signature of the requiring bundle.
- *
- * <p>
- * The directive value is encoded in the Require-Bundle manifest header
- * like:
- *
- * <pre>
- * Require-Bundle: com.acme.module.test; visibility:="private"
- * </pre>
- *
- * @see Constants#VISIBILITY_DIRECTIVE
- * @since 1.3
- */
- public final static String VISIBILITY_PRIVATE = "private";
-
- /**
- * Manifest header directive value (named "reexport") identifying
- * a reexport visibility type. A reexport visibility type indicates any
- * packages that are exported by the required bundle are re-exported by the
- * requiring bundle. Any arbitrary arbitrary matching attributes with which
- * they were exported by the required bundle are deleted.
- *
- * <p>
- * The directive value is encoded in the Require-Bundle manifest header
- * like:
- *
- * <pre>
- * Require-Bundle: com.acme.module.test; visibility:="reexport"
- * </pre>
- *
- * @see Constants#VISIBILITY_DIRECTIVE
- * @since 1.3
- */
- public final static String VISIBILITY_REEXPORT = "reexport";
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Constants.java,v 1.23 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * Defines standard names for the OSGi environment property, service property,
+ * and Manifest header attribute keys.
+ *
+ * <p>
+ * The values associated with these keys are of type
+ * <code>java.lang.String</code>, unless otherwise indicated.
+ *
+ * @version $Revision: 1.23 $
+ * @since 1.1
+ */
+
+public interface Constants {
+ /**
+ * Location identifier of the OSGi <i>system bundle </i>, which is defined
+ * to be "System Bundle".
+ */
+ public static final String SYSTEM_BUNDLE_LOCATION = "System Bundle";
+
+ /**
+ * Alias for the symbolic name of the OSGi <i>system bundle </i>. It is
+ * defined to be "system.bundle".
+ *
+ * @since 1.3
+ */
+ public static final String SYSTEM_BUNDLE_SYMBOLICNAME = "system.bundle";
+
+ /**
+ * Manifest header (named "Bundle-Category") identifying the
+ * bundle's category.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_CATEGORY = "Bundle-Category";
+
+ /**
+ * Manifest header (named "Bundle-ClassPath") identifying a list
+ * of directories and embedded JAR files, which are bundle resources used to
+ * extend the bundle's classpath.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_CLASSPATH = "Bundle-ClassPath";
+
+ /**
+ * Manifest header (named "Bundle-Copyright") identifying the
+ * bundle's copyright information.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_COPYRIGHT = "Bundle-Copyright";
+
+ /**
+ * Manifest header (named "Bundle-Description") containing a brief
+ * description of the bundle's functionality.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_DESCRIPTION = "Bundle-Description";
+
+ /**
+ * Manifest header (named "Bundle-Name") identifying the bundle's
+ * name.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_NAME = "Bundle-Name";
+
+ /**
+ * Manifest header (named "Bundle-NativeCode") identifying a
+ * number of hardware environments and the native language code libraries
+ * that the bundle is carrying for each of these environments.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_NATIVECODE = "Bundle-NativeCode";
+
+ /**
+ * Manifest header (named "Export-Package") identifying the
+ * packages that the bundle offers to the Framework for export.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String EXPORT_PACKAGE = "Export-Package";
+
+ /**
+ * Manifest header (named "Export-Service") identifying the fully
+ * qualified class names of the services that the bundle may register (used
+ * for informational purposes only).
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String EXPORT_SERVICE = "Export-Service";
+
+ /**
+ * Manifest header (named "Import-Package") identifying the
+ * packages on which the bundle depends.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String IMPORT_PACKAGE = "Import-Package";
+
+ /**
+ * Manifest header (named "DynamicImport-Package") identifying the
+ * packages that the bundle may dynamically import during execution.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @since 1.2
+ */
+ public static final String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
+
+ /**
+ * Manifest header (named "Import-Service") identifying the fully
+ * qualified class names of the services that the bundle requires (used for
+ * informational purposes only).
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String IMPORT_SERVICE = "Import-Service";
+
+ /**
+ * Manifest header (named "Bundle-Vendor") identifying the
+ * bundle's vendor.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_VENDOR = "Bundle-Vendor";
+
+ /**
+ * Manifest header (named "Bundle-Version") identifying the
+ * bundle's version.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_VERSION = "Bundle-Version";
+
+ /**
+ * Manifest header (named "Bundle-DocURL") identifying the
+ * bundle's documentation URL, from which further information about the
+ * bundle may be obtained.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_DOCURL = "Bundle-DocURL";
+
+ /**
+ * Manifest header (named "Bundle-ContactAddress") identifying the
+ * contact address where problems with the bundle may be reported; for
+ * example, an email address.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
+
+ /**
+ * Manifest header attribute (named "Bundle-Activator")
+ * identifying the bundle's activator class.
+ *
+ * <p>
+ * If present, this header specifies the name of the bundle resource class
+ * that implements the <code>BundleActivator</code> interface and whose
+ * <code>start</code> and <code>stop</code> methods are called by the
+ * Framework when the bundle is started and stopped, respectively.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_ACTIVATOR = "Bundle-Activator";
+
+ /**
+ * Manifest header (named "Bundle-UpdateLocation") identifying the
+ * location from which a new bundle version is obtained during a bundle
+ * update operation.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String BUNDLE_UPDATELOCATION = "Bundle-UpdateLocation";
+
+ /**
+ * Manifest header attribute (named "specification-version")
+ * identifying the version of a package specified in the Export-Package or
+ * Import-Package manifest header.
+ *
+ * <p>
+ * The attribute value is encoded in the Export-Package or Import-Package
+ * manifest header like:
+ *
+ * <pre>
+ * Import-Package: org.osgi.framework ; specification-version="1.1"
+ * </pre>
+ *
+ * @deprecated Since 1.3. This has been replaced by
+ * {@link #VERSION_ATTRIBUTE}.
+ */
+ public static final String PACKAGE_SPECIFICATION_VERSION = "specification-version";
+
+ /**
+ * Manifest header attribute (named "processor") identifying the
+ * processor required to run native bundle code specified in the
+ * Bundle-NativeCode manifest header).
+ *
+ * <p>
+ * The attribute value is encoded in the Bundle-NativeCode manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-NativeCode: http.so ; processor=x86 ...
+ * </pre>
+ */
+ public static final String BUNDLE_NATIVECODE_PROCESSOR = "processor";
+
+ /**
+ * Manifest header attribute (named "osname") identifying the
+ * operating system required to run native bundle code specified in the
+ * Bundle-NativeCode manifest header).
+ * <p>
+ * The attribute value is encoded in the Bundle-NativeCode manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-NativeCode: http.so ; osname=Linux ...
+ * </pre>
+ */
+ public static final String BUNDLE_NATIVECODE_OSNAME = "osname";
+
+ /**
+ * Manifest header attribute (named "osversion") identifying the
+ * operating system version required to run native bundle code specified in
+ * the Bundle-NativeCode manifest header).
+ * <p>
+ * The attribute value is encoded in the Bundle-NativeCode manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-NativeCode: http.so ; osversion="2.34" ...
+ * </pre>
+ */
+ public static final String BUNDLE_NATIVECODE_OSVERSION = "osversion";
+
+ /**
+ * Manifest header attribute (named "language") identifying the
+ * language in which the native bundle code is written specified in the
+ * Bundle-NativeCode manifest header. See ISO 639 for possible values.
+ * <p>
+ * The attribute value is encoded in the Bundle-NativeCode manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-NativeCode: http.so ; language=nl_be ...
+ * </pre>
+ */
+ public static final String BUNDLE_NATIVECODE_LANGUAGE = "language";
+
+ /**
+ * Manifest header (named "Bundle-RequiredExecutionEnvironment")
+ * identifying the required execution environment for the bundle. The
+ * service platform may run this bundle if any of the execution environments
+ * named in this header matches one of the execution environments it
+ * implements.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @since 1.2
+ */
+ public static final String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+
+ /*
+ * Framework environment properties.
+ */
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.version") identifying the Framework
+ * version.
+ *
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ */
+ public static final String FRAMEWORK_VERSION = "org.osgi.framework.version";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.vendor") identifying the Framework
+ * implementation vendor.
+ *
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ */
+ public static final String FRAMEWORK_VENDOR = "org.osgi.framework.vendor";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.language") identifying the Framework
+ * implementation language (see ISO 639 for possible values).
+ *
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ */
+ public static final String FRAMEWORK_LANGUAGE = "org.osgi.framework.language";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.os.name") identifying the Framework
+ * host-computer's operating system.
+ *
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ */
+ public static final String FRAMEWORK_OS_NAME = "org.osgi.framework.os.name";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.os.version") identifying the Framework
+ * host-computer's operating system version number.
+ *
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ */
+ public static final String FRAMEWORK_OS_VERSION = "org.osgi.framework.os.version";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.processor") identifying the Framework
+ * host-computer's processor name.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ */
+ public static final String FRAMEWORK_PROCESSOR = "org.osgi.framework.processor";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.executionenvironment") identifying
+ * execution environments provided by the Framework.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.2
+ */
+ public static final String FRAMEWORK_EXECUTIONENVIRONMENT = "org.osgi.framework.executionenvironment";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.bootdelegation") identifying packages for
+ * which the Framework must delegate class loading to the boot class path.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.3
+ */
+ public static final String FRAMEWORK_BOOTDELEGATION = "org.osgi.framework.bootdelegation";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.framework.system.packages") identifying package which
+ * the system bundle must export.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.3
+ */
+ public static final String FRAMEWORK_SYSTEMPACKAGES = "org.osgi.framework.system.packages";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.supports.framework.extension") identifying whether
+ * the Framework supports framework extension bundles. If the value of this
+ * property is <code>true</code>, then the Framework supports framework
+ * extension bundles. The default value is <code>false</code>.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.3
+ */
+ public static final String SUPPORTS_FRAMEWORK_EXTENSION = "org.osgi.supports.framework.extension";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.supports.bootclasspath.extension") identifying
+ * whether the Framework supports bootclasspath extension bundles. If the
+ * value of this property is <code>true</code>, then the Framework
+ * supports bootclasspath extension bundles. The default value is
+ * <code>false</code>.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.3
+ */
+ public static final String SUPPORTS_BOOTCLASSPATH_EXTENSION = "org.osgi.supports.bootclasspath.extension";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.supports.framework.fragment") identifying whether the
+ * Framework supports fragment bundles. If the value of this property is
+ * <code>true</code>, then the Framework supports fragment bundles. The
+ * default value is <code>false</code>.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.3
+ */
+ public static final String SUPPORTS_FRAMEWORK_FRAGMENT = "org.osgi.supports.framework.fragment";
+
+ /**
+ * Framework environment property (named
+ * "org.osgi.supports.framework.requirebundle") identifying
+ * whether the Framework supports the <code>Require-Bundle</code> manifest
+ * header. If the value of this property is <code>true</code>, then the
+ * Framework supports the <code>Require-Bundle</code> manifest header. The
+ * default value is <code>false</code>.
+ * <p>
+ * The value of this property may be retrieved by calling the
+ * <code>BundleContext.getProperty</code> method.
+ *
+ * @since 1.3
+ */
+ public static final String SUPPORTS_FRAMEWORK_REQUIREBUNDLE = "org.osgi.supports.framework.requirebundle";
+
+ /*
+ * Service properties.
+ */
+
+ /**
+ * Service property (named "objectClass") identifying all of the
+ * class names under which a service was registered in the Framework (of
+ * type <code>java.lang.String[]</code>).
+ *
+ * <p>
+ * This property is set by the Framework when a service is registered.
+ */
+ public static final String OBJECTCLASS = "objectClass";
+
+ /**
+ * Service property (named "service.id") identifying a service's
+ * registration number (of type <code>java.lang.Long</code>).
+ *
+ * <p>
+ * The value of this property is assigned by the Framework when a service is
+ * registered. The Framework assigns a unique value that is larger than all
+ * previously assigned values since the Framework was started. These values
+ * are NOT persistent across restarts of the Framework.
+ */
+ public static final String SERVICE_ID = "service.id";
+
+ /**
+ * Service property (named "service.pid") identifying a service's
+ * persistent identifier.
+ *
+ * <p>
+ * This property may be supplied in the <code>properties</code>
+ * <code>Dictionary</code>
+ * object passed to the <code>BundleContext.registerService</code> method.
+ *
+ * <p>
+ * A service's persistent identifier uniquely identifies the service and
+ * persists across multiple Framework invocations.
+ *
+ * <p>
+ * By convention, every bundle has its own unique namespace, starting with
+ * the bundle's identifier (see {@link Bundle#getBundleId}) and followed by
+ * a dot (.). A bundle may use this as the prefix of the persistent
+ * identifiers for the services it registers.
+ */
+ public static final String SERVICE_PID = "service.pid";
+
+ /**
+ * Service property (named "service.ranking") identifying a
+ * service's ranking number (of type <code>java.lang.Integer</code>).
+ *
+ * <p>
+ * This property may be supplied in the <code>properties
+ * Dictionary</code>
+ * object passed to the <code>BundleContext.registerService</code> method.
+ *
+ * <p>
+ * The service ranking is used by the Framework to determine the <i>default
+ * </i> service to be returned from a call to the
+ * {@link BundleContext#getServiceReference} method: If more than one
+ * service implements the specified class, the <code>ServiceReference</code>
+ * object with the highest ranking is returned.
+ *
+ * <p>
+ * The default ranking is zero (0). A service with a ranking of
+ * <code>Integer.MAX_VALUE</code> is very likely to be returned as the
+ * default service, whereas a service with a ranking of
+ * <code>Integer.MIN_VALUE</code> is very unlikely to be returned.
+ *
+ * <p>
+ * If the supplied property value is not of type
+ * <code>java.lang.Integer</code>, it is deemed to have a ranking value
+ * of zero.
+ */
+ public static final String SERVICE_RANKING = "service.ranking";
+
+ /**
+ * Service property (named "service.vendor") identifying a
+ * service's vendor.
+ *
+ * <p>
+ * This property may be supplied in the properties <code>Dictionary</code>
+ * object passed to the <code>BundleContext.registerService</code> method.
+ */
+ public static final String SERVICE_VENDOR = "service.vendor";
+
+ /**
+ * Service property (named "service.description") identifying a
+ * service's description.
+ *
+ * <p>
+ * This property may be supplied in the properties <code>Dictionary</code>
+ * object passed to the <code>BundleContext.registerService</code> method.
+ */
+ public static final String SERVICE_DESCRIPTION = "service.description";
+
+ /**
+ * Manifest header (named "Bundle-SymbolicName") identifying the
+ * bundle's symbolic name.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @since 1.3
+ */
+ public final static String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
+
+ /**
+ * Manifest header directive (named "singleton") identifying
+ * whether a bundle is a singleton. The default value is <code>false</code>.
+ *
+ * <p>
+ * The directive value is encoded in the Bundle-SymbolicName manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-SymbolicName: com.acme.module.test; singleton:=true
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String SINGLETON_DIRECTIVE = "singleton";
+
+ /**
+ * Manifest header directive (named "fragment-attachment")
+ * identifying if and when a fragment may attach to a host bundle. The
+ * default value is <code>"always"</code>.
+ *
+ * <p>
+ * The directive value is encoded in the Bundle-SymbolicName manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="never"
+ * </pre>
+ *
+ * @see Constants#FRAGMENT_ATTACHMENT_ALWAYS
+ * @see Constants#FRAGMENT_ATTACHMENT_RESOLVETIME
+ * @see Constants#FRAGMENT_ATTACHMENT_NEVER
+ * @since 1.3
+ */
+ public final static String FRAGMENT_ATTACHMENT_DIRECTIVE = "fragment-attachment";
+
+ /**
+ * Manifest header directive value (named "always") identifying a
+ * fragment attachment type of always. A fragment attachment type of always
+ * indicates that fragments are allowed to attach to the host bundle at any
+ * time (while the host is resolved or during the process of resolving the
+ * host bundle).
+ *
+ * <p>
+ * The directive value is encoded in the Bundle-SymbolicName manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="always"
+ * </pre>
+ *
+ * @see Constants#FRAGMENT_ATTACHMENT_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String FRAGMENT_ATTACHMENT_ALWAYS = "always";
+
+ /**
+ * Manifest header directive value (named "resolve-time")
+ * identifying a fragment attachment type of resolve-time. A fragment
+ * attachment type of resolve-time indicates that fragments are allowed to
+ * attach to the host bundle only during the process of resolving the host
+ * bundle.
+ *
+ * <p>
+ * The directive value is encoded in the Bundle-SymbolicName manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="resolve-time"
+ * </pre>
+ *
+ * @see Constants#FRAGMENT_ATTACHMENT_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String FRAGMENT_ATTACHMENT_RESOLVETIME = "resolve-time";
+
+ /**
+ * Manifest header directive value (named "never") identifying a
+ * fragment attachment type of never. A fragment attachment type of never
+ * indicates that no fragments are allowed to attach to the host bundle at
+ * any time.
+ *
+ * <p>
+ * The directive value is encoded in the Bundle-SymbolicName manifest header
+ * like:
+ *
+ * <pre>
+ * Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="never"
+ * </pre>
+ *
+ * @see Constants#FRAGMENT_ATTACHMENT_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String FRAGMENT_ATTACHMENT_NEVER = "never";
+
+ /**
+ * Manifest header (named "Bundle-Localization") identifying the
+ * base name of the bundle's localization entries.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @see #BUNDLE_LOCALIZATION_DEFAULT_BASENAME
+ * @since 1.3
+ */
+ public final static String BUNDLE_LOCALIZATION = "Bundle-Localization";
+
+ /**
+ * Default value for the <code>Bundle-Localization</code> manifest header.
+ *
+ * @see #BUNDLE_LOCALIZATION
+ * @since 1.3
+ */
+ public final static String BUNDLE_LOCALIZATION_DEFAULT_BASENAME = "OSGI-INF/l10n/bundle";
+
+ /**
+ * Manifest header (named "Require-Bundle") identifying the
+ * symbolic names of other bundles required by the bundle.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @since 1.3
+ */
+ public final static String REQUIRE_BUNDLE = "Require-Bundle";
+
+ /**
+ * Manifest header attribute (named "bundle-version") identifying
+ * a range of versions for a bundle specified in the Require-Bundle or
+ * Fragment-Host manifest headers. The default value is <code>0.0.0</code>.
+ *
+ * <p>
+ * The attribute value is encoded in the Require-Bundle manifest header
+ * like:
+ *
+ * <pre>
+ * Require-Bundle: com.acme.module.test; bundle-version="1.1"
+ * Require-Bundle: com.acme.module.test; bundle-version="[1.0,2.0)"
+ * </pre>
+ *
+ * <p>
+ * The bundle-version attribute value uses a mathematical interval notation
+ * to specify a range of bundle versions. A bundle-version attribute value
+ * specified as a single version means a version range that includes any
+ * bundle version greater than or equal to the specified version.
+ *
+ * @since 1.3
+ */
+ public static final String BUNDLE_VERSION_ATTRIBUTE = "bundle-version";
+
+ /**
+ * Manifest header (named "Fragment-Host") identifying the
+ * symbolic name of another bundle for which that the bundle is a fragment.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @since 1.3
+ */
+ public final static String FRAGMENT_HOST = "Fragment-Host";
+
+ /**
+ * Manifest header attribute (named "selection-filter") is used
+ * for selection by filtering based upon system properties.
+ *
+ * <p>
+ * The attribute value is encoded in manifest headers like:
+ *
+ * <pre>
+ * Bundle-NativeCode: libgtk.so; selection-filter="(ws=gtk)"; ...
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String SELECTION_FILTER_ATTRIBUTE = "selection-filter";
+
+ /**
+ * Manifest header (named "Bundle-ManifestVersion") identifying
+ * the bundle manifest version. A bundle manifest may express the version of
+ * the syntax in which it is written by specifying a bundle manifest
+ * version. Bundles exploiting OSGi R4, or later, syntax must specify a
+ * bundle manifest version.
+ * <p>
+ * The bundle manifest version defined by OSGi R4 or, more specifically, by
+ * V1.3 of the OSGi Framework Specification is "2".
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ *
+ * @since 1.3
+ */
+ public final static String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
+
+ /**
+ * Manifest header attribute (named "version") identifying the
+ * version of a package specified in the Export-Package or Import-Package
+ * manifest header.
+ *
+ * <p>
+ * The attribute value is encoded in the Export-Package or Import-Package
+ * manifest header like:
+ *
+ * <pre>
+ * Import-Package: org.osgi.framework; version="1.1"
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String VERSION_ATTRIBUTE = "version";
+
+ /**
+ * Manifest header attribute (named "bundle-symbolic-name")
+ * identifying the symbolic name of a bundle that exports a package
+ * specified in the Import-Package manifest header.
+ *
+ * <p>
+ * The attribute value is encoded in the Import-Package manifest header
+ * like:
+ *
+ * <pre>
+ * Import-Package: org.osgi.framework; bundle-symbolic-name="com.acme.module.test"
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String BUNDLE_SYMBOLICNAME_ATTRIBUTE = "bundle-symbolic-name";
+
+ /**
+ * Manifest header directive (named "resolution") identifying the
+ * resolution type in the Import-Package or Require-Bundle manifest header.
+ *
+ * <p>
+ * The directive value is encoded in the Import-Package or Require-Bundle
+ * manifest header like:
+ *
+ * <pre>
+ * Import-Package: org.osgi.framework; resolution:="optional"
+ * Require-Bundle: com.acme.module.test; resolution:="optional"
+ * </pre>
+ *
+ * @see Constants#RESOLUTION_MANDATORY
+ * @see Constants#RESOLUTION_OPTIONAL
+ * @since 1.3
+ */
+ public final static String RESOLUTION_DIRECTIVE = "resolution";
+
+ /**
+ * Manifest header directive value (named "mandatory") identifying
+ * a mandatory resolution type. A mandatory resolution type indicates that
+ * the import package or require bundle must be resolved when the bundle is
+ * resolved. If such an import or require bundle cannot be resolved, the
+ * module fails to resolve.
+ *
+ * <p>
+ * The directive value is encoded in the Import-Package or Require-Bundle
+ * manifest header like:
+ *
+ * <pre>
+ * Import-Package: org.osgi.framework; resolution:="manditory"
+ * Require-Bundle: com.acme.module.test; resolution:="manditory"
+ * </pre>
+ *
+ * @see Constants#RESOLUTION_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String RESOLUTION_MANDATORY = "mandatory";
+
+ /**
+ * Manifest header directive value (named "optional") identifying
+ * an optional resolution type. An optional resolution type indicates that
+ * the import or require bundle is optional and the bundle may be resolved
+ * without the import or require bundle being resolved. If the import or
+ * require bundle is not resolved when the bundle is resolved, the import or
+ * require bundle may not be resolved before the bundle is refreshed.
+ *
+ * <p>
+ * The directive value is encoded in the Import-Package or Require-Bundle
+ * manifest header like:
+ *
+ * <pre>
+ * Import-Package: org.osgi.framework; resolution:="optional"
+ * Require-Bundle: com.acme.module.test; resolution:="optional"
+ * </pre>
+ *
+ * @see Constants#RESOLUTION_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String RESOLUTION_OPTIONAL = "optional";
+
+ /**
+ * Manifest header directive (named "uses") identifying a list of
+ * packages that an exported package uses.
+ *
+ * <p>
+ * The directive value is encoded in the Export-Package manifest header
+ * like:
+ *
+ * <pre>
+ * Export-Package: org.osgi.util.tracker; uses:="org.osgi.framework"
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String USES_DIRECTIVE = "uses";
+
+ /**
+ * Manifest header directive (named "include") identifying a list
+ * of classes and/or resources of the specified package which must be
+ * allowed to be exported in the Export-Package manifest header.
+ *
+ * <p>
+ * The directive value is encoded in the Export-Package manifest header
+ * like:
+ *
+ * <pre>
+ * Export-Package: org.osgi.framework; include:="MyStuff*"
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String INCLUDE_DIRECTIVE = "include";
+
+ /**
+ * Manifest header directive (named "exclude") identifying a list
+ * of classes and/or resources of the specified package which must not be
+ * allowed to be exported in the Export-Package manifest header.
+ *
+ * <p>
+ * The directive value is encoded in the Export-Package manifest header
+ * like:
+ *
+ * <pre>
+ * Export-Package: org.osgi.framework; exclude:="MyStuff*"
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String EXCLUDE_DIRECTIVE = "exclude";
+
+ /**
+ * Manifest header directive (named "mandatory") identifying names
+ * of matching attributes which must be specified by matching Import-Package
+ * statements in the Export-Package manifest header.
+ *
+ * <p>
+ * The directive value is encoded in the Export-Package manifest header
+ * like:
+ *
+ * <pre>
+ * Export-Package: org.osgi.framework; mandatory:="bundle-symbolic-name"
+ * </pre>
+ *
+ * @since 1.3
+ */
+ public final static String MANDATORY_DIRECTIVE = "mandatory";
+
+ /**
+ * Manifest header directive (named "visibility") identifying the
+ * visibility of a reqiured bundle in the Require-Bundle manifest header.
+ *
+ * <p>
+ * The directive value is encoded in the Require-Bundle manifest header
+ * like:
+ *
+ * <pre>
+ * Require-Bundle: com.acme.module.test; visibility:="reexport"
+ * </pre>
+ *
+ * @see Constants#VISIBILITY_PRIVATE
+ * @see Constants#VISIBILITY_REEXPORT
+ * @since 1.3
+ */
+ public final static String VISIBILITY_DIRECTIVE = "visibility";
+
+ /**
+ * Manifest header directive value (named "private") identifying a
+ * private visibility type. A private visibility type indicates that any
+ * packages that are exported by the required bundle are not made visible on
+ * the export signature of the requiring bundle.
+ *
+ * <p>
+ * The directive value is encoded in the Require-Bundle manifest header
+ * like:
+ *
+ * <pre>
+ * Require-Bundle: com.acme.module.test; visibility:="private"
+ * </pre>
+ *
+ * @see Constants#VISIBILITY_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String VISIBILITY_PRIVATE = "private";
+
+ /**
+ * Manifest header directive value (named "reexport") identifying
+ * a reexport visibility type. A reexport visibility type indicates any
+ * packages that are exported by the required bundle are re-exported by the
+ * requiring bundle. Any arbitrary arbitrary matching attributes with which
+ * they were exported by the required bundle are deleted.
+ *
+ * <p>
+ * The directive value is encoded in the Require-Bundle manifest header
+ * like:
+ *
+ * <pre>
+ * Require-Bundle: com.acme.module.test; visibility:="reexport"
+ * </pre>
+ *
+ * @see Constants#VISIBILITY_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String VISIBILITY_REEXPORT = "reexport";
+ /**
+ * Manifest header directive (named "extension")
+ * identifying the type of the extension fragment.
+ *
+ * <p>
+ * The directive value is encoded in the Fragment-Host manifest header
+ * like:
+ *
+ * <pre>
+ * Fragment-Host: system.bundle; extension:="framework"
+ * </pre>
+ *
+ * @see Constants#EXTENSION_FRAMEWORK
+ * @see Constants#EXTENSION_BOOTCLASSPATH
+ * @since 1.3
+ */
+ public final static String EXTENSION_DIRECTIVE = "extension";
+
+ /**
+ * Manifest header directive value (named "framework") identifying
+ * the type of extension fragment. An extension fragment type of framework
+ * indicates that the extension fragment is to be loaded by
+ * the framework's class loader.
+ *
+ * <p>
+ * The directive value is encoded in the Fragment-Host manifest header
+ * like:
+ *
+ * <pre>
+ * Fragment-Host: system.bundle; extension:="framework"
+ * </pre>
+ *
+ * @see Constants#EXTENSION_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String EXTENSION_FRAMEWORK = "framework";
+
+ /**
+ * Manifest header directive value (named "bootclasspath") identifying
+ * the type of extension fragment. An extension fragment type of bootclasspath
+ * indicates that the extension fragment is to be loaded by
+ * the boot class loader.
+ *
+ * <p>
+ * The directive value is encoded in the Fragment-Host manifest header
+ * like:
+ *
+ * <pre>
+ * Fragment-Host: system.bundle; extension:="bootclasspath"
+ * </pre>
+ *
+ * @see Constants#EXTENSION_DIRECTIVE
+ * @since 1.3
+ */
+ public final static String EXTENSION_BOOTCLASSPATH = "bootclasspath";
+
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/framework/Filter.java b/org.osgi/src/main/java/org/osgi/framework/Filter.java
index 262675f..a3180ba 100644
--- a/org.osgi/src/main/java/org/osgi/framework/Filter.java
+++ b/org.osgi/src/main/java/org/osgi/framework/Filter.java
@@ -1,111 +1,123 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Filter.java,v 1.11 2005/05/13 20:32:56 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-package org.osgi.framework;
-
-import java.util.Dictionary;
-
-/**
- * An RFC 1960-based Filter.
- * <p>
- * <code>Filter</code> objects can be created by calling
- * {@link BundleContext#createFilter} with the chosen filter string.
- * <p>
- * A <code>Filter</code> object can be used numerous times to determine if the
- * match argument matches the filter string that was used to create the
- * <code>Filter</code> object.
- * <p>
- * Some examples of LDAP filters are:
- *
- * <pre>
- * "(cn=Babs Jensen)"
- * "(!(cn=Tim Howes))"
- * "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
- * "(o=univ*of*mich*)"
- * </pre>
- *
- * @version $Revision: 1.11 $
- * @since 1.1
- * @see "Framework specification for a description of the filter string syntax."
- */
-public interface Filter {
- /**
- * Filter using a service's properties.
- * <p>
- * The filter is executed using the keys and values of the referenced service's
- * properties. The keys are case insensitively matched with the filter.
- *
- * @param reference The reference to the service whose properties are used
- * in the match.
- *
- * @return <code>true</code> if the service's properties match this filter;
- * <code>false</code> otherwise.
- */
- public boolean match(ServiceReference reference);
-
- /**
- * Filter using a <code>Dictionary</code> object. The Filter is executed using
- * the <code>Dictionary</code> object's keys and values.
- * The keys are case insensitively matched with the filter.
- *
- * @param dictionary The <code>Dictionary</code> object whose keys are used in
- * the match.
- *
- * @return <code>true</code> if the <code>Dictionary</code> object's keys and
- * values match this filter; <code>false</code> otherwise.
- *
- * @exception IllegalArgumentException If <code>dictionary</code> contains
- * case variants of the same key name.
- */
- public boolean match(Dictionary dictionary);
-
- /**
- * Returns this <code>Filter</code> object's filter string.
- * <p>
- * The filter string is normalized by removing whitespace which does not
- * affect the meaning of the filter.
- *
- * @return Filter string.
- */
- public String toString();
-
- /**
- * Compares this <code>Filter</code> object to another object.
- *
- * @param obj The object to compare against this <code>Filter</code> object.
- *
- * @return If the other object is a <code>Filter</code> object, then returns
- * <code>this.toString().equals(obj.toString()</code>;<code>false</code>
- * otherwise.
- */
- public boolean equals(Object obj);
-
- /**
- * Returns the hashCode for this <code>Filter</code> object.
- *
- * @return The hashCode of the filter string; that is,
- * <code>this.toString().hashCode()</code>.
- */
- public int hashCode();
-
- /**
- * Filter with case sensitivity using a <code>Dictionary</code> object. The
- * Filter is executed using the <code>Dictionary</code> object's keys and
- * values. The keys are case sensitively matched with the filter.
- *
- * @param dictionary The <code>Dictionary</code> object whose keys are used in
- * the match.
- *
- * @return <code>true</code> if the <code>Dictionary</code> object's keys and
- * values match this filter; <code>false</code> otherwise.
- *
- * @since 1.3
- */
- public boolean matchCase(Dictionary dictionary);
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Filter.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.Dictionary;
+
+/**
+ * An RFC 1960-based Filter.
+ * <p>
+ * <code>Filter</code> objects can be created by calling
+ * {@link BundleContext#createFilter} with the chosen filter string.
+ * <p>
+ * A <code>Filter</code> object can be used numerous times to determine if the
+ * match argument matches the filter string that was used to create the
+ * <code>Filter</code> object.
+ * <p>
+ * Some examples of LDAP filters are:
+ *
+ * <pre>
+ * "(cn=Babs Jensen)"
+ * "(!(cn=Tim Howes))"
+ * "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
+ * "(o=univ*of*mich*)"
+ * </pre>
+ *
+ * @version $Revision: 1.13 $
+ * @since 1.1
+ * @see "Framework specification for a description of the filter string syntax."
+ */
+public interface Filter {
+ /**
+ * Filter using a service's properties.
+ * <p>
+ * The filter is executed using the keys and values of the referenced
+ * service's properties. The keys are case insensitively matched with the
+ * filter.
+ *
+ * @param reference The reference to the service whose properties are used
+ * in the match.
+ *
+ * @return <code>true</code> if the service's properties match this
+ * filter; <code>false</code> otherwise.
+ */
+ public boolean match(ServiceReference reference);
+
+ /**
+ * Filter using a <code>Dictionary</code> object. The Filter is executed
+ * using the <code>Dictionary</code> object's keys and values. The keys
+ * are case insensitively matched with the filter.
+ *
+ * @param dictionary The <code>Dictionary</code> object whose keys are
+ * used in the match.
+ *
+ * @return <code>true</code> if the <code>Dictionary</code> object's
+ * keys and values match this filter; <code>false</code>
+ * otherwise.
+ *
+ * @throws IllegalArgumentException If <code>dictionary</code> contains
+ * case variants of the same key name.
+ */
+ public boolean match(Dictionary dictionary);
+
+ /**
+ * Returns this <code>Filter</code> object's filter string.
+ * <p>
+ * The filter string is normalized by removing whitespace which does not
+ * affect the meaning of the filter.
+ *
+ * @return Filter string.
+ */
+ public String toString();
+
+ /**
+ * Compares this <code>Filter</code> object to another object.
+ *
+ * @param obj The object to compare against this <code>Filter</code>
+ * object.
+ *
+ * @return If the other object is a <code>Filter</code> object, then
+ * returns <code>this.toString().equals(obj.toString()</code>;<code>false</code>
+ * otherwise.
+ */
+ public boolean equals(Object obj);
+
+ /**
+ * Returns the hashCode for this <code>Filter</code> object.
+ *
+ * @return The hashCode of the filter string; that is,
+ * <code>this.toString().hashCode()</code>.
+ */
+ public int hashCode();
+
+ /**
+ * Filter with case sensitivity using a <code>Dictionary</code> object.
+ * The Filter is executed using the <code>Dictionary</code> object's keys
+ * and values. The keys are case sensitively matched with the filter.
+ *
+ * @param dictionary The <code>Dictionary</code> object whose keys are
+ * used in the match.
+ *
+ * @return <code>true</code> if the <code>Dictionary</code> object's
+ * keys and values match this filter; <code>false</code>
+ * otherwise.
+ *
+ * @since 1.3
+ */
+ public boolean matchCase(Dictionary dictionary);
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/framework/FrameworkEvent.java b/org.osgi/src/main/java/org/osgi/framework/FrameworkEvent.java
index b226dab..d6f19c6 100644
--- a/org.osgi/src/main/java/org/osgi/framework/FrameworkEvent.java
+++ b/org.osgi/src/main/java/org/osgi/framework/FrameworkEvent.java
@@ -1,199 +1,207 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkEvent.java,v 1.9 2005/05/13 20:32:56 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.EventObject;
-
-/**
- * A general Framework event.
- *
- * <p>
- * <code>FrameworkEvent</code> is the event class used when notifying listeners of
- * general events occuring within the OSGI environment. A type code is used to
- * identify the event type for future extendability.
- *
- * <p>
- * OSGi Alliance reserves the right to extend the set of event types.
- *
- * @version $Revision: 1.9 $
- */
-
-public class FrameworkEvent extends EventObject {
- static final long serialVersionUID = 207051004521261705L;
- /**
- * Bundle related to the event.
- */
- private Bundle bundle;
-
- /**
- * Exception related to the event.
- */
- private Throwable throwable;
-
- /**
- * Type of event.
- */
- private int type;
-
- /**
- * The Framework has started.
- *
- * <p>
- * This event is broadcast when the Framework has started after all
- * installed bundles that are marked to be started have been started and the
- * Framework has reached the intitial start level.
- *
- * <p>
- * The value of <code>STARTED</code> is 0x00000001.
- *
- * @see "<code>StartLevel</code>"
- */
- public final static int STARTED = 0x00000001;
-
- /**
- * An error has occurred.
- *
- * <p>
- * There was an error associated with a bundle.
- *
- * <p>
- * The value of <code>ERROR</code> is 0x00000002.
- */
- public final static int ERROR = 0x00000002;
-
- /**
- * A PackageAdmin.refreshPackage operation has completed.
- *
- * <p>
- * This event is broadcast when the Framework has completed the refresh
- * packages operation initiated by a call to the
- * PackageAdmin.refreshPackages method.
- *
- * <p>
- * The value of <code>PACKAGES_REFRESHED</code> is 0x00000004.
- *
- * @since 1.2
- * @see "<code>PackageAdmin.refreshPackages</code>"
- */
- public final static int PACKAGES_REFRESHED = 0x00000004;
-
- /**
- * A StartLevel.setStartLevel operation has completed.
- *
- * <p>
- * This event is broadcast when the Framework has completed changing the
- * active start level initiated by a call to the StartLevel.setStartLevel
- * method.
- *
- * <p>
- * The value of <code>STARTLEVEL_CHANGED</code> is 0x00000008.
- *
- * @since 1.2
- * @see "<code>StartLevel</code>"
- */
- public final static int STARTLEVEL_CHANGED = 0x00000008;
-
- /**
- * A warning has occurred.
- *
- * <p>
- * There was a warning associated with a bundle.
- *
- * <p>
- * The value of <code>WARNING</code> is 0x00000010.
- *
- * @since 1.3
- */
- public final static int WARNING = 0x00000010;
-
- /**
- * An informational event has occurred.
- *
- * <p>
- * There was an informational event associated with a bundle.
- *
- * <p>
- * The value of <code>INFO</code> is 0x00000020.
- *
- * @since 1.3
- */
- public final static int INFO = 0x00000020;
-
- /**
- * Creates a Framework event.
- *
- * @param type The event type.
- * @param source The event source object. This may not be <code>null</code>.
- * @deprecated Since 1.2. This constructor is deprecated in favor of using
- * the other constructor with the System Bundle as the event
- * source.
- */
- public FrameworkEvent(int type, Object source) {
- super(source);
- this.type = type;
- this.bundle = null;
- this.throwable = null;
- }
-
- /**
- * Creates a Framework event regarding the specified bundle.
- *
- * @param type The event type.
- * @param bundle The event source.
- * @param throwable The related exception. This argument may be
- * <code>null</code> if there is no related exception.
- */
- public FrameworkEvent(int type, Bundle bundle, Throwable throwable) {
- super(bundle);
- this.type = type;
- this.bundle = bundle;
- this.throwable = throwable;
- }
-
- /**
- * Returns the exception related to this event.
- *
- * @return The related exception or <code>null</code> if none.
- */
- public Throwable getThrowable() {
- return throwable;
- }
-
- /**
- * Returns the bundle associated with the event. This bundle is also the
- * source of the event.
- *
- * @return The bundle associated with the event.
- */
- public Bundle getBundle() {
- return bundle;
- }
-
- /**
- * Returns the type of framework event.
- * <p>
- * The type values are:
- * <ul>
- * <li>{@link #STARTED}
- * <li>{@link #ERROR}
- * <li>{@link #WARNING}
- * <li>{@link #INFO}
- * <li>{@link #PACKAGES_REFRESHED}
- * <li>{@link #STARTLEVEL_CHANGED}
- * </ul>
- *
- * @return The type of state change.
- */
-
- public int getType() {
- return type;
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkEvent.java,v 1.12 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.framework;
+
+import java.util.EventObject;
+
+/**
+ * A general event from the Framework.
+ *
+ * <p>
+ * <code>FrameworkEvent</code> is the event class used when notifying
+ * listeners of general events occuring within the OSGI environment. A type code
+ * is used to identify the event type for future extendability.
+ *
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of event types.
+ *
+ * @version $Revision: 1.12 $
+ */
+
+public class FrameworkEvent extends EventObject {
+ static final long serialVersionUID = 207051004521261705L;
+ /**
+ * Bundle related to the event.
+ */
+ private Bundle bundle;
+
+ /**
+ * Exception related to the event.
+ */
+ private Throwable throwable;
+
+ /**
+ * Type of event.
+ */
+ private int type;
+
+ /**
+ * The Framework has started.
+ *
+ * <p>
+ * This event is fired when the Framework has started after all
+ * installed bundles that are marked to be started have been started and the
+ * Framework has reached the intitial start level.
+ *
+ * <p>
+ * The value of <code>STARTED</code> is 0x00000001.
+ *
+ * @see "<code>StartLevel</code>"
+ */
+ public final static int STARTED = 0x00000001;
+
+ /**
+ * An error has occurred.
+ *
+ * <p>
+ * There was an error associated with a bundle.
+ *
+ * <p>
+ * The value of <code>ERROR</code> is 0x00000002.
+ */
+ public final static int ERROR = 0x00000002;
+
+ /**
+ * A PackageAdmin.refreshPackage operation has completed.
+ *
+ * <p>
+ * This event is fired when the Framework has completed the refresh
+ * packages operation initiated by a call to the
+ * PackageAdmin.refreshPackages method.
+ *
+ * <p>
+ * The value of <code>PACKAGES_REFRESHED</code> is 0x00000004.
+ *
+ * @since 1.2
+ * @see "<code>PackageAdmin.refreshPackages</code>"
+ */
+ public final static int PACKAGES_REFRESHED = 0x00000004;
+
+ /**
+ * A StartLevel.setStartLevel operation has completed.
+ *
+ * <p>
+ * This event is fired when the Framework has completed changing the
+ * active start level initiated by a call to the StartLevel.setStartLevel
+ * method.
+ *
+ * <p>
+ * The value of <code>STARTLEVEL_CHANGED</code> is 0x00000008.
+ *
+ * @since 1.2
+ * @see "<code>StartLevel</code>"
+ */
+ public final static int STARTLEVEL_CHANGED = 0x00000008;
+
+ /**
+ * A warning has occurred.
+ *
+ * <p>
+ * There was a warning associated with a bundle.
+ *
+ * <p>
+ * The value of <code>WARNING</code> is 0x00000010.
+ *
+ * @since 1.3
+ */
+ public final static int WARNING = 0x00000010;
+
+ /**
+ * An informational event has occurred.
+ *
+ * <p>
+ * There was an informational event associated with a bundle.
+ *
+ * <p>
+ * The value of <code>INFO</code> is 0x00000020.
+ *
+ * @since 1.3
+ */
+ public final static int INFO = 0x00000020;
+
+ /**
+ * Creates a Framework event.
+ *
+ * @param type The event type.
+ * @param source The event source object. This may not be <code>null</code>.
+ * @deprecated Since 1.2. This constructor is deprecated in favor of using
+ * the other constructor with the System Bundle as the event
+ * source.
+ */
+ public FrameworkEvent(int type, Object source) {
+ super(source);
+ this.type = type;
+ this.bundle = null;
+ this.throwable = null;
+ }
+
+ /**
+ * Creates a Framework event regarding the specified bundle.
+ *
+ * @param type The event type.
+ * @param bundle The event source.
+ * @param throwable The related exception. This argument may be
+ * <code>null</code> if there is no related exception.
+ */
+ public FrameworkEvent(int type, Bundle bundle, Throwable throwable) {
+ super(bundle);
+ this.type = type;
+ this.bundle = bundle;
+ this.throwable = throwable;
+ }
+
+ /**
+ * Returns the exception related to this event.
+ *
+ * @return The related exception or <code>null</code> if none.
+ */
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ /**
+ * Returns the bundle associated with the event. This bundle is also the
+ * source of the event.
+ *
+ * @return The bundle associated with the event.
+ */
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ /**
+ * Returns the type of framework event.
+ * <p>
+ * The type values are:
+ * <ul>
+ * <li>{@link #STARTED}
+ * <li>{@link #ERROR}
+ * <li>{@link #WARNING}
+ * <li>{@link #INFO}
+ * <li>{@link #PACKAGES_REFRESHED}
+ * <li>{@link #STARTLEVEL_CHANGED}
+ * </ul>
+ *
+ * @return The type of state change.
+ */
+
+ public int getType() {
+ return type;
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/FrameworkListener.java b/org.osgi/src/main/java/org/osgi/framework/FrameworkListener.java
index e97b4e4..d1ced14 100644
--- a/org.osgi/src/main/java/org/osgi/framework/FrameworkListener.java
+++ b/org.osgi/src/main/java/org/osgi/framework/FrameworkListener.java
@@ -1,39 +1,48 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkListener.java,v 1.6 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.EventListener;
-
-/**
- * A <code>FrameworkEvent</code> listener.
- *
- * <p>
- * <code>FrameworkListener</code> is a listener interface that may be implemented
- * by a bundle developer. A <code>FrameworkListener</code> object is registered
- * with the Framework using the {@link BundleContext#addFrameworkListener}
- * method. <code>FrameworkListener</code> objects are called with a
- * <code>FrameworkEvent</code> objects when the Framework starts and when
- * asynchronous errors occur.
- *
- * @version $Revision: 1.6 $
- * @see FrameworkEvent
- */
-
-public abstract interface FrameworkListener extends EventListener {
-
- /**
- * Receives notification of a general <code>FrameworkEvent</code> object.
- *
- * @param event The <code>FrameworkEvent</code> object.
- */
- public abstract void frameworkEvent(FrameworkEvent event);
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkListener.java,v 1.9 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.EventListener;
+
+/**
+ * A <code>FrameworkEvent</code> listener. When a <code>FrameworkEvent</code> is
+ * fired, it is asynchronously delivered to a <code>FrameworkListener</code>.
+ *
+ * <p>
+ * <code>FrameworkListener</code> is a listener interface that may be
+ * implemented by a bundle developer. A <code>FrameworkListener</code> object
+ * is registered with the Framework using the
+ * {@link BundleContext#addFrameworkListener} method.
+ * <code>FrameworkListener</code> objects are called with a
+ * <code>FrameworkEvent</code> objects when the Framework starts and when
+ * asynchronous errors occur.
+ *
+ * @version $Revision: 1.9 $
+ * @see FrameworkEvent
+ */
+
+public interface FrameworkListener extends EventListener {
+
+ /**
+ * Receives notification of a general <code>FrameworkEvent</code> object.
+ *
+ * @param event The <code>FrameworkEvent</code> object.
+ */
+ public void frameworkEvent(FrameworkEvent event);
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/FrameworkUtil.java b/org.osgi/src/main/java/org/osgi/framework/FrameworkUtil.java
index 3056e01..4f25652 100644
--- a/org.osgi/src/main/java/org/osgi/framework/FrameworkUtil.java
+++ b/org.osgi/src/main/java/org/osgi/framework/FrameworkUtil.java
@@ -1,85 +1,141 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkUtil.java,v 1.1 2005/07/14 20:32:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-
-import java.lang.reflect.Constructor;
-
-
-/**
- * Framework Utility class.
- *
- * <p>
- * This class contains utility methods which access Framework functions that may
- * be useful to bundles.
- *
- * @version $Revision: 1.1 $
- * @since 1.3
- */
-public class FrameworkUtil
-{
- private static final Class[] CONST_ARGS = new Class[] { String.class };
- private static final String FILTER_IMPL_FQCN = "org.osgi.framework.filterImplFQCN";
- private static final String FILTER_IMPL_DEFAULT = "org.apache.felix.framework.FilterImpl";
- private static Class filterImplClass;
-
-
- /**
- * Creates a <code>Filter</code> object. This <code>Filter</code> object
- * may be used to match a <code>ServiceReference</code> object or a
- * <code>Dictionary</code> object.
- *
- * <p>
- * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
- * thrown with a human readable message where the filter became unparsable.
- *
- * @param filter The filter string.
- * @return A <code>Filter</code> object encapsulating the filter string.
- * @throws InvalidSyntaxException If <code>filter</code> contains an
- * invalid filter string that cannot be parsed.
- * @throws NullPointerException If <code>filter</code> is null.
- *
- * @see Filter
- */
- public static Filter createFilter( String filter ) throws InvalidSyntaxException
- {
- if ( filterImplClass == null )
- {
- String fqcn = System.getProperty( FILTER_IMPL_FQCN );
- if ( fqcn == null )
- {
- fqcn = FILTER_IMPL_DEFAULT;
- }
-
- try
- {
- filterImplClass = Class.forName( fqcn );
- }
- catch ( ClassNotFoundException e )
- {
- throw new RuntimeException( "Failed to load filter implementation class: " + fqcn );
- }
- }
-
- Constructor constructor;
- try
- {
- constructor = filterImplClass.getConstructor( CONST_ARGS );
- Filter instance = ( Filter ) constructor.newInstance( new Object[] { filter } );
- return instance;
- }
- catch ( Exception e )
- {
- throw new RuntimeException( "Failed to instantiate filter using implementation class: "
- + filterImplClass.getName() );
- }
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/FrameworkUtil.java,v 1.5 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (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.framework;
+
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Framework Utility class.
+ *
+ * <p>
+ * This class contains utility methods which access Framework functions that may
+ * be useful to bundles.
+ *
+ * @version $Revision: 1.5 $
+ * @since 1.3
+ */
+public class FrameworkUtil {
+ /*
+ * NOTE: A framework implementor may also choose to replace this class in
+ * their distribution with a class that directly interfaces with the
+ * framework implementation.
+ */
+
+ /*
+ * This class will load the FrameworkUtil class in the package named by the
+ * org.osgi.vendor.framework package. For each instance of this class, an
+ * instance of the vendor FrameworkUtil class will be created and this class
+ * will delegate method calls to the vendor FrameworkUtil instance.
+ */
+ private static final String packageProperty = "org.osgi.vendor.framework";
+
+ /*
+ * This is the delegate method used by createFilter.
+ */
+ private final static Method createFilter;
+
+ static {
+ createFilter = (Method) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String packageName = System
+ .getProperty(packageProperty);
+ if (packageName == null) {
+ throw new NoClassDefFoundError(packageProperty
+ + " property not set");
+ }
+
+ Class delegateClass;
+ try {
+ delegateClass = Class.forName(packageName
+ + ".FrameworkUtil");
+ }
+ catch (ClassNotFoundException e) {
+ throw new NoClassDefFoundError(e.toString());
+ }
+
+ Method result;
+ try {
+ result = delegateClass.getMethod("createFilter",
+ new Class[] {String.class});
+ }
+ catch (NoSuchMethodException e) {
+ throw new NoSuchMethodError(e.toString());
+ }
+
+ if (!Modifier.isStatic(result.getModifiers())) {
+ throw new NoSuchMethodError(
+ "createFilter method must be static");
+ }
+
+ return result;
+ }
+ });
+ }
+
+
+ /**
+ * FrameworkUtil objects may not be constructed.
+ */
+ private FrameworkUtil() {}
+
+ /**
+ * Creates a <code>Filter</code> object. This <code>Filter</code> object
+ * may be used to match a <code>ServiceReference</code> object or a
+ * <code>Dictionary</code> object.
+ *
+ * <p>
+ * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
+ * thrown with a human readable message where the filter became unparsable.
+ *
+ * @param filter The filter string.
+ * @return A <code>Filter</code> object encapsulating the filter string.
+ * @throws InvalidSyntaxException If <code>filter</code> contains an
+ * invalid filter string that cannot be parsed.
+ * @throws NullPointerException If <code>filter</code> is null.
+ *
+ * @see Filter
+ */
+ public static Filter createFilter(String filter)
+ throws InvalidSyntaxException {
+ try {
+ try {
+ return (Filter) createFilter
+ .invoke(null, new Object[] {filter});
+ }
+ catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+ catch (InvalidSyntaxException e) {
+ throw e;
+ }
+ catch (Error e) {
+ throw e;
+ }
+ catch (RuntimeException e) {
+ throw e;
+ }
+ catch (Throwable e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/InvalidSyntaxException.java b/org.osgi/src/main/java/org/osgi/framework/InvalidSyntaxException.java
index 8d1782d..949d001 100644
--- a/org.osgi/src/main/java/org/osgi/framework/InvalidSyntaxException.java
+++ b/org.osgi/src/main/java/org/osgi/framework/InvalidSyntaxException.java
@@ -1,107 +1,118 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/InvalidSyntaxException.java,v 1.10 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * A Framework exception.
- *
- * <p>
- * An <code>InvalidSyntaxException</code> object indicates that a filter string
- * parameter has an invalid syntax and cannot be parsed.
- *
- * <p>
- * See {@link Filter} for a description of the filter string syntax.
- *
- * @version $Revision: 1.10 $
- */
-
-public class InvalidSyntaxException extends Exception {
- static final long serialVersionUID = -4295194420816491875L;
- /**
- * The invalid filter string.
- */
- private String filter;
- /**
- * Nested exception.
- */
- private Throwable cause;
-
- /**
- * Creates an exception of type <code>InvalidSyntaxException</code>.
- *
- * <p>
- * This method creates an <code>InvalidSyntaxException</code> object with the
- * specified message and the filter string which generated the exception.
- *
- * @param msg The message.
- * @param filter The invalid filter string.
- */
- public InvalidSyntaxException(String msg, String filter) {
- super(msg);
- this.filter = filter;
- this.cause = null;
- }
-
- /**
- * Creates an exception of type <code>InvalidSyntaxException</code>.
- *
- * <p>
- * This method creates an <code>InvalidSyntaxException</code> object with the
- * specified message and the filter string which generated the exception.
- *
- * @param msg The message.
- * @param filter The invalid filter string.
- * @param cause The cause of this exception.
- * @since 1.3
- */
- public InvalidSyntaxException(String msg, String filter, Throwable cause) {
- super(msg);
- this.filter = filter;
- this.cause = cause;
- }
-
- /**
- * Returns the filter string that generated the
- * <code>InvalidSyntaxException</code> object.
- *
- * @return The invalid filter string.
- * @see BundleContext#getServiceReferences
- * @see BundleContext#addServiceListener(ServiceListener,String)
- */
- public String getFilter() {
- return filter;
- }
-
- /**
- * 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.3
- */
- public Throwable getCause() {
- return cause;
- }
-
- /**
- * The cause of this exception can only be set when constructed.
- *
- * @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.3
- */
- public Throwable initCause(Throwable cause) {
- throw new IllegalStateException();
- }
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/InvalidSyntaxException.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * A Framework exception.
+ *
+ * <p>
+ * An <code>InvalidSyntaxException</code> object indicates that a filter
+ * string parameter has an invalid syntax and cannot be parsed.
+ *
+ * <p>
+ * See {@link Filter} for a description of the filter string syntax.
+ *
+ * @version $Revision: 1.13 $
+ */
+
+public class InvalidSyntaxException extends Exception {
+ static final long serialVersionUID = -4295194420816491875L;
+ /**
+ * The invalid filter string.
+ */
+ private String filter;
+ /**
+ * Nested exception.
+ */
+ private Throwable cause;
+
+ /**
+ * Creates an exception of type <code>InvalidSyntaxException</code>.
+ *
+ * <p>
+ * This method creates an <code>InvalidSyntaxException</code> object with
+ * the specified message and the filter string which generated the
+ * exception.
+ *
+ * @param msg The message.
+ * @param filter The invalid filter string.
+ */
+ public InvalidSyntaxException(String msg, String filter) {
+ super(msg);
+ this.filter = filter;
+ this.cause = null;
+ }
+
+ /**
+ * Creates an exception of type <code>InvalidSyntaxException</code>.
+ *
+ * <p>
+ * This method creates an <code>InvalidSyntaxException</code> object with
+ * the specified message and the filter string which generated the
+ * exception.
+ *
+ * @param msg The message.
+ * @param filter The invalid filter string.
+ * @param cause The cause of this exception.
+ * @since 1.3
+ */
+ public InvalidSyntaxException(String msg, String filter, Throwable cause) {
+ super(msg);
+ this.filter = filter;
+ this.cause = cause;
+ }
+
+ /**
+ * Returns the filter string that generated the
+ * <code>InvalidSyntaxException</code> object.
+ *
+ * @return The invalid filter string.
+ * @see BundleContext#getServiceReferences
+ * @see BundleContext#addServiceListener(ServiceListener,String)
+ */
+ public String getFilter() {
+ return filter;
+ }
+
+ /**
+ * 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.3
+ */
+ 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.3
+ */
+ public Throwable initCause(Throwable cause) {
+ throw new IllegalStateException();
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/PackagePermission.java b/org.osgi/src/main/java/org/osgi/framework/PackagePermission.java
index 3dc9b4e..740912e 100644
--- a/org.osgi/src/main/java/org/osgi/framework/PackagePermission.java
+++ b/org.osgi/src/main/java/org/osgi/framework/PackagePermission.java
@@ -1,535 +1,541 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/PackagePermission.java,v 1.10 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.io.IOException;
-import java.security.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-/**
- * A bundle's authority to import or export a package.
- *
- * <p>
- * A package is a dot-separated string that defines a fully qualified Java
- * package.
- * <p>
- * For example:
- *
- * <pre>
- * <code>
- * org.osgi.service.http
- * </code>
- * </pre>
- *
- * <p>
- * <code>PackagePermission</code> has two actions: <code>EXPORT</code> and
- * <code>IMPORT</code>. The <code>EXPORT</code> action implies the <code>IMPORT</code>
- * action.
- *
- * @version $Revision: 1.10 $
- */
-
-public final class PackagePermission extends BasicPermission {
- static final long serialVersionUID = -5107705877071099135L;
- /**
- * The action string <code>export</code>.
- */
- public final static String EXPORT = "export";
-
- /**
- * The action string <code>import</code>.
- */
- public final static String IMPORT = "import";
-
- private final static int ACTION_EXPORT = 0x00000001;
- private final static int ACTION_IMPORT = 0x00000002;
- private final static int ACTION_ALL = ACTION_EXPORT
- | ACTION_IMPORT;
- private final static int ACTION_NONE = 0;
-// NOT USED
-// private final static int ACTION_ERROR = 0x80000000;
-
- /**
- * The actions mask.
- */
- private transient int action_mask = ACTION_NONE;
-
- /**
- * The actions in canonical form.
- *
- * @serial
- */
- private String actions = null;
-
- /**
- * Defines the authority to import and/or export a package within the OSGi
- * environment.
- * <p>
- * The name is specified as a normal Java package name: a dot-separated
- * string. Wildcards may be used. For example:
- *
- * <pre>
- *
- * org.osgi.service.http
- * javax.servlet.*
- * *
- *
- * </pre>
- *
- * <p>
- * Package Permissions are granted over all possible versions of a package.
- *
- * A bundle that needs to export a package must have the appropriate
- * <code>PackagePermission</code> for that package; similarly, a bundle that
- * needs to import a package must have the appropriate
- * <code>PackagePermssion</code> for that package.
- * <p>
- * Permission is granted for both classes and resources.
- *
- * @param name Package name.
- * @param actions <code>EXPORT</code>,<code>IMPORT</code> (canonical order).
- */
-
- public PackagePermission(String name, String actions) {
- this(name, getMask(actions));
- }
-
- /**
- * Package private constructor used by PackagePermissionCollection.
- *
- * @param name class name
- * @param mask action mask
- */
- PackagePermission(String name, int mask) {
- super(name);
- init(mask);
- }
-
- /**
- * Called by constructors and when deserialized.
- *
- * @param mask action mask
- */
- private void init(int mask) {
- if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
- throw new IllegalArgumentException("invalid action string");
- }
-
- action_mask = mask;
- }
-
- /**
- * Parse action string into 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 >= 5 && (a[i - 5] == 'i' || a[i - 5] == 'I')
- && (a[i - 4] == 'm' || a[i - 4] == 'M')
- && (a[i - 3] == 'p' || a[i - 3] == 'P')
- && (a[i - 2] == 'o' || a[i - 2] == 'O')
- && (a[i - 1] == 'r' || a[i - 1] == 'R')
- && (a[i] == 't' || a[i] == 'T')) {
- matchlen = 6;
- mask |= ACTION_IMPORT;
-
- }
- else
- if (i >= 5 && (a[i - 5] == 'e' || a[i - 5] == 'E')
- && (a[i - 4] == 'x' || a[i - 4] == 'X')
- && (a[i - 3] == 'p' || a[i - 3] == 'P')
- && (a[i - 2] == 'o' || a[i - 2] == 'O')
- && (a[i - 1] == 'r' || a[i - 1] == 'R')
- && (a[i] == 't' || a[i] == 'T')) {
- matchlen = 6;
- mask |= ACTION_EXPORT | ACTION_IMPORT;
-
- }
- 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);
- }
-
- /**
- * Determines if the specified permission is implied by this object.
- *
- * <p>
- * This method checks that the package name of the target is implied by the
- * package name of this object. The list of <code>PackagePermission</code>
- * actions must either match or allow for the list of the target object to
- * imply the target <code>PackagePermission</code> action.
- * <p>
- * The permission to export a package implies the permission to import the
- * named package.
- *
- * <pre>
- * x.y.*,"export" -> x.y.z,"export" is true
- * *,"import" -> x.y, "import" is true
- * *,"export" -> x.y, "import" is true
- * x.y,"export" -> x.y.z, "export" is false
- * </pre>
- *
- * @param p The target permission to interrogate.
- * @return <code>true</code> if the specified <code>PackagePermission</code>
- * action is implied by this object; <code>false</code> otherwise.
- */
-
- public boolean implies(Permission p) {
- if (p instanceof PackagePermission) {
- PackagePermission target = (PackagePermission) p;
-
- return (((action_mask & target.action_mask) == target.action_mask) && super
- .implies(p));
- }
-
- return (false);
- }
-
- /**
- * Returns the canonical string representation of the
- * <code>PackagePermission</code> actions.
- *
- * <p>
- * Always returns present <code>PackagePermission</code> actions in the
- * following order: <code>EXPORT</code>,<code>IMPORT</code>.
- *
- * @return Canonical string representation of the <code>PackagePermission</code>
- * actions.
- */
-
- public String getActions() {
- if (actions == null) {
- StringBuffer sb = new StringBuffer();
- boolean comma = false;
-
- if ((action_mask & ACTION_EXPORT) == ACTION_EXPORT) {
- sb.append(EXPORT);
- comma = true;
- }
-
- if ((action_mask & ACTION_IMPORT) == ACTION_IMPORT) {
- if (comma)
- sb.append(',');
- sb.append(IMPORT);
- }
-
- actions = sb.toString();
- }
-
- return (actions);
- }
-
- /**
- * Returns a new <code>PermissionCollection</code> object suitable for storing
- * <code>PackagePermission</code> objects.
- *
- * @return A new <code>PermissionCollection</code> object.
- */
- public PermissionCollection newPermissionCollection() {
- return (new PackagePermissionCollection());
- }
-
- /**
- * Determines the equality of two <code>PackagePermission</code> objects.
- *
- * This method checks that specified package has the same package name and
- * <code>PackagePermission</code> actions as this <code>PackagePermission</code>
- * object.
- *
- * @param obj The object to test for equality with this
- * <code>PackagePermission</code> object.
- * @return <code>true</code> if <code>obj</code> is a <code>PackagePermission</code>,
- * and has the same package name and actions as this
- * <code>PackagePermission</code> object; <code>false</code> otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return (true);
- }
-
- if (!(obj instanceof PackagePermission)) {
- return (false);
- }
-
- PackagePermission p = (PackagePermission) obj;
-
- return ((action_mask == p.action_mask) && getName().equals(p.getName()));
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return A hash code value for this object.
- */
-
- public int hashCode() {
- return (getName().hashCode() ^ getActions().hashCode());
- }
-
- /**
- * Returns the current action mask.
- * <p>
- * Used by the PackagePermissionCollection class.
- *
- * @return Current action mask.
- */
- int getMask() {
- return (action_mask);
- }
-
- /**
- * WriteObject is called to save the state of this permission 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();
- }
-
- /**
- * readObject is called to restore the state of this permission from a
- * stream.
- */
- private synchronized void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- // Read in the action, then initialize the rest
- s.defaultReadObject();
- init(getMask(actions));
- }
-}
-
-/**
- * Stores a set of <code>PackagePermission</code> permissions.
- *
- * @see java.security.Permission
- * @see java.security.Permissions
- * @see java.security.PermissionCollection
- */
-
-final class PackagePermissionCollection extends PermissionCollection {
- static final long serialVersionUID = -3350758995234427603L;
- /**
- * Table of permissions.
- *
- * @serial
- */
- private Hashtable permissions;
-
- /**
- * Boolean saying if "*" is in the collection.
- *
- * @serial
- */
- private boolean all_allowed;
-
- /**
- * Create an empty PackagePermissions object.
- *
- */
-
- public PackagePermissionCollection() {
- permissions = new Hashtable();
- all_allowed = false;
- }
-
- /**
- * Adds a permission to the <code>PackagePermission</code> objects. The key
- * for the hash is the name.
- *
- * @param permission The <code>PackagePermission</code> object to add.
- *
- * @exception IllegalArgumentException If the permission is not a
- * <code>PackagePermission</code> instance.
- *
- * @exception SecurityException If this <code>PackagePermissionCollection</code>
- * object has been marked read-only.
- */
-
- public void add(Permission permission) {
- if (!(permission instanceof PackagePermission))
- throw new IllegalArgumentException("invalid permission: "
- + permission);
- if (isReadOnly())
- throw new SecurityException("attempt to add a Permission to a "
- + "readonly PermissionCollection");
-
- PackagePermission pp = (PackagePermission) permission;
- String name = pp.getName();
-
- PackagePermission existing = (PackagePermission) permissions.get(name);
-
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = pp.getMask();
- if (oldMask != newMask) {
- permissions.put(name, new PackagePermission(name, oldMask
- | newMask));
-
- }
- }
- else {
- permissions.put(name, permission);
- }
-
- if (!all_allowed) {
- if (name.equals("*"))
- all_allowed = true;
- }
- }
-
- /**
- * Determines if the specified permissions implies the permissions expressed
- * in <code>permission</code>.
- *
- * @param permission The Permission object to compare with this
- * <code>PackagePermission</code> object.
- *
- * @return <code>true</code> if <code>permission</code> is a proper subset of a
- * permission in the set; <code>false</code> otherwise.
- */
-
- public boolean implies(Permission permission) {
- if (!(permission instanceof PackagePermission))
- return (false);
-
- PackagePermission pp = (PackagePermission) permission;
- PackagePermission x;
-
- int desired = pp.getMask();
- int effective = 0;
-
- // short circuit if the "*" Permission was added
- if (all_allowed) {
- x = (PackagePermission) 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 = pp.getName();
-
- x = (PackagePermission) 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, offset;
-
- offset = name.length() - 1;
-
- while ((last = name.lastIndexOf(".", offset)) != -1) {
-
- name = name.substring(0, last + 1) + "*";
- x = (PackagePermission) 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 <code>PackagePermission</code> objects in the
- * container.
- *
- * @return Enumeration of all <code>PackagePermission</code> objects.
- */
-
- public Enumeration elements() {
- return (permissions.elements());
- }
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/PackagePermission.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.io.IOException;
+import java.security.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * A bundle's authority to import or export a package.
+ *
+ * <p>
+ * A package is a dot-separated string that defines a fully qualified Java
+ * package.
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * <code>
+ * org.osgi.service.http
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * <code>PackagePermission</code> has two actions: <code>EXPORT</code> and
+ * <code>IMPORT</code>. The <code>EXPORT</code> action implies the
+ * <code>IMPORT</code> action.
+ *
+ * @version $Revision: 1.13 $
+ */
+
+public final class PackagePermission extends BasicPermission {
+ static final long serialVersionUID = -5107705877071099135L;
+ /**
+ * The action string <code>export</code>.
+ */
+ public final static String EXPORT = "export";
+
+ /**
+ * The action string <code>import</code>.
+ */
+ public final static String IMPORT = "import";
+
+ private final static int ACTION_EXPORT = 0x00000001;
+ private final static int ACTION_IMPORT = 0x00000002;
+ private final static int ACTION_ALL = ACTION_EXPORT
+ | ACTION_IMPORT;
+ private final static int ACTION_NONE = 0;
+ /**
+ * The actions mask.
+ */
+ private transient int action_mask = ACTION_NONE;
+
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private String actions = null;
+
+ /**
+ * Defines the authority to import and/or export a package within the OSGi
+ * environment.
+ * <p>
+ * The name is specified as a normal Java package name: a dot-separated
+ * string. Wildcards may be used. For example:
+ *
+ * <pre>
+ * org.osgi.service.http
+ * javax.servlet.*
+ * *
+ * </pre>
+ *
+ * <p>
+ * Package Permissions are granted over all possible versions of a package.
+ *
+ * A bundle that needs to export a package must have the appropriate
+ * <code>PackagePermission</code> for that package; similarly, a bundle
+ * that needs to import a package must have the appropriate
+ * <code>PackagePermssion</code> for that package.
+ * <p>
+ * Permission is granted for both classes and resources.
+ *
+ * @param name Package name.
+ * @param actions <code>EXPORT</code>,<code>IMPORT</code> (canonical
+ * order).
+ */
+
+ public PackagePermission(String name, String actions) {
+ this(name, getMask(actions));
+ }
+
+ /**
+ * Package private constructor used by PackagePermissionCollection.
+ *
+ * @param name class name
+ * @param mask action mask
+ */
+ PackagePermission(String name, int mask) {
+ super(name);
+ init(mask);
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param mask action mask
+ */
+ private void init(int mask) {
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+
+ action_mask = mask;
+ }
+
+ /**
+ * Parse action string into 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 >= 5 && (a[i - 5] == 'i' || a[i - 5] == 'I')
+ && (a[i - 4] == 'm' || a[i - 4] == 'M')
+ && (a[i - 3] == 'p' || a[i - 3] == 'P')
+ && (a[i - 2] == 'o' || a[i - 2] == 'O')
+ && (a[i - 1] == 'r' || a[i - 1] == 'R')
+ && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 6;
+ mask |= ACTION_IMPORT;
+
+ }
+ else
+ if (i >= 5 && (a[i - 5] == 'e' || a[i - 5] == 'E')
+ && (a[i - 4] == 'x' || a[i - 4] == 'X')
+ && (a[i - 3] == 'p' || a[i - 3] == 'P')
+ && (a[i - 2] == 'o' || a[i - 2] == 'O')
+ && (a[i - 1] == 'r' || a[i - 1] == 'R')
+ && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 6;
+ mask |= ACTION_EXPORT | ACTION_IMPORT;
+
+ }
+ 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);
+ }
+
+ /**
+ * Determines if the specified permission is implied by this object.
+ *
+ * <p>
+ * This method checks that the package name of the target is implied by the
+ * package name of this object. The list of <code>PackagePermission</code>
+ * actions must either match or allow for the list of the target object to
+ * imply the target <code>PackagePermission</code> action.
+ * <p>
+ * The permission to export a package implies the permission to import the
+ * named package.
+ *
+ * <pre>
+ * x.y.*,"export" -> x.y.z,"export" is true
+ * *,"import" -> x.y, "import" is true
+ * *,"export" -> x.y, "import" is true
+ * x.y,"export" -> x.y.z, "export" is false
+ * </pre>
+ *
+ * @param p The target permission to interrogate.
+ * @return <code>true</code> if the specified
+ * <code>PackagePermission</code> action is implied by this
+ * object; <code>false</code> otherwise.
+ */
+
+ public boolean implies(Permission p) {
+ if (p instanceof PackagePermission) {
+ PackagePermission target = (PackagePermission) p;
+
+ return (((action_mask & target.action_mask) == target.action_mask) && super
+ .implies(p));
+ }
+
+ return (false);
+ }
+
+ /**
+ * Returns the canonical string representation of the
+ * <code>PackagePermission</code> actions.
+ *
+ * <p>
+ * Always returns present <code>PackagePermission</code> actions in the
+ * following order: <code>EXPORT</code>,<code>IMPORT</code>.
+ *
+ * @return Canonical string representation of the
+ * <code>PackagePermission</code> actions.
+ */
+
+ public String getActions() {
+ if (actions == null) {
+ StringBuffer sb = new StringBuffer();
+ boolean comma = false;
+
+ if ((action_mask & ACTION_EXPORT) == ACTION_EXPORT) {
+ sb.append(EXPORT);
+ comma = true;
+ }
+
+ if ((action_mask & ACTION_IMPORT) == ACTION_IMPORT) {
+ if (comma)
+ sb.append(',');
+ sb.append(IMPORT);
+ }
+
+ actions = sb.toString();
+ }
+
+ return (actions);
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>PackagePermission</code> objects.
+ *
+ * @return A new <code>PermissionCollection</code> object.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return (new PackagePermissionCollection());
+ }
+
+ /**
+ * Determines the equality of two <code>PackagePermission</code> objects.
+ *
+ * This method checks that specified package has the same package name and
+ * <code>PackagePermission</code> actions as this
+ * <code>PackagePermission</code> object.
+ *
+ * @param obj The object to test for equality with this
+ * <code>PackagePermission</code> object.
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>PackagePermission</code>, and has the same package name
+ * and actions as this <code>PackagePermission</code> object;
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return (true);
+ }
+
+ if (!(obj instanceof PackagePermission)) {
+ return (false);
+ }
+
+ PackagePermission p = (PackagePermission) obj;
+
+ return ((action_mask == p.action_mask) && getName().equals(p.getName()));
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+
+ public int hashCode() {
+ return (getName().hashCode() ^ getActions().hashCode());
+ }
+
+ /**
+ * Returns the current action mask.
+ * <p>
+ * Used by the PackagePermissionCollection class.
+ *
+ * @return Current action mask.
+ */
+ int getMask() {
+ return (action_mask);
+ }
+
+ /**
+ * WriteObject is called to save the state of this permission 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();
+ }
+
+ /**
+ * readObject is called to restore the state of this permission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ init(getMask(actions));
+ }
+}
+
+/**
+ * Stores a set of <code>PackagePermission</code> permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class PackagePermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = -3350758995234427603L;
+ /**
+ * Table of permissions.
+ *
+ * @serial
+ */
+ private Hashtable permissions;
+
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ */
+ private boolean all_allowed;
+
+ /**
+ * Create an empty PackagePermissions object.
+ */
+
+ public PackagePermissionCollection() {
+ permissions = new Hashtable();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to the <code>PackagePermission</code> objects. The
+ * key for the hash is the name.
+ *
+ * @param permission The <code>PackagePermission</code> object to add.
+ *
+ * @throws IllegalArgumentException If the permission is not a
+ * <code>PackagePermission</code> instance.
+ *
+ * @throws SecurityException If this
+ * <code>PackagePermissionCollection</code> object has been marked
+ * read-only.
+ */
+
+ public void add(Permission permission) {
+ if (!(permission instanceof PackagePermission))
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ if (isReadOnly())
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+
+ PackagePermission pp = (PackagePermission) permission;
+ String name = pp.getName();
+
+ PackagePermission existing = (PackagePermission) permissions.get(name);
+
+ if (existing != null) {
+ int oldMask = existing.getMask();
+ int newMask = pp.getMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new PackagePermission(name, oldMask
+ | newMask));
+
+ }
+ }
+ else {
+ permissions.put(name, permission);
+ }
+
+ if (!all_allowed) {
+ if (name.equals("*"))
+ all_allowed = true;
+ }
+ }
+
+ /**
+ * Determines if the specified permissions implies the permissions expressed
+ * in <code>permission</code>.
+ *
+ * @param permission The Permission object to compare with this
+ * <code>PackagePermission</code> object.
+ *
+ * @return <code>true</code> if <code>permission</code> is a proper
+ * subset of a permission in the set; <code>false</code>
+ * otherwise.
+ */
+
+ public boolean implies(Permission permission) {
+ if (!(permission instanceof PackagePermission))
+ return (false);
+
+ PackagePermission pp = (PackagePermission) permission;
+ PackagePermission x;
+
+ int desired = pp.getMask();
+ int effective = 0;
+
+ // short circuit if the "*" Permission was added
+ if (all_allowed) {
+ x = (PackagePermission) 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 = pp.getName();
+
+ x = (PackagePermission) 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, offset;
+
+ offset = name.length() - 1;
+
+ while ((last = name.lastIndexOf(".", offset)) != -1) {
+
+ name = name.substring(0, last + 1) + "*";
+ x = (PackagePermission) 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 <code>PackagePermission</code> objects in
+ * the container.
+ *
+ * @return Enumeration of all <code>PackagePermission</code> objects.
+ */
+
+ public Enumeration elements() {
+ return (permissions.elements());
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/ServiceEvent.java b/org.osgi/src/main/java/org/osgi/framework/ServiceEvent.java
index 29d3650..7fa0b9c 100644
--- a/org.osgi/src/main/java/org/osgi/framework/ServiceEvent.java
+++ b/org.osgi/src/main/java/org/osgi/framework/ServiceEvent.java
@@ -1,129 +1,136 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceEvent.java,v 1.9 2005/05/13 20:32:56 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.Dictionary;
-import java.util.EventObject;
-
-/**
- * A service lifecycle change event.
- * <p>
- * <code>ServiceEvent</code> objects are delivered to a <code>ServiceListener</code>
- * objects when a change occurs in this service's lifecycle. A type code is used
- * to identify the event type for future extendability.
- *
- * <p>
- * OSGi Alliance reserves the right to extend the set of types.
- *
- * @version $Revision: 1.9 $
- * @see ServiceListener
- */
-
-public class ServiceEvent extends EventObject {
- static final long serialVersionUID = 8792901483909409299L;
- /**
- * Reference to the service that had a change occur in its lifecycle.
- */
- private ServiceReference reference;
-
- /**
- * Type of service lifecycle change.
- */
- private int type;
-
- /**
- * This service has been registered.
- * <p>
- * This event is synchronously delivered <strong>after </strong> the service
- * has been registered with the Framework.
- *
- * <p>
- * The value of <code>REGISTERED</code> is 0x00000001.
- *
- * @see BundleContext#registerService(String[],Object,Dictionary)
- */
- public final static int REGISTERED = 0x00000001;
-
- /**
- * The properties of a registered service have been modified.
- * <p>
- * This event is synchronously delivered <strong>after </strong> the service
- * properties have been modified.
- *
- * <p>
- * The value of <code>MODIFIED</code> is 0x00000002.
- *
- * @see ServiceRegistration#setProperties
- */
- public final static int MODIFIED = 0x00000002;
-
- /**
- * This service is in the process of being unregistered.
- * <p>
- * This event is synchronously delivered <strong>before </strong> the
- * service has completed unregistering.
- *
- * <p>
- * If a bundle is using a service that is <code>UNREGISTERING</code>, the
- * bundle should release its use of the service when it receives this event.
- * If the bundle does not release its use of the service when it receives
- * this event, the Framework will automatically release the bundle's use of
- * the service while completing the service unregistration operation.
- *
- * <p>
- * The value of UNREGISTERING is 0x00000004.
- *
- * @see ServiceRegistration#unregister
- * @see BundleContext#ungetService
- */
- public final static int UNREGISTERING = 0x00000004;
-
- /**
- * Creates a new service event object.
- *
- * @param type The event type.
- * @param reference A <code>ServiceReference</code> object to the service that
- * had a lifecycle change.
- */
- public ServiceEvent(int type, ServiceReference reference) {
- super(reference);
- this.reference = reference;
- this.type = type;
- }
-
- /**
- * Returns a reference to the service that had a change occur in its
- * lifecycle.
- * <p>
- * This reference is the source of the event.
- *
- * @return Reference to the service that had a lifecycle change.
- */
- public ServiceReference getServiceReference() {
- return (reference);
- }
-
- /**
- * Returns the type of event. The event type values are:
- * <ul>
- * <li>{@link #REGISTERED}
- * <li>{@link #MODIFIED}
- * <li>{@link #UNREGISTERING}
- * </ul>
- *
- * @return Type of service lifecycle change.
- */
-
- public int getType() {
- return (type);
- }
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceEvent.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.EventObject;
+
+/**
+ * An event from the Framework describing a service lifecycle change.
+ * <p>
+ * <code>ServiceEvent</code> objects are delivered to a
+ * <code>ServiceListener</code> objects when a change occurs in this service's
+ * lifecycle. A type code is used to identify the event type for future
+ * extendability.
+ *
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ *
+ * @version $Revision: 1.13 $
+ * @see ServiceListener
+ */
+
+public class ServiceEvent extends EventObject {
+ static final long serialVersionUID = 8792901483909409299L;
+ /**
+ * Reference to the service that had a change occur in its lifecycle.
+ */
+ private ServiceReference reference;
+
+ /**
+ * Type of service lifecycle change.
+ */
+ private int type;
+
+ /**
+ * This service has been registered.
+ * <p>
+ * This event is synchronously delivered <strong>after</strong> the service
+ * has been registered with the Framework.
+ *
+ * <p>
+ * The value of <code>REGISTERED</code> is 0x00000001.
+ *
+ * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
+ */
+ public final static int REGISTERED = 0x00000001;
+
+ /**
+ * The properties of a registered service have been modified.
+ * <p>
+ * This event is synchronously delivered <strong>after</strong> the service
+ * properties have been modified.
+ *
+ * <p>
+ * The value of <code>MODIFIED</code> is 0x00000002.
+ *
+ * @see ServiceRegistration#setProperties
+ */
+ public final static int MODIFIED = 0x00000002;
+
+ /**
+ * This service is in the process of being unregistered.
+ * <p>
+ * This event is synchronously delivered <strong>before</strong> the
+ * service has completed unregistering.
+ *
+ * <p>
+ * If a bundle is using a service that is <code>UNREGISTERING</code>, the
+ * bundle should release its use of the service when it receives this event.
+ * If the bundle does not release its use of the service when it receives
+ * this event, the Framework will automatically release the bundle's use of
+ * the service while completing the service unregistration operation.
+ *
+ * <p>
+ * The value of UNREGISTERING is 0x00000004.
+ *
+ * @see ServiceRegistration#unregister
+ * @see BundleContext#ungetService
+ */
+ public final static int UNREGISTERING = 0x00000004;
+
+ /**
+ * Creates a new service event object.
+ *
+ * @param type The event type.
+ * @param reference A <code>ServiceReference</code> object to the service
+ * that had a lifecycle change.
+ */
+ public ServiceEvent(int type, ServiceReference reference) {
+ super(reference);
+ this.reference = reference;
+ this.type = type;
+ }
+
+ /**
+ * Returns a reference to the service that had a change occur in its
+ * lifecycle.
+ * <p>
+ * This reference is the source of the event.
+ *
+ * @return Reference to the service that had a lifecycle change.
+ */
+ public ServiceReference getServiceReference() {
+ return reference;
+ }
+
+ /**
+ * Returns the type of event. The event type values are:
+ * <ul>
+ * <li>{@link #REGISTERED}
+ * <li>{@link #MODIFIED}
+ * <li>{@link #UNREGISTERING}
+ * </ul>
+ *
+ * @return Type of service lifecycle change.
+ */
+
+ public int getType() {
+ return type;
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/ServiceFactory.java b/org.osgi/src/main/java/org/osgi/framework/ServiceFactory.java
index 04041c3..e9adb9e 100644
--- a/org.osgi/src/main/java/org/osgi/framework/ServiceFactory.java
+++ b/org.osgi/src/main/java/org/osgi/framework/ServiceFactory.java
@@ -1,89 +1,99 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceFactory.java,v 1.6 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * Allows services to provide customized service objects in the OSGi
- * environment.
- *
- * <p>
- * When registering a service, a <code>ServiceFactory</code> object can be used
- * instead of a service object, so that the bundle developer can gain control of
- * the specific service object granted to a bundle that is using the service.
- *
- * <p>
- * When this happens, the <code>BundleContext.getService(ServiceReference)</code>
- * method calls the <code>ServiceFactory.getService</code> method to create a
- * service object specifically for the requesting bundle. The service object
- * returned by the <code>ServiceFactory</code> object is cached by the Framework
- * until the bundle releases its use of the service.
- *
- * <p>
- * When the bundle's use count for the service equals zero (including the bundle
- * stopping or the service being unregistered), the
- * <code>ServiceFactory.ungetService</code> method is called.
- *
- * <p>
- * <code>ServiceFactory</code> objects are only used by the Framework and are not
- * made available to other bundles in the OSGi environment.
- *
- * @version $Revision: 1.6 $
- * @see BundleContext#getService
- */
-
-public abstract interface ServiceFactory {
- /**
- * Creates a new service object.
- *
- * <p>
- * The Framework invokes this method the first time the specified
- * <code>bundle</code> requests a service object using the
- * <code>BundleContext.getService(ServiceReference)</code> method. The service
- * factory can then return a specific service object for each bundle.
- *
- * <p>
- * The Framework caches the value returned (unless it is <code>null</code>),
- * and will return the same service object on any future call to
- * <code>BundleContext.getService</code> from the same bundle.
- *
- * <p>
- * The Framework will check if the returned service object is an instance of
- * all the classes named when the service was registered. If not, then
- * <code>null</code> is returned to the bundle.
- *
- * @param bundle The bundle using the service.
- * @param registration The <code>ServiceRegistration</code> object for the
- * service.
- * @return A service object that <strong>must </strong> be an instance of
- * all the classes named when the service was registered.
- * @see BundleContext#getService
- */
- public abstract Object getService(Bundle bundle,
- ServiceRegistration registration);
-
- /**
- * Releases a service object.
- *
- * <p>
- * The Framework invokes this method when a service has been released by a
- * bundle. The service object may then be destroyed.
- *
- * @param bundle The bundle releasing the service.
- * @param registration The <code>ServiceRegistration</code> object for the
- * service.
- * @param service The service object returned by a previous call to the
- * <code>ServiceFactory.getService</code> method.
- * @see BundleContext#ungetService
- */
- public abstract void ungetService(Bundle bundle,
- ServiceRegistration registration, Object service);
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceFactory.java,v 1.8 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * Allows services to provide customized service objects in the OSGi
+ * environment.
+ *
+ * <p>
+ * When registering a service, a <code>ServiceFactory</code> object can be
+ * used instead of a service object, so that the bundle developer can gain
+ * control of the specific service object granted to a bundle that is using the
+ * service.
+ *
+ * <p>
+ * When this happens, the
+ * <code>BundleContext.getService(ServiceReference)</code> method calls the
+ * <code>ServiceFactory.getService</code> method to create a service object
+ * specifically for the requesting bundle. The service object returned by the
+ * <code>ServiceFactory</code> object is cached by the Framework until the
+ * bundle releases its use of the service.
+ *
+ * <p>
+ * When the bundle's use count for the service equals zero (including the bundle
+ * stopping or the service being unregistered), the
+ * <code>ServiceFactory.ungetService</code> method is called.
+ *
+ * <p>
+ * <code>ServiceFactory</code> objects are only used by the Framework and are
+ * not made available to other bundles in the OSGi environment.
+ *
+ * @version $Revision: 1.8 $
+ * @see BundleContext#getService
+ */
+
+public interface ServiceFactory {
+ /**
+ * Creates a new service object.
+ *
+ * <p>
+ * The Framework invokes this method the first time the specified
+ * <code>bundle</code> requests a service object using the
+ * <code>BundleContext.getService(ServiceReference)</code> method. The
+ * service factory can then return a specific service object for each
+ * bundle.
+ *
+ * <p>
+ * The Framework caches the value returned (unless it is <code>null</code>),
+ * and will return the same service object on any future call to
+ * <code>BundleContext.getService</code> from the same bundle.
+ *
+ * <p>
+ * The Framework will check if the returned service object is an instance of
+ * all the classes named when the service was registered. If not, then
+ * <code>null</code> is returned to the bundle.
+ *
+ * @param bundle The bundle using the service.
+ * @param registration The <code>ServiceRegistration</code> object for the
+ * service.
+ * @return A service object that <strong>must </strong> be an instance of
+ * all the classes named when the service was registered.
+ * @see BundleContext#getService
+ */
+ public Object getService(Bundle bundle,
+ ServiceRegistration registration);
+
+ /**
+ * Releases a service object.
+ *
+ * <p>
+ * The Framework invokes this method when a service has been released by a
+ * bundle. The service object may then be destroyed.
+ *
+ * @param bundle The bundle releasing the service.
+ * @param registration The <code>ServiceRegistration</code> object for the
+ * service.
+ * @param service The service object returned by a previous call to the
+ * <code>ServiceFactory.getService</code> method.
+ * @see BundleContext#ungetService
+ */
+ public void ungetService(Bundle bundle,
+ ServiceRegistration registration, Object service);
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/ServiceListener.java b/org.osgi/src/main/java/org/osgi/framework/ServiceListener.java
index 699c888..1553f06 100644
--- a/org.osgi/src/main/java/org/osgi/framework/ServiceListener.java
+++ b/org.osgi/src/main/java/org/osgi/framework/ServiceListener.java
@@ -1,51 +1,63 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceListener.java,v 1.8 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.EventListener;
-
-/**
- * A <code>ServiceEvent</code> listener.
- *
- * <p><code>ServiceListener</code> is a listener interface that may be implemented by a bundle
- * developer.
- * <p>A <code>ServiceListener</code> object is registered with the Framework using the
- * <code>BundleContext.addServiceListener</code> method.
- * <code>ServiceListener</code> objects are called with a <code>ServiceEvent</code> object when
- * a service is registered, modified, or is in the process of unregistering.
- *
- * <p><code>ServiceEvent</code> object delivery to <code>ServiceListener</code> objects is filtered by the
- * filter specified when the listener was registered. If the Java Runtime Environment
- * supports permissions, then additional filtering is done.
- * <code>ServiceEvent</code> objects are only delivered to the listener if the bundle which defines
- * the listener object's class has the appropriate <code>ServicePermission</code> to get the service
- * using at least one of the named classes the service was registered under.
- *
- * <p><code>ServiceEvent</code> object delivery to <code>ServiceListener</code> objects is
- * further filtered according to package sources as defined in
- * {@link ServiceReference#isAssignableTo(Bundle, String)}.
- *
- * @version $Revision: 1.8 $
- * @see ServiceEvent
- * @see ServicePermission
- */
-
-public abstract interface ServiceListener extends EventListener
-{
- /**
- * Receives notification that a service has had a lifecycle change.
- *
- * @param event The <code>ServiceEvent</code> object.
- */
- public abstract void serviceChanged(ServiceEvent event);
-}
-
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceListener.java,v 1.11 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.EventListener;
+
+/**
+ * A <code>ServiceEvent</code> listener. When a <code>ServiceEvent</code> is
+ * fired, it is synchronously delivered to a <code>BundleListener</code>.
+ *
+ * <p>
+ * <code>ServiceListener</code> is a listener interface that may be
+ * implemented by a bundle developer.
+ * <p>
+ * A <code>ServiceListener</code> object is registered with the Framework
+ * using the <code>BundleContext.addServiceListener</code> method.
+ * <code>ServiceListener</code> objects are called with a
+ * <code>ServiceEvent</code> object when a service is registered, modified, or
+ * is in the process of unregistering.
+ *
+ * <p>
+ * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
+ * objects is filtered by the filter specified when the listener was registered.
+ * If the Java Runtime Environment supports permissions, then additional
+ * filtering is done. <code>ServiceEvent</code> objects are only delivered to
+ * the listener if the bundle which defines the listener object's class has the
+ * appropriate <code>ServicePermission</code> to get the service using at
+ * least one of the named classes the service was registered under.
+ *
+ * <p>
+ * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
+ * objects is further filtered according to package sources as defined in
+ * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+ *
+ * @version $Revision: 1.11 $
+ * @see ServiceEvent
+ * @see ServicePermission
+ */
+
+public interface ServiceListener extends EventListener {
+ /**
+ * Receives notification that a service has had a lifecycle change.
+ *
+ * @param event The <code>ServiceEvent</code> object.
+ */
+ public void serviceChanged(ServiceEvent event);
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/ServicePermission.java b/org.osgi/src/main/java/org/osgi/framework/ServicePermission.java
index ab78a2e..5cd62c4 100644
--- a/org.osgi/src/main/java/org/osgi/framework/ServicePermission.java
+++ b/org.osgi/src/main/java/org/osgi/framework/ServicePermission.java
@@ -1,503 +1,508 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServicePermission.java,v 1.10 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.io.IOException;
-import java.security.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-/**
- * Indicates a bundle's authority to register or get a service.
- * <ul>
- * <li>The <code>ServicePermission.REGISTER</code> action allows a bundle to
- * register a service on the specified names.
- * <li>The <code>ServicePermission.GET</code> action allows a bundle to detect a
- * service and get it.
- * </ul>
- * Permission to get a service is required in order to detect events regarding
- * the service. Untrusted bundles should not be able to detect the presence of
- * certain services unless they have the appropriate <code>ServicePermission</code>
- * to get the specific service.
- *
- * @version $Revision: 1.10 $
- */
-
-final public class ServicePermission extends BasicPermission {
- static final long serialVersionUID = -7662148639076511574L;
- /**
- * The action string <code>get</code> (Value is "get").
- */
- public final static String GET = "get";
- /**
- * The action string <code>register</code> (Value is "register").
- */
- public final static String REGISTER = "register";
-
- private final static int ACTION_GET = 0x00000001;
- private final static int ACTION_REGISTER = 0x00000002;
- private final static int ACTION_ALL = ACTION_GET
- | ACTION_REGISTER;
- private final static int ACTION_NONE = 0;
-// NOT USED!!
-// private final static int ACTION_ERROR = 0x80000000;
-
- /**
- * The actions mask.
- */
- private transient int action_mask = ACTION_NONE;
-
- /**
- * The actions in canonical form.
- *
- * @serial
- */
- private String actions = null;
-
- /**
- * Create a new ServicePermission.
- *
- * <p>
- * The name of the service is specified as a fully qualified class name.
- *
- * <pre>
- *
- * ClassName ::= <class name> | <class name ending in ".*">
- *
- * </pre>
- *
- * Examples:
- *
- * <pre>
- * org.osgi.service.http.HttpService
- * org.osgi.service.http.*
- * org.osgi.service.snmp.*
- * </pre>
- *
- * <p>
- * There are two possible actions: <code>get</code> and <code>register</code>.
- * The <code>get</code> permission allows the owner of this permission to
- * obtain a service with this name. The <code>register</code> permission
- * allows the bundle to register a service under that name.
- *
- * @param name class name
- * @param actions <code>get</code>,<code>register</code> (canonical order)
- */
-
- public ServicePermission(String name, String actions) {
- this(name, getMask(actions));
- }
-
- /**
- * Package private constructor used by ServicePermissionCollection.
- *
- * @param name class name
- * @param mask action mask
- */
- ServicePermission(String name, int mask) {
- super(name);
-
- init(mask);
- }
-
- /**
- * Called by constructors and when deserialized.
- *
- * @param mask action mask
- */
- private void init(int mask) {
- if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
- throw new IllegalArgumentException("invalid action string");
- }
-
- action_mask = mask;
- }
-
- /**
- * Parse action string into 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 >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
- && (a[i - 1] == 'e' || a[i - 1] == 'E')
- && (a[i] == 't' || a[i] == 'T')) {
- matchlen = 3;
- mask |= ACTION_GET;
-
- }
- else
- if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
- && (a[i - 6] == 'e' || a[i - 6] == 'E')
- && (a[i - 5] == 'g' || a[i - 5] == 'G')
- && (a[i - 4] == 'i' || a[i - 4] == 'I')
- && (a[i - 3] == 's' || a[i - 3] == 'S')
- && (a[i - 2] == 't' || a[i - 2] == 'T')
- && (a[i - 1] == 'e' || a[i - 1] == 'E')
- && (a[i] == 'r' || a[i] == 'R')) {
- matchlen = 8;
- mask |= ACTION_REGISTER;
-
- }
- else {
- // parse error
- throw new IllegalArgumentException("invalid permission: "
- + actions);
- }
-
- // make sure we didn't just match the tail of a word
- // like "ackbarfregister". 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;
- }
-
- /**
- * Determines if a <code>ServicePermission</code> object "implies" the
- * specified permission.
- *
- * @param p The target permission to check.
- * @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 ServicePermission) {
- ServicePermission target = (ServicePermission) p;
-
- return (((action_mask & target.action_mask) == target.action_mask) && super
- .implies(p));
- }
-
- return (false);
- }
-
- /**
- * Returns the canonical string representation of the actions. Always
- * returns present actions in the following order: <code>get</code>,
- * <code>register</code>.
- *
- * @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_GET) == ACTION_GET) {
- sb.append(GET);
- comma = true;
- }
-
- if ((action_mask & ACTION_REGISTER) == ACTION_REGISTER) {
- if (comma)
- sb.append(',');
- sb.append(REGISTER);
- }
-
- actions = sb.toString();
- }
-
- return (actions);
- }
-
- /**
- * Returns a new <code>PermissionCollection</code> object for storing
- * <code>ServicePermission<code> objects.
- *
- * @return A new <code>PermissionCollection</code> object suitable for storing
- * <code>ServicePermission</code> objects.
- */
- public PermissionCollection newPermissionCollection() {
- return (new ServicePermissionCollection());
- }
-
- /**
- * Determines the equalty of two ServicePermission objects.
- *
- * Checks that specified object has the same class name and action as this
- * <code>ServicePermission</code>.
- *
- * @param obj The object to test for equality.
- * @return true if obj is a <code>ServicePermission</code>, and has the same
- * class name and actions as this <code>ServicePermission</code>
- * object; <code>false</code> otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return (true);
- }
-
- if (!(obj instanceof ServicePermission)) {
- return (false);
- }
-
- ServicePermission p = (ServicePermission) obj;
-
- return ((action_mask == p.action_mask) && getName().equals(p.getName()));
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return Hash code value for this object.
- */
-
- public int hashCode() {
- return (getName().hashCode() ^ getActions().hashCode());
- }
-
- /**
- * Returns the current action mask. Used by the ServicePermissionCollection
- * object.
- *
- * @return The actions mask.
- */
- int getMask() {
- return (action_mask);
- }
-
- /**
- * WriteObject is called to save the state of this permission to a stream.
- * The actions are serialized, and the superclass takes care of the name.
- */
-
- private synchronized void writeObject(java.io.ObjectOutputStream s)
- throws IOException {
- // 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();
- }
-
- /**
- * readObject is called to restore the state of this permission from a
- * stream.
- */
- private synchronized void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- // Read in the action, then initialize the rest
- s.defaultReadObject();
- init(getMask(actions));
- }
-}
-
-/**
- * Stores a set of ServicePermission permissions.
- *
- * @see java.security.Permission
- * @see java.security.Permissions
- * @see java.security.PermissionCollection
- */
-
-final class ServicePermissionCollection extends PermissionCollection {
- static final long serialVersionUID = 662615640374640621L;
- /**
- * Table of permissions.
- *
- * @serial
- */
- private Hashtable permissions;
-
- /**
- * Boolean saying if "*" is in the collection.
- *
- * @serial
- */
- private boolean all_allowed;
-
- /**
- * Creates an empty ServicePermissions object.
- *
- */
-
- public ServicePermissionCollection() {
- permissions = new Hashtable();
- all_allowed = false;
- }
-
- /**
- * Adds a permission to the <code>ServicePermission</code> objects using the
- * key for the hash as the name.
- *
- * @param permission The Permission object to add.
- *
- * @exception IllegalArgumentException If the permission is not a
- * ServicePermission object.
- *
- * @exception SecurityException If this <code>ServicePermissionCollection</code>
- * object has been marked read-only.
- */
-
- public void add(Permission permission) {
- if (!(permission instanceof ServicePermission))
- throw new IllegalArgumentException("invalid permission: "
- + permission);
- if (isReadOnly())
- throw new SecurityException("attempt to add a Permission to a "
- + "readonly PermissionCollection");
-
- ServicePermission sp = (ServicePermission) permission;
- String name = sp.getName();
-
- ServicePermission existing = (ServicePermission) permissions.get(name);
-
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = sp.getMask();
- if (oldMask != newMask) {
- permissions.put(name, new ServicePermission(name, oldMask
- | newMask));
- }
- }
- else {
- permissions.put(name, permission);
- }
-
- if (!all_allowed) {
- if (name.equals("*"))
- all_allowed = true;
- }
- }
-
- /**
- * Determines if a set of permissions implies the permissions expressed in
- * <code>permission</code>.
- *
- * @param permission The Permission object to compare.
- *
- * @return <code>true</code> if <code>permission</code> is a proper subset of a
- * permission in the set; <code>false</code> otherwise.
- */
-
- public boolean implies(Permission permission) {
- if (!(permission instanceof ServicePermission))
- return (false);
-
- ServicePermission sp = (ServicePermission) permission;
- ServicePermission x;
-
- int desired = sp.getMask();
- int effective = 0;
-
- // short circuit if the "*" Permission was added
- if (all_allowed) {
- x = (ServicePermission) 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 = sp.getName();
-
- x = (ServicePermission) 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, offset;
-
- offset = name.length() - 1;
-
- while ((last = name.lastIndexOf(".", offset)) != -1) {
-
- name = name.substring(0, last + 1) + "*";
- x = (ServicePermission) 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>ServicePermission</code> objects in
- * the container.
- *
- * @return Enumeration of all the ServicePermission objects.
- */
-
- public Enumeration elements() {
- return (permissions.elements());
- }
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServicePermission.java,v 1.13 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.io.IOException;
+import java.security.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * Indicates a bundle's authority to register or get a service.
+ * <ul>
+ * <li>The <code>ServicePermission.REGISTER</code> action allows a bundle to
+ * register a service on the specified names.
+ * <li>The <code>ServicePermission.GET</code> action allows a bundle to
+ * detect a service and get it.
+ * </ul>
+ * Permission to get a service is required in order to detect events regarding
+ * the service. Untrusted bundles should not be able to detect the presence of
+ * certain services unless they have the appropriate
+ * <code>ServicePermission</code> to get the specific service.
+ *
+ * @version $Revision: 1.13 $
+ */
+
+final public class ServicePermission extends BasicPermission {
+ static final long serialVersionUID = -7662148639076511574L;
+ /**
+ * The action string <code>get</code> (Value is "get").
+ */
+ public final static String GET = "get";
+ /**
+ * The action string <code>register</code> (Value is "register").
+ */
+ public final static String REGISTER = "register";
+
+ private final static int ACTION_GET = 0x00000001;
+ private final static int ACTION_REGISTER = 0x00000002;
+ private final static int ACTION_ALL = ACTION_GET
+ | ACTION_REGISTER;
+ private final static int ACTION_NONE = 0;
+ /**
+ * The actions mask.
+ */
+ private transient int action_mask = ACTION_NONE;
+
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private String actions = null;
+
+ /**
+ * Create a new ServicePermission.
+ *
+ * <p>
+ * The name of the service is specified as a fully qualified class name.
+ *
+ * <pre>
+ * ClassName ::= <class name> | <class name ending in ".*">
+ * </pre>
+ *
+ * Examples:
+ *
+ * <pre>
+ * org.osgi.service.http.HttpService
+ * org.osgi.service.http.*
+ * org.osgi.service.snmp.*
+ * </pre>
+ *
+ * <p>
+ * There are two possible actions: <code>get</code> and
+ * <code>register</code>. The <code>get</code> permission allows the
+ * owner of this permission to obtain a service with this name. The
+ * <code>register</code> permission allows the bundle to register a
+ * service under that name.
+ *
+ * @param name class name
+ * @param actions <code>get</code>,<code>register</code> (canonical
+ * order)
+ */
+
+ public ServicePermission(String name, String actions) {
+ this(name, getMask(actions));
+ }
+
+ /**
+ * Package private constructor used by ServicePermissionCollection.
+ *
+ * @param name class name
+ * @param mask action mask
+ */
+ ServicePermission(String name, int mask) {
+ super(name);
+
+ init(mask);
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param mask action mask
+ */
+ private void init(int mask) {
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+
+ action_mask = mask;
+ }
+
+ /**
+ * Parse action string into 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 >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
+ && (a[i - 1] == 'e' || a[i - 1] == 'E')
+ && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 3;
+ mask |= ACTION_GET;
+
+ }
+ else
+ if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
+ && (a[i - 6] == 'e' || a[i - 6] == 'E')
+ && (a[i - 5] == 'g' || a[i - 5] == 'G')
+ && (a[i - 4] == 'i' || a[i - 4] == 'I')
+ && (a[i - 3] == 's' || a[i - 3] == 'S')
+ && (a[i - 2] == 't' || a[i - 2] == 'T')
+ && (a[i - 1] == 'e' || a[i - 1] == 'E')
+ && (a[i] == 'r' || a[i] == 'R')) {
+ matchlen = 8;
+ mask |= ACTION_REGISTER;
+
+ }
+ else {
+ // parse error
+ throw new IllegalArgumentException("invalid permission: "
+ + actions);
+ }
+
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfregister". 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;
+ }
+
+ /**
+ * Determines if a <code>ServicePermission</code> object "implies" the
+ * specified permission.
+ *
+ * @param p The target permission to check.
+ * @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 ServicePermission) {
+ ServicePermission target = (ServicePermission) p;
+
+ return (((action_mask & target.action_mask) == target.action_mask) && super
+ .implies(p));
+ }
+
+ return (false);
+ }
+
+ /**
+ * Returns the canonical string representation of the actions. Always
+ * returns present actions in the following order: <code>get</code>,
+ * <code>register</code>.
+ *
+ * @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_GET) == ACTION_GET) {
+ sb.append(GET);
+ comma = true;
+ }
+
+ if ((action_mask & ACTION_REGISTER) == ACTION_REGISTER) {
+ if (comma)
+ sb.append(',');
+ sb.append(REGISTER);
+ }
+
+ actions = sb.toString();
+ }
+
+ return (actions);
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object for storing
+ * <code>ServicePermission<code> objects.
+ *
+ * @return A new <code>PermissionCollection</code> object suitable for storing
+ * <code>ServicePermission</code> objects.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return (new ServicePermissionCollection());
+ }
+
+ /**
+ * Determines the equalty of two ServicePermission objects.
+ *
+ * Checks that specified object has the same class name and action as this
+ * <code>ServicePermission</code>.
+ *
+ * @param obj The object to test for equality.
+ * @return true if obj is a <code>ServicePermission</code>, and has the
+ * same class name and actions as this
+ * <code>ServicePermission</code> object; <code>false</code>
+ * otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return (true);
+ }
+
+ if (!(obj instanceof ServicePermission)) {
+ return (false);
+ }
+
+ ServicePermission p = (ServicePermission) obj;
+
+ return ((action_mask == p.action_mask) && getName().equals(p.getName()));
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return Hash code value for this object.
+ */
+
+ public int hashCode() {
+ return (getName().hashCode() ^ getActions().hashCode());
+ }
+
+ /**
+ * Returns the current action mask. Used by the ServicePermissionCollection
+ * object.
+ *
+ * @return The actions mask.
+ */
+ int getMask() {
+ return (action_mask);
+ }
+
+ /**
+ * WriteObject is called to save the state of this permission to a stream.
+ * The actions are serialized, and the superclass takes care of the name.
+ */
+
+ private synchronized void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ // 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();
+ }
+
+ /**
+ * readObject is called to restore the state of this permission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ init(getMask(actions));
+ }
+}
+
+/**
+ * Stores a set of ServicePermission permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class ServicePermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = 662615640374640621L;
+ /**
+ * Table of permissions.
+ *
+ * @serial
+ */
+ private Hashtable permissions;
+
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ */
+ private boolean all_allowed;
+
+ /**
+ * Creates an empty ServicePermissions object.
+ */
+
+ public ServicePermissionCollection() {
+ permissions = new Hashtable();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to the <code>ServicePermission</code> objects using
+ * the key for the hash as the name.
+ *
+ * @param permission The Permission object to add.
+ *
+ * @throws IllegalArgumentException If the permission is not a
+ * ServicePermission object.
+ * @throws SecurityException If this
+ * <code>ServicePermissionCollection</code> object has been marked
+ * read-only.
+ */
+
+ public void add(Permission permission) {
+ if (!(permission instanceof ServicePermission))
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ if (isReadOnly())
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+
+ ServicePermission sp = (ServicePermission) permission;
+ String name = sp.getName();
+
+ ServicePermission existing = (ServicePermission) permissions.get(name);
+
+ if (existing != null) {
+ int oldMask = existing.getMask();
+ int newMask = sp.getMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new ServicePermission(name, oldMask
+ | newMask));
+ }
+ }
+ else {
+ permissions.put(name, permission);
+ }
+
+ if (!all_allowed) {
+ if (name.equals("*"))
+ all_allowed = true;
+ }
+ }
+
+ /**
+ * Determines if a set of permissions implies the permissions expressed in
+ * <code>permission</code>.
+ *
+ * @param permission The Permission object to compare.
+ *
+ * @return <code>true</code> if <code>permission</code> is a proper
+ * subset of a permission in the set; <code>false</code>
+ * otherwise.
+ */
+
+ public boolean implies(Permission permission) {
+ if (!(permission instanceof ServicePermission))
+ return (false);
+
+ ServicePermission sp = (ServicePermission) permission;
+ ServicePermission x;
+
+ int desired = sp.getMask();
+ int effective = 0;
+
+ // short circuit if the "*" Permission was added
+ if (all_allowed) {
+ x = (ServicePermission) 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 = sp.getName();
+
+ x = (ServicePermission) 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, offset;
+
+ offset = name.length() - 1;
+
+ while ((last = name.lastIndexOf(".", offset)) != -1) {
+
+ name = name.substring(0, last + 1) + "*";
+ x = (ServicePermission) 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>ServicePermission</code>
+ * objects in the container.
+ *
+ * @return Enumeration of all the ServicePermission objects.
+ */
+
+ public Enumeration elements() {
+ return (permissions.elements());
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/ServiceReference.java b/org.osgi/src/main/java/org/osgi/framework/ServiceReference.java
index 87b16e5..8112ccf 100644
--- a/org.osgi/src/main/java/org/osgi/framework/ServiceReference.java
+++ b/org.osgi/src/main/java/org/osgi/framework/ServiceReference.java
@@ -1,146 +1,153 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceReference.java,v 1.11 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.Dictionary;
-
-/**
- * A reference to a service.
- *
- * <p>
- * The Framework returns <code>ServiceReference</code> objects from the
- * <code>BundleContext.getServiceReference</code> and
- * <code>BundleContext.getServiceReferences</code> methods.
- * <p>
- * A <code>ServiceReference</code> object may be shared between bundles and can be
- * used to examine the properties of the service and to get the service object.
- * <p>
- * Every service registered in the Framework has a unique
- * <code>ServiceRegistration</code> object and may have multiple, distinct
- * <code>ServiceReference</code> objects referring to it.
- * <code>ServiceReference</code> objects associated with a
- * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
- * and are considered equal (more specifically, their <code>equals()</code>
- * method will return <code>true</code> when compared).
- * <p>
- * If the same service object is registered multiple times,
- * <code>ServiceReference</code> objects associated with different
- * <code>ServiceRegistration</code> objects are not equal.
- *
- * @version $Revision: 1.11 $
- * @see BundleContext#getServiceReference
- * @see BundleContext#getServiceReferences
- * @see BundleContext#getService
- */
-
-public abstract interface ServiceReference {
- /**
- * Returns the property value to which the specified property key is mapped
- * in the properties <code>Dictionary</code> object of the service
- * referenced by this <code>ServiceReference</code> object.
- *
- * <p>
- * Property keys are case-insensitive.
- *
- * <p>
- * This method must continue to return property values after the service has
- * been unregistered. This is so references to unregistered services (for
- * example, <code>ServiceReference</code> objects stored in the log) can
- * still be interrogated.
- *
- * @param key The property key.
- * @return The property value to which the key is mapped; <code>null</code>
- * if there is no property named after the key.
- */
- public abstract Object getProperty(String key);
-
- /**
- * Returns an array of the keys in the properties <code>Dictionary</code>
- * object of the service referenced by this <code>ServiceReference</code>
- * object.
- *
- * <p>
- * This method will continue to return the keys after the service has been
- * unregistered. This is so references to unregistered services (for
- * example, <code>ServiceReference</code> objects stored in the log) can
- * still be interrogated.
- *
- * <p>
- * This method is <i>case-preserving </i>; this means that every key in the
- * returned array must have the same case as the corresponding key in the
- * properties <code>Dictionary</code> that was passed to the
- * {@link BundleContext#registerService(String[],Object,Dictionary)}or
- * {@link ServiceRegistration#setProperties}methods.
- *
- * @return An array of property keys.
- */
- public abstract String[] getPropertyKeys();
-
- /**
- * Returns the bundle that registered the service referenced by this
- * <code>ServiceReference</code> object.
- *
- * <p>
- * This method must return <code>null</code> when the service has
- * been unregistered. This can be used to determine if the service has been
- * unregistered.
- *
- * @return The bundle that registered the service referenced by this
- * <code>ServiceReference</code> object; <code>null</code> if
- * that service has already been unregistered.
- * @see BundleContext#registerService(String[],Object,Dictionary)
- */
- public abstract Bundle getBundle();
-
- /**
- * Returns the bundles that are using the service referenced by this
- * <code>ServiceReference</code> object. Specifically, this method returns
- * the bundles whose usage count for that service is greater than zero.
- *
- * @return An array of bundles whose usage count for the service referenced
- * by this <code>ServiceReference</code> object is greater than
- * zero; <code>null</code> if no bundles are currently using that
- * service.
- *
- * @since 1.1
- */
- public abstract Bundle[] getUsingBundles();
-
- /**
- * Tests if the bundle that registered the service referenced by this
- * <code>ServiceReference</code> and the specified bundle use the same source
- * for the package of the specified class name.
- * <p>
- * This method performs the following checks:
- * <ol>
- * <li>Get the package name from the specified class name.</li>
- * <li>For the bundle that registered the service referenced by this
- * <code>ServiceReference</code> (registrant bundle); find the source for the
- * package. If no source is found then return <code>true</code> if the
- * registrant bundle is equal to the specified bundle; otherwise return
- * <code>false</code>.</li>
- * <li>If the package source of the registrant bundle is equal to the
- * package source of the specified bundle then return <code>true</code>;
- * otherwise return <code>false</code>.</li>
- * </ol>
- *
- * @param bundle The <code>Bundle</code> object to check.
- * @param className The class name to check.
- * @return <code>true</code> if the bundle which registered the service
- * referenced by this <code>ServiceReference</code> and the specified
- * bundle use the same source for the package of the specified class
- * name. Otherwise <code>false</code> is returned.
- *
- * @since 1.3
- */
- public abstract boolean isAssignableTo(Bundle bundle, String className);
-
-}
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceReference.java,v 1.14 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+/**
+ * A reference to a service.
+ *
+ * <p>
+ * The Framework returns <code>ServiceReference</code> objects from the
+ * <code>BundleContext.getServiceReference</code> and
+ * <code>BundleContext.getServiceReferences</code> methods.
+ * <p>
+ * A <code>ServiceReference</code> object may be shared between bundles and
+ * can be used to examine the properties of the service and to get the service
+ * object.
+ * <p>
+ * Every service registered in the Framework has a unique
+ * <code>ServiceRegistration</code> object and may have multiple, distinct
+ * <code>ServiceReference</code> objects referring to it.
+ * <code>ServiceReference</code> objects associated with a
+ * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
+ * and are considered equal (more specifically, their <code>equals()</code>
+ * method will return <code>true</code> when compared).
+ * <p>
+ * If the same service object is registered multiple times,
+ * <code>ServiceReference</code> objects associated with different
+ * <code>ServiceRegistration</code> objects are not equal.
+ *
+ * @version $Revision: 1.14 $
+ * @see BundleContext#getServiceReference
+ * @see BundleContext#getServiceReferences
+ * @see BundleContext#getService
+ */
+
+public interface ServiceReference {
+ /**
+ * Returns the property value to which the specified property key is mapped
+ * in the properties <code>Dictionary</code> object of the service
+ * referenced by this <code>ServiceReference</code> object.
+ *
+ * <p>
+ * Property keys are case-insensitive.
+ *
+ * <p>
+ * This method must continue to return property values after the service has
+ * been unregistered. This is so references to unregistered services (for
+ * example, <code>ServiceReference</code> objects stored in the log) can
+ * still be interrogated.
+ *
+ * @param key The property key.
+ * @return The property value to which the key is mapped; <code>null</code>
+ * if there is no property named after the key.
+ */
+ public Object getProperty(String key);
+
+ /**
+ * Returns an array of the keys in the properties <code>Dictionary</code>
+ * object of the service referenced by this <code>ServiceReference</code>
+ * object.
+ *
+ * <p>
+ * This method will continue to return the keys after the service has been
+ * unregistered. This is so references to unregistered services (for
+ * example, <code>ServiceReference</code> objects stored in the log) can
+ * still be interrogated.
+ *
+ * <p>
+ * This method is <i>case-preserving </i>; this means that every key in the
+ * returned array must have the same case as the corresponding key in the
+ * properties <code>Dictionary</code> that was passed to the
+ * {@link BundleContext#registerService(String[],Object,java.util.Dictionary)} or
+ * {@link ServiceRegistration#setProperties} methods.
+ *
+ * @return An array of property keys.
+ */
+ public String[] getPropertyKeys();
+
+ /**
+ * Returns the bundle that registered the service referenced by this
+ * <code>ServiceReference</code> object.
+ *
+ * <p>
+ * This method must return <code>null</code> when the service has been
+ * unregistered. This can be used to determine if the service has been
+ * unregistered.
+ *
+ * @return The bundle that registered the service referenced by this
+ * <code>ServiceReference</code> object; <code>null</code> if
+ * that service has already been unregistered.
+ * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
+ */
+ public Bundle getBundle();
+
+ /**
+ * Returns the bundles that are using the service referenced by this
+ * <code>ServiceReference</code> object. Specifically, this method returns
+ * the bundles whose usage count for that service is greater than zero.
+ *
+ * @return An array of bundles whose usage count for the service referenced
+ * by this <code>ServiceReference</code> object is greater than
+ * zero; <code>null</code> if no bundles are currently using that
+ * service.
+ *
+ * @since 1.1
+ */
+ public Bundle[] getUsingBundles();
+
+ /**
+ * Tests if the bundle that registered the service referenced by this
+ * <code>ServiceReference</code> and the specified bundle use the same
+ * source for the package of the specified class name.
+ * <p>
+ * This method performs the following checks:
+ * <ol>
+ * <li>Get the package name from the specified class name.</li>
+ * <li>For the bundle that registered the service referenced by this
+ * <code>ServiceReference</code> (registrant bundle); find the source for
+ * the package. If no source is found then return <code>true</code> if the
+ * registrant bundle is equal to the specified bundle; otherwise return
+ * <code>false</code>.</li>
+ * <li>If the package source of the registrant bundle is equal to the
+ * package source of the specified bundle then return <code>true</code>;
+ * otherwise return <code>false</code>.</li>
+ * </ol>
+ *
+ * @param bundle The <code>Bundle</code> object to check.
+ * @param className The class name to check.
+ * @return <code>true</code> if the bundle which registered the service
+ * referenced by this <code>ServiceReference</code> and the
+ * specified bundle use the same source for the package of the
+ * specified class name. Otherwise <code>false</code> is returned.
+ *
+ * @since 1.3
+ */
+ public boolean isAssignableTo(Bundle bundle, String className);
+
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/ServiceRegistration.java b/org.osgi/src/main/java/org/osgi/framework/ServiceRegistration.java
index 5b4f026..afe7d8a 100644
--- a/org.osgi/src/main/java/org/osgi/framework/ServiceRegistration.java
+++ b/org.osgi/src/main/java/org/osgi/framework/ServiceRegistration.java
@@ -1,105 +1,112 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceRegistration.java,v 1.8 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.Dictionary;
-
-/**
- * A registered service.
- *
- * <p>
- * The Framework returns a <code>ServiceRegistration</code> object when a
- * <code>BundleContext.registerService</code> method invocation is successful.
- * The <code>ServiceRegistration</code> object is for the private use of the
- * registering bundle and should not be shared with other bundles.
- * <p>
- * The <code>ServiceRegistration</code> object may be used to update the
- * properties of the service or to unregister the service.
- *
- * @version $Revision: 1.8 $
- * @see BundleContext#registerService(String[],Object,Dictionary)
- */
-
-public abstract interface ServiceRegistration {
- /**
- * Returns a <code>ServiceReference</code> object for a service being
- * registered.
- * <p>
- * The <code>ServiceReference</code> object may be shared with other bundles.
- *
- * @exception java.lang.IllegalStateException If this
- * <code>ServiceRegistration</code> object has already been
- * unregistered.
- * @return <code>ServiceReference</code> object.
- */
- public abstract ServiceReference getReference();
-
- /**
- * Updates the properties associated with a service.
- *
- * <p>
- * The {@link Constants#OBJECTCLASS} and {@link Constants#SERVICE_ID} keys
- * cannot be modified by this method. These values are set by the Framework
- * when the service is registered in the OSGi environment.
- *
- * <p>
- * The following steps are required to modify service properties:
- * <ol>
- * <li>The service's properties are replaced with the provided properties.
- * <li>A service event of type {@link ServiceEvent#MODIFIED} is
- * synchronously sent.
- * </ol>
- *
- * @param properties The properties for this service. See {@link Constants}
- * for a list of standard service property keys. Changes should not
- * be made to this object after calling this method. To update the
- * service's properties this method should be called again.
- *
- * @exception IllegalStateException If this <code>ServiceRegistration</code>
- * object has already been unregistered.
- *
- * @exception IllegalArgumentException If <code>properties</code> contains
- * case variants of the same key name.
- */
- public abstract void setProperties(Dictionary properties);
-
- /**
- * Unregisters a service. Remove a <code>ServiceRegistration</code> object
- * from the Framework service registry. All <code>ServiceReference</code>
- * objects associated with this <code>ServiceRegistration</code> object can no
- * longer be used to interact with the service.
- *
- * <p>
- * The following steps are required to unregister a service:
- * <ol>
- * <li>The service is removed from the Framework service registry so that
- * it can no longer be used. <code>ServiceReference</code> objects for the
- * service may no longer be used to get a service object for the service.
- * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is
- * synchronously sent so that bundles using this service can release their
- * use of it.
- * <li>For each bundle whose use count for this service is greater than
- * zero: <br>
- * The bundle's use count for this service is set to zero. <br>
- * If the service was registered with a {@link ServiceFactory} object, the
- * <code>ServiceFactory.ungetService</code> method is called to release the
- * service object for the bundle.
- * </ol>
- *
- * @exception java.lang.IllegalStateException If this
- * <code>ServiceRegistration</code> object has already been
- * unregistered.
- * @see BundleContext#ungetService
- * @see ServiceFactory#ungetService
- */
- public abstract void unregister();
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServiceRegistration.java,v 1.11 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.framework;
+
+import java.util.Dictionary;
+
+/**
+ * A registered service.
+ *
+ * <p>
+ * The Framework returns a <code>ServiceRegistration</code> object when a
+ * <code>BundleContext.registerService</code> method invocation is successful.
+ * The <code>ServiceRegistration</code> object is for the private use of the
+ * registering bundle and should not be shared with other bundles.
+ * <p>
+ * The <code>ServiceRegistration</code> object may be used to update the
+ * properties of the service or to unregister the service.
+ *
+ * @version $Revision: 1.11 $
+ * @see BundleContext#registerService(String[],Object,Dictionary)
+ */
+
+public interface ServiceRegistration {
+ /**
+ * Returns a <code>ServiceReference</code> object for a service being
+ * registered.
+ * <p>
+ * The <code>ServiceReference</code> object may be shared with other
+ * bundles.
+ *
+ * @throws java.lang.IllegalStateException If this
+ * <code>ServiceRegistration</code> object has already been
+ * unregistered.
+ * @return <code>ServiceReference</code> object.
+ */
+ public ServiceReference getReference();
+
+ /**
+ * Updates the properties associated with a service.
+ *
+ * <p>
+ * The {@link Constants#OBJECTCLASS} and {@link Constants#SERVICE_ID} keys
+ * cannot be modified by this method. These values are set by the Framework
+ * when the service is registered in the OSGi environment.
+ *
+ * <p>
+ * The following steps are required to modify service properties:
+ * <ol>
+ * <li>The service's properties are replaced with the provided properties.
+ * <li>A service event of type {@link ServiceEvent#MODIFIED} is
+ * fired.
+ * </ol>
+ *
+ * @param properties The properties for this service. See {@link Constants}
+ * for a list of standard service property keys. Changes should not
+ * be made to this object after calling this method. To update the
+ * service's properties this method should be called again.
+ *
+ * @throws IllegalStateException If this <code>ServiceRegistration</code>
+ * object has already been unregistered.
+ * @throws IllegalArgumentException If <code>properties</code> contains
+ * case variants of the same key name.
+ */
+ public void setProperties(Dictionary properties);
+
+ /**
+ * Unregisters a service. Remove a <code>ServiceRegistration</code> object
+ * from the Framework service registry. All <code>ServiceReference</code>
+ * objects associated with this <code>ServiceRegistration</code> object
+ * can no longer be used to interact with the service.
+ *
+ * <p>
+ * The following steps are required to unregister a service:
+ * <ol>
+ * <li>The service is removed from the Framework service registry so that
+ * it can no longer be used. <code>ServiceReference</code> objects for the
+ * service may no longer be used to get a service object for the service.
+ * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is
+ * fired so that bundles using this service can release their
+ * use of it.
+ * <li>For each bundle whose use count for this service is greater than
+ * zero: <br>
+ * The bundle's use count for this service is set to zero. <br>
+ * If the service was registered with a {@link ServiceFactory} object, the
+ * <code>ServiceFactory.ungetService</code> method is called to release
+ * the service object for the bundle.
+ * </ol>
+ *
+ * @throws java.lang.IllegalStateException If this
+ * <code>ServiceRegistration</code> object has already been
+ * unregistered.
+ * @see BundleContext#ungetService
+ * @see ServiceFactory#ungetService
+ */
+ public void unregister();
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/SynchronousBundleListener.java b/org.osgi/src/main/java/org/osgi/framework/SynchronousBundleListener.java
index edbe0b3..37dc56a 100644
--- a/org.osgi/src/main/java/org/osgi/framework/SynchronousBundleListener.java
+++ b/org.osgi/src/main/java/org/osgi/framework/SynchronousBundleListener.java
@@ -1,43 +1,52 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/SynchronousBundleListener.java,v 1.8 2005/05/13 20:32:54 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-/**
- * A synchronous <code>BundleEvent</code> listener.
- *
- * <p>
- * <code>SynchronousBundleListener</code> is a listener interface that may be
- * implemented by a bundle developer.
- * <p>
- * A <code>SynchronousBundleListener</code> object is registered with the
- * Framework using the {@link BundleContext#addBundleListener} method.
- * <code>SynchronousBundleListener</code> objects are called with a
- * <code>BundleEvent</code> object when a bundle has been installed,
- * resolved, started, stopped, updated, unresolved, or uninstalled.
- * <p>
- * Unlike normal <code>BundleListener</code> objects,
- * <code>SynchronousBundleListener</code>s are synchronously called during bundle
- * lifecycle processing. The bundle lifecycle processing will not proceed
- * until all <code>SynchronousBundleListener</code>s have completed.
- * <code>SynchronousBundleListener</code> objects will be called prior to
- * <code>BundleListener</code> objects.
- * <p>
- * <code>AdminPermission</code> is required to add or remove a
- * <code>SynchronousBundleListener</code> object.
- *
- * @version $Revision: 1.8 $
- * @since 1.1
- * @see BundleEvent
- */
-
-public abstract interface SynchronousBundleListener extends BundleListener {
-}
-
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/SynchronousBundleListener.java,v 1.13 2006/03/14 01:21:02 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.framework;
+
+/**
+ * A synchronous <code>BundleEvent</code> listener. When a <code>BundleEvent</code> is
+ * fired, it is synchronously delivered to a <code>BundleListener</code>.
+ *
+ * <p>
+ * <code>SynchronousBundleListener</code> is a listener interface that may be
+ * implemented by a bundle developer.
+ * <p>
+ * A <code>SynchronousBundleListener</code> object is registered with the
+ * Framework using the {@link BundleContext#addBundleListener} method.
+ * <code>SynchronousBundleListener</code> objects are called with a
+ * <code>BundleEvent</code> object when a bundle has been installed, resolved,
+ * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
+ * <p>
+ * Unlike normal <code>BundleListener</code> objects,
+ * <code>SynchronousBundleListener</code>s are synchronously called during
+ * bundle lifecycle processing. The bundle lifecycle processing will not proceed
+ * until all <code>SynchronousBundleListener</code>s have completed.
+ * <code>SynchronousBundleListener</code> objects will be called prior to
+ * <code>BundleListener</code> objects.
+ * <p>
+ * <code>AdminPermission[bundle,LISTENER]</code> is required to add or remove a
+ * <code>SynchronousBundleListener</code> object.
+ *
+ * @version $Revision: 1.13 $
+ * @since 1.1
+ * @see BundleEvent
+ */
+
+public interface SynchronousBundleListener extends BundleListener {
+ // This is a marker interface
+}
diff --git a/org.osgi/src/main/java/org/osgi/framework/Version.java b/org.osgi/src/main/java/org/osgi/framework/Version.java
index 93e3173..c251bdf 100644
--- a/org.osgi/src/main/java/org/osgi/framework/Version.java
+++ b/org.osgi/src/main/java/org/osgi/framework/Version.java
@@ -1,344 +1,353 @@
-/*
- * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Version.java,v 1.13 2005/05/13 20:32:55 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.framework;
-
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-
-/**
- * Version identifier for bundles and packages.
- *
- * <p>
- * Version identifiers have four components.
- * <ol>
- * <li>Major version. A non-negative integer.</li>
- * <li>Minor version. A non-negative integer.</li>
- * <li>Micro version. A non-negative integer.</li>
- * <li>Qualifier. A text string. See <code>Version(String)</code> for the
- * format of the qualifier string.</li>
- * </ol>
- *
- * <p>
- * <code>Version</code> objects are immutable.
- *
- * @version $Revision: 1.13 $
- * @since 1.3
- */
-
-public class Version implements Comparable {
- private final int major;
- private final int minor;
- private final int micro;
- private final String qualifier;
- private static final String SEPARATOR = "."; //$NON-NLS-1$
-
- /**
- * The empty version "0.0.0". Equivalent to calling
- * <code>new Version(0,0,0)</code>.
- */
- public static final Version emptyVersion = new Version(0, 0, 0);
-
- /**
- * Creates a version identifier from the specified numerical components.
- *
- * <p>
- * The qualifier is set to the empty string.
- *
- * @param major Major component of the version identifier.
- * @param minor Minor component of the version identifier.
- * @param micro Micro component of the version identifier.
- * @throws IllegalArgumentException If the numerical components are
- * negative.
- */
- public Version(int major, int minor, int micro) {
- this(major, minor, micro, null);
- }
-
- /**
- * Creates a version identifier from the specifed components.
- *
- * @param major Major component of the version identifier.
- * @param minor Minor component of the version identifier.
- * @param micro Micro component of the version identifier.
- * @param qualifier Qualifier component of the version identifier. If
- * <code>null</code> is specified, then the qualifier will be set
- * to the empty string.
- * @throws IllegalArgumentException If the numerical components are negative
- * or the qualifier string is invalid.
- */
- public Version(int major, int minor, int micro, String qualifier) {
- if (qualifier == null) {
- qualifier = ""; //$NON-NLS-1$
- }
-
- this.major = major;
- this.minor = minor;
- this.micro = micro;
- this.qualifier = qualifier;
- validate();
- }
-
- /**
- * Created a version identifier from the specified string.
- *
- * <p>
- * Here is the grammar for version strings.
- *
- * <pre>
- * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
- * major ::= digit+
- * minor ::= digit+
- * micro ::= digit+
- * qualifier ::= (alpha|digit|'_'|'-')+
- * digit ::= [0..9]
- * alpha ::= [a..zA..Z]
- * </pre>
- * There must be no whitespace in version.
- *
- * @param version String representation of the version identifier.
- * @throws IllegalArgumentException If <code>version</code> is improperly
- * formatted.
- */
- public Version(String version) {
- int major = 0;
- int minor = 0;
- int micro = 0;
- String qualifier = ""; //$NON-NLS-1$
-
- try {
- StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
- major = Integer.parseInt(st.nextToken());
-
- if (st.hasMoreTokens()) {
- st.nextToken(); // consume delimiter
- minor = Integer.parseInt(st.nextToken());
-
- if (st.hasMoreTokens()) {
- st.nextToken(); // consume delimiter
- micro = Integer.parseInt(st.nextToken());
-
- if (st.hasMoreTokens()) {
- st.nextToken(); // consume delimiter
- qualifier = st.nextToken();
-
- if (st.hasMoreTokens()) {
- throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
- }
- }
- }
- }
- }
- catch (NoSuchElementException e) {
- throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
- }
-
- this.major = major;
- this.minor = minor;
- this.micro = micro;
- this.qualifier = qualifier;
- validate();
- }
-
- /**
- * Called by the Version constructors to validate the version components.
- *
- * @throws IllegalArgumentException If the numerical components are negative
- * or the qualifier string is invalid.
- */
- private void validate() {
- if (major < 0) {
- throw new IllegalArgumentException("negative major"); //$NON-NLS-1$
- }
- if (minor < 0) {
- throw new IllegalArgumentException("negative minor"); //$NON-NLS-1$
- }
- if (micro < 0) {
- throw new IllegalArgumentException("negative micro"); //$NON-NLS-1$
- }
- int length = qualifier.length();
- for (int i = 0; i < length; i++) {
- if ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".indexOf(qualifier.charAt(i)) == -1) { //$NON-NLS-1$
- throw new IllegalArgumentException("invalid qualifier"); //$NON-NLS-1$
- }
- }
- }
-
- /**
- * Parses a version identifier from the specified string.
- *
- * <p>
- * See <code>Version(String)</code> for the format of the version string.
- *
- * @param version String representation of the version identifier. Leading
- * and trailing whitespace will be ignored.
- * @return A <code>Version</code> object representing the version
- * identifier. If <code>version</code> is <code>null</code> or
- * the empty string then <code>emptyVersion</code> will be
- * returned.
- * @throws IllegalArgumentException If <code>version</code> is improperly
- * formatted.
- */
- public static Version parseVersion(String version) {
- if (version == null) {
- return emptyVersion;
- }
-
- version = version.trim();
- if (version.length() == 0) {
- return emptyVersion;
- }
-
- return new Version(version);
- }
-
- /**
- * Returns the major component of this version identifier.
- *
- * @return The major component.
- */
- public int getMajor() {
- return major;
- }
-
- /**
- * Returns the minor component of this version identifier.
- *
- * @return The minor component.
- */
- public int getMinor() {
- return minor;
- }
-
- /**
- * Returns the micro component of this version identifier.
- *
- * @return The micro component.
- */
- public int getMicro() {
- return micro;
- }
-
- /**
- * Returns the qualifier component of this version identifier.
- *
- * @return The qualifier component.
- */
- public String getQualifier() {
- return qualifier;
- }
-
- /**
- * Returns the string representation of this version identifier.
- *
- * <p>
- * The format of the version string will be <code>major.minor.micro</code>
- * if qualifier is the empty string or
- * <code>major.minor.micro.qualifier</code> otherwise.
- *
- * @return The string representation of this version identifier.
- */
- public String toString() {
- String base = major + SEPARATOR + minor + SEPARATOR + micro;
- if (qualifier.length() == 0) { //$NON-NLS-1$
- return base;
- }
- else {
- return base + SEPARATOR + qualifier;
- }
- }
-
- /**
- * Returns a hash code value for the object.
- *
- * @return An integer which is a hash code value for this object.
- */
- public int hashCode() {
- return (major << 24) + (minor << 16) + (micro << 8)
- + qualifier.hashCode();
- }
-
- /**
- * Compares this <code>Version</code> object to another object.
- *
- * <p>
- * A version is considered to be <b>equal to </b> another version if the
- * major, minor and micro components are equal and the qualifier component
- * is equal (using <code>String.equals</code>).
- *
- * @param object The <code>Version</code> object to be compared.
- * @return <code>true</code> if <code>object</code> is a
- * <code>Version</code> and is equal to this object;
- * <code>false</code> otherwise.
- */
- public boolean equals(Object object) {
- if (object == this) { // quicktest
- return true;
- }
-
- if (!(object instanceof Version)) {
- return false;
- }
-
- Version other = (Version) object;
- return (major == other.major) && (minor == other.minor)
- && (micro == other.micro) && qualifier.equals(other.qualifier);
- }
-
- /**
- * Compares this <code>Version</code> object to another object.
- *
- * <p>
- * A version is considered to be <b>less than </b> another version if its
- * major component is less than the other version's major component, or the
- * major components are equal and its minor component is less than the other
- * version's minor component, or the major and minor components are equal
- * and its micro component is less than the other version's micro component,
- * or the major, minor and micro components are equal and it's qualifier
- * component is less than the other version's qualifier component (using
- * <code>String.compareTo</code>).
- *
- * <p>
- * A version is considered to be <b>equal to</b> another version if the
- * major, minor and micro components are equal and the qualifier component
- * is equal (using <code>String.compareTo</code>).
- *
- * @param object The <code>Version</code> object to be compared.
- * @return A negative integer, zero, or a positive integer if this object is
- * less than, equal to, or greater than the specified
- * <code>Version</code> object.
- * @throws ClassCastException If the specified object is not a
- * <code>Version</code>.
- */
- public int compareTo(Object object) {
- if (object == this) { // quicktest
- return 0;
- }
-
- Version other = (Version) object;
-
- int result = major - other.major;
- if (result != 0) {
- return result;
- }
-
- result = minor - other.minor;
- if (result != 0) {
- return result;
- }
-
- result = micro - other.micro;
- if (result != 0) {
- return result;
- }
-
- return qualifier.compareTo(other.qualifier);
- }
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Version.java,v 1.15 2006/03/14 01:21:02 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.framework;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * Version identifier for bundles and packages.
+ *
+ * <p>
+ * Version identifiers have four components.
+ * <ol>
+ * <li>Major version. A non-negative integer.</li>
+ * <li>Minor version. A non-negative integer.</li>
+ * <li>Micro version. A non-negative integer.</li>
+ * <li>Qualifier. A text string. See <code>Version(String)</code> for the
+ * format of the qualifier string.</li>
+ * </ol>
+ *
+ * <p>
+ * <code>Version</code> objects are immutable.
+ *
+ * @version $Revision: 1.15 $
+ * @since 1.3
+ */
+
+public class Version implements Comparable {
+ private final int major;
+ private final int minor;
+ private final int micro;
+ private final String qualifier;
+ private static final String SEPARATOR = "."; //$NON-NLS-1$
+
+ /**
+ * The empty version "0.0.0". Equivalent to calling
+ * <code>new Version(0,0,0)</code>.
+ */
+ public static final Version emptyVersion = new Version(0, 0, 0);
+
+ /**
+ * Creates a version identifier from the specified numerical components.
+ *
+ * <p>
+ * The qualifier is set to the empty string.
+ *
+ * @param major Major component of the version identifier.
+ * @param minor Minor component of the version identifier.
+ * @param micro Micro component of the version identifier.
+ * @throws IllegalArgumentException If the numerical components are
+ * negative.
+ */
+ public Version(int major, int minor, int micro) {
+ this(major, minor, micro, null);
+ }
+
+ /**
+ * Creates a version identifier from the specifed components.
+ *
+ * @param major Major component of the version identifier.
+ * @param minor Minor component of the version identifier.
+ * @param micro Micro component of the version identifier.
+ * @param qualifier Qualifier component of the version identifier. If
+ * <code>null</code> is specified, then the qualifier will be set
+ * to the empty string.
+ * @throws IllegalArgumentException If the numerical components are negative
+ * or the qualifier string is invalid.
+ */
+ public Version(int major, int minor, int micro, String qualifier) {
+ if (qualifier == null) {
+ qualifier = ""; //$NON-NLS-1$
+ }
+
+ this.major = major;
+ this.minor = minor;
+ this.micro = micro;
+ this.qualifier = qualifier;
+ validate();
+ }
+
+ /**
+ * Created a version identifier from the specified string.
+ *
+ * <p>
+ * Here is the grammar for version strings.
+ *
+ * <pre>
+ * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
+ * major ::= digit+
+ * minor ::= digit+
+ * micro ::= digit+
+ * qualifier ::= (alpha|digit|'_'|'-')+
+ * digit ::= [0..9]
+ * alpha ::= [a..zA..Z]
+ * </pre>
+ *
+ * There must be no whitespace in version.
+ *
+ * @param version String representation of the version identifier.
+ * @throws IllegalArgumentException If <code>version</code> is improperly
+ * formatted.
+ */
+ public Version(String version) {
+ int major = 0;
+ int minor = 0;
+ int micro = 0;
+ String qualifier = ""; //$NON-NLS-1$
+
+ try {
+ StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
+ major = Integer.parseInt(st.nextToken());
+
+ if (st.hasMoreTokens()) {
+ st.nextToken(); // consume delimiter
+ minor = Integer.parseInt(st.nextToken());
+
+ if (st.hasMoreTokens()) {
+ st.nextToken(); // consume delimiter
+ micro = Integer.parseInt(st.nextToken());
+
+ if (st.hasMoreTokens()) {
+ st.nextToken(); // consume delimiter
+ qualifier = st.nextToken();
+
+ if (st.hasMoreTokens()) {
+ throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ catch (NoSuchElementException e) {
+ throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
+ }
+
+ this.major = major;
+ this.minor = minor;
+ this.micro = micro;
+ this.qualifier = qualifier;
+ validate();
+ }
+
+ /**
+ * Called by the Version constructors to validate the version components.
+ *
+ * @throws IllegalArgumentException If the numerical components are negative
+ * or the qualifier string is invalid.
+ */
+ private void validate() {
+ if (major < 0) {
+ throw new IllegalArgumentException("negative major"); //$NON-NLS-1$
+ }
+ if (minor < 0) {
+ throw new IllegalArgumentException("negative minor"); //$NON-NLS-1$
+ }
+ if (micro < 0) {
+ throw new IllegalArgumentException("negative micro"); //$NON-NLS-1$
+ }
+ int length = qualifier.length();
+ for (int i = 0; i < length; i++) {
+ if ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".indexOf(qualifier.charAt(i)) == -1) { //$NON-NLS-1$
+ throw new IllegalArgumentException("invalid qualifier"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Parses a version identifier from the specified string.
+ *
+ * <p>
+ * See <code>Version(String)</code> for the format of the version string.
+ *
+ * @param version String representation of the version identifier. Leading
+ * and trailing whitespace will be ignored.
+ * @return A <code>Version</code> object representing the version
+ * identifier. If <code>version</code> is <code>null</code> or
+ * the empty string then <code>emptyVersion</code> will be
+ * returned.
+ * @throws IllegalArgumentException If <code>version</code> is improperly
+ * formatted.
+ */
+ public static Version parseVersion(String version) {
+ if (version == null) {
+ return emptyVersion;
+ }
+
+ version = version.trim();
+ if (version.length() == 0) {
+ return emptyVersion;
+ }
+
+ return new Version(version);
+ }
+
+ /**
+ * Returns the major component of this version identifier.
+ *
+ * @return The major component.
+ */
+ public int getMajor() {
+ return major;
+ }
+
+ /**
+ * Returns the minor component of this version identifier.
+ *
+ * @return The minor component.
+ */
+ public int getMinor() {
+ return minor;
+ }
+
+ /**
+ * Returns the micro component of this version identifier.
+ *
+ * @return The micro component.
+ */
+ public int getMicro() {
+ return micro;
+ }
+
+ /**
+ * Returns the qualifier component of this version identifier.
+ *
+ * @return The qualifier component.
+ */
+ public String getQualifier() {
+ return qualifier;
+ }
+
+ /**
+ * Returns the string representation of this version identifier.
+ *
+ * <p>
+ * The format of the version string will be <code>major.minor.micro</code>
+ * if qualifier is the empty string or
+ * <code>major.minor.micro.qualifier</code> otherwise.
+ *
+ * @return The string representation of this version identifier.
+ */
+ public String toString() {
+ String base = major + SEPARATOR + minor + SEPARATOR + micro;
+ if (qualifier.length() == 0) { //$NON-NLS-1$
+ return base;
+ }
+ else {
+ return base + SEPARATOR + qualifier;
+ }
+ }
+
+ /**
+ * Returns a hash code value for the object.
+ *
+ * @return An integer which is a hash code value for this object.
+ */
+ public int hashCode() {
+ return (major << 24) + (minor << 16) + (micro << 8)
+ + qualifier.hashCode();
+ }
+
+ /**
+ * Compares this <code>Version</code> object to another object.
+ *
+ * <p>
+ * A version is considered to be <b>equal to </b> another version if the
+ * major, minor and micro components are equal and the qualifier component
+ * is equal (using <code>String.equals</code>).
+ *
+ * @param object The <code>Version</code> object to be compared.
+ * @return <code>true</code> if <code>object</code> is a
+ * <code>Version</code> and is equal to this object;
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object object) {
+ if (object == this) { // quicktest
+ return true;
+ }
+
+ if (!(object instanceof Version)) {
+ return false;
+ }
+
+ Version other = (Version) object;
+ return (major == other.major) && (minor == other.minor)
+ && (micro == other.micro) && qualifier.equals(other.qualifier);
+ }
+
+ /**
+ * Compares this <code>Version</code> object to another object.
+ *
+ * <p>
+ * A version is considered to be <b>less than </b> another version if its
+ * major component is less than the other version's major component, or the
+ * major components are equal and its minor component is less than the other
+ * version's minor component, or the major and minor components are equal
+ * and its micro component is less than the other version's micro component,
+ * or the major, minor and micro components are equal and it's qualifier
+ * component is less than the other version's qualifier component (using
+ * <code>String.compareTo</code>).
+ *
+ * <p>
+ * A version is considered to be <b>equal to</b> another version if the
+ * major, minor and micro components are equal and the qualifier component
+ * is equal (using <code>String.compareTo</code>).
+ *
+ * @param object The <code>Version</code> object to be compared.
+ * @return A negative integer, zero, or a positive integer if this object is
+ * less than, equal to, or greater than the specified
+ * <code>Version</code> object.
+ * @throws ClassCastException If the specified object is not a
+ * <code>Version</code>.
+ */
+ public int compareTo(Object object) {
+ if (object == this) { // quicktest
+ return 0;
+ }
+
+ Version other = (Version) object;
+
+ int result = major - other.major;
+ if (result != 0) {
+ return result;
+ }
+
+ result = minor - other.minor;
+ if (result != 0) {
+ return result;
+ }
+
+ result = micro - other.micro;
+ if (result != 0) {
+ return result;
+ }
+
+ return qualifier.compareTo(other.qualifier);
+ }
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java b/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java
index 62962dd..5e7682f 100644
--- a/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java
+++ b/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleLocationCondition.java
@@ -1,49 +1,118 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleLocationCondition.java,v 1.9 2005/05/25 16:22:46 twatson Exp $
- *
- * Copyright (c) OSGi Alliance (2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-package org.osgi.service.condpermadmin;
-
-import java.io.FilePermission;
-import org.osgi.framework.Bundle;
-
-/**
- *
- * Checks to see if a Bundle matches the given location pattern. Pattern matching
- * is done using FilePermission style patterns.
- *
- * @version $Revision: 1.9 $
- */
-public class BundleLocationCondition {
- private static final String CONDITION_TYPE = "org.osgi.service.condpermadmin.BundleLocationCondition";
- /**
- * Constructs a condition that tries to match the passed Bundle's location
- * to the location pattern.
- *
- * @param bundle the Bundle being evaluated.
- * @param info the ConditionInfo to construct the condition for. The args of the
- * ConditionInfo specify the location to match the Bundle
- * location to. Matching is done according to the patterns documented
- * in FilePermission.
- */
- static public Condition getCondition(Bundle bundle, ConditionInfo info) {
- if (!CONDITION_TYPE.equals(info.getType()))
- throw new IllegalArgumentException("ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
- String[] args = info.getArgs();
- if (args.length != 1)
- throw new IllegalArgumentException("Illegal number of args: " + args.length);
- String location = args[0];
- FilePermission locationPat = new FilePermission(location, "read");
- FilePermission sourcePat = new FilePermission(bundle.getLocation().toString(), "read");
- return locationPat.implies(sourcePat) ? Condition.TRUE : Condition.FALSE;
- }
-
- private BundleLocationCondition() {
- // private constructor to prevent objects of this type
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleLocationCondition.java,v 1.17 2006/03/14 01:20:40 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (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.condpermadmin;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Hashtable;
+
+import org.osgi.framework.*;
+
+/**
+ * Condition to test if the location of a bundle matches a pattern. Pattern
+ * matching is done according to the filter string matching rules.
+ *
+ * @version $Revision: 1.17 $
+ */
+public class BundleLocationCondition {
+ private static final String CONDITION_TYPE = "org.osgi.service.condpermadmin.BundleLocationCondition";
+
+ /**
+ * Constructs a condition that tries to match the passed Bundle's location
+ * to the location pattern.
+ *
+ * @param bundle The Bundle being evaluated.
+ * @param info The ConditionInfo to construct the condition for. The args of
+ * the ConditionInfo must be a single String which specifies the
+ * location pattern to match against the Bundle location. Matching is
+ * done according to the filter string matching rules. Any '*'
+ * characters in the location argument are used as wildcards when
+ * matching bundle locations unless they are escaped with a '\'
+ * character.
+ * @return Condition object for the requested condition.
+ */
+ static public Condition getCondition(final Bundle bundle, ConditionInfo info) {
+ if (!CONDITION_TYPE.equals(info.getType()))
+ throw new IllegalArgumentException(
+ "ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+ String[] args = info.getArgs();
+ if (args.length != 1)
+ throw new IllegalArgumentException("Illegal number of args: "
+ + args.length);
+ String bundleLocation = (String) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return bundle.getLocation();
+ }
+ });
+ Filter filter = null;
+ try {
+ filter = FrameworkUtil.createFilter("(location="
+ + escapeLocation(args[0]) + ")");
+ }
+ catch (InvalidSyntaxException e) {
+ // this should never happen, but just incase
+ throw new RuntimeException("Invalid filter: " + e.getFilter());
+ }
+ Hashtable matchProps = new Hashtable(2);
+ matchProps.put("location", bundleLocation);
+ return filter.match(matchProps) ? Condition.TRUE : Condition.FALSE;
+ }
+
+ private BundleLocationCondition() {
+ // private constructor to prevent objects of this type
+ }
+
+ /**
+ * Escape the value string such that '(', ')' and '\' are escaped. The '\'
+ * char is only escaped if it is not followed by a '*'.
+ *
+ * @param value unescaped value string.
+ * @return escaped value string.
+ */
+ private static String escapeLocation(String value) {
+ boolean escaped = false;
+ int inlen = value.length();
+ int outlen = inlen << 1; /* inlen * 2 */
+
+ char[] output = new char[outlen];
+ value.getChars(0, inlen, output, inlen);
+
+ int cursor = 0;
+ for (int i = inlen; i < outlen; i++) {
+ char c = output[i];
+ switch (c) {
+ case '\\' :
+ if (i + 1 < outlen && output[i + 1] == '*')
+ break;
+ case '(' :
+ case ')' :
+ output[cursor] = '\\';
+ cursor++;
+ escaped = true;
+ break;
+ }
+
+ output[cursor] = c;
+ cursor++;
+ }
+
+ return escaped ? new String(output, 0, cursor) : value;
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java b/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java
index 78f2f66..1742b06 100644
--- a/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java
+++ b/org.osgi/src/main/java/org/osgi/service/condpermadmin/BundleSignerCondition.java
@@ -1,69 +1,152 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleSignerCondition.java,v 1.4 2005/05/25 16:22:46 twatson Exp $
- *
- * Copyright (c) OSGi Alliance (2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.condpermadmin;
-
-import org.osgi.framework.Bundle;
-
-/**
- * This condition checks the signer of a bundle. Since the bundle's signer can only change
- * when the bundle is updated, this condition is immutable.
- * <p>
- * The condition expressed using a single String that specifies a Distinguished Name (DN)
- * chain to match bundle signers against. DN's are encoded using IETF RFC 2253. Usually
- * signers use certificates that are issued by certificate authorities, which also have a
- * corresponding DN and certificate. The certificate authorities can form a chain of trust
- * where the last DN and certificate is known by the framework. The signer of a bundle is
- * expressed as signers DN followed by the DN of its issuer followed by the DN of the next
- * issuer until the DN of the root certificate authority. Each DN is separated by a semicolon.
- * <p>
- * A bundle can satisfy this condition if one of its signers has a DN chain that matches the
- * DN chain used to construct this condition.
- * Wildcards (`*') can be used to allow greater flexibility in specifying the DN chains.
- * Wildcards can be used in place of DNs, RDNs, or the value in an RDN. If a wildcard is
- * used for a value of an RDN, the value must be exactly "*" and will match any value for
- * the corresponding type in that RDN. If a wildcard is used for a RDN, it must be the
- * first RDN and will match any number of RDNs (including zero RDNs).
- *
- * @version $Revision: 1.4 $
- */
-public class BundleSignerCondition
-{
-// NOT USED!!!
-// private static final String CONDITION_TYPE = "org.osgi.service.condpermadmin.BundleSignerCondition";
-
- /**
- * Constructs a condition that tries to match the passed Bundle's location
- * to the location pattern.
- *
- * @param bundle the Bundle being evaluated.
- * @param info the ConditionInfo to construct the condition for. The args of the
- * ConditionInfo specify the chain of distinguished names pattern to match
- * against the signer of the Bundle
- */
- static public Condition getCondition(Bundle bundle, ConditionInfo info) {
-/*
- if (!CONDITION_TYPE.equals(info.getType()))
- throw new IllegalArgumentException("ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
- String[] args = info.getArgs();
- if (args.length != 1)
- throw new IllegalArgumentException("Illegal number of args: " + args.length);
- // implementation specific code used here
- AbstractBundle ab = (AbstractBundle) bundle;
- return ab.getBundleData().matchDNChain(args[0]) ? Condition.TRUE : Condition.FALSE;
-*/
- // TODO: Fix BundleSignerCondition.getCondition()
- return null;
- }
-
- private BundleSignerCondition() {
- // private constructor to prevent objects of this type
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/BundleSignerCondition.java,v 1.9 2006/03/14 01:20:40 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (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.condpermadmin;
+
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Condition to test if the signer of a bundle matches a pattern. Since the bundle's signer can
+ * only change when the bundle is updated, this condition is immutable.
+ * <p>
+ * The condition expressed using a single String that specifies a Distinguished
+ * Name (DN) chain to match bundle signers against. DN's are encoded using IETF
+ * RFC 2253. Usually signers use certificates that are issued by certificate
+ * authorities, which also have a corresponding DN and certificate. The
+ * certificate authorities can form a chain of trust where the last DN and
+ * certificate is known by the framework. The signer of a bundle is expressed as
+ * signers DN followed by the DN of its issuer followed by the DN of the next
+ * issuer until the DN of the root certificate authority. Each DN is separated
+ * by a semicolon.
+ * <p>
+ * A bundle can satisfy this condition if one of its signers has a DN chain that
+ * matches the DN chain used to construct this condition. Wildcards (`*') can be
+ * used to allow greater flexibility in specifying the DN chains. Wildcards can
+ * be used in place of DNs, RDNs, or the value in an RDN. If a wildcard is used
+ * for a value of an RDN, the value must be exactly "*" and will match any value
+ * for the corresponding type in that RDN. If a wildcard is used for a RDN, it
+ * must be the first RDN and will match any number of RDNs (including zero
+ * RDNs).
+ *
+ * @version $Revision: 1.9 $
+ */
+public class BundleSignerCondition {
+ /*
+ * NOTE: A framework implementor may also choose to replace this class in
+ * their distribution with a class that directly interfaces with the
+ * framework implementation. This replacement class MUST NOT alter the
+ * public/protected signature of this class.
+ */
+
+ /*
+ * This class will load the BundleSignerCondition class in the package named
+ * by the org.osgi.vendor.condpermadmin package. This class will delegate
+ * getCondition methods calls to the vendor BundleSignerCondition class.
+ */
+ private static final String packageProperty = "org.osgi.vendor.condpermadmin";
+ private static final Method getCondition;
+ static {
+ getCondition = (Method) AccessController
+ .doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String packageName = System
+ .getProperty(packageProperty);
+ if (packageName == null) {
+ throw new NoClassDefFoundError(packageProperty
+ + " property not set");
+ }
+
+ Class delegateClass;
+ try {
+ delegateClass = Class.forName(packageName
+ + ".BundleSignerCondition");
+ }
+ catch (ClassNotFoundException e) {
+ throw new NoClassDefFoundError(e.toString());
+ }
+
+ Method result;
+ try {
+ result = delegateClass.getMethod("getCondition",
+ new Class[] {Bundle.class,
+ ConditionInfo.class });
+ }
+ catch (NoSuchMethodException e) {
+ throw new NoSuchMethodError(e.toString());
+ }
+
+ if (!Modifier.isStatic(result.getModifiers())) {
+ throw new NoSuchMethodError(
+ "getCondition method must be static");
+ }
+
+ return result;
+ }
+ });
+ }
+
+ private static final String CONDITION_TYPE = "org.osgi.service.condpermadmin.BundleSignerCondition";
+
+ /**
+ * Constructs a Condition that tries to match the passed Bundle's location
+ * to the location pattern.
+ *
+ * @param bundle The Bundle being evaluated.
+ * @param info The ConditionInfo to construct the condition for. The args of
+ * the ConditionInfo specify a single String specifying the chain of
+ * distinguished names pattern to match against the signer of the
+ * Bundle.
+ * @return A Condition which checks the signers of the specified bundle.
+ */
+ static public Condition getCondition(Bundle bundle, ConditionInfo info) {
+ if (!CONDITION_TYPE.equals(info.getType()))
+ throw new IllegalArgumentException(
+ "ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+ String[] args = info.getArgs();
+ if (args.length != 1)
+ throw new IllegalArgumentException("Illegal number of args: "
+ + args.length);
+
+ try {
+ try {
+ return (Condition) getCondition.invoke(null, new Object[] {
+ bundle, info});
+ }
+ catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+ catch (Error e) {
+ throw e;
+ }
+ catch (RuntimeException e) {
+ throw e;
+ }
+ catch (Throwable e) {
+ throw new RuntimeException(e.toString());
+ }
+ }
+
+ private BundleSignerCondition() {
+ // private constructor to prevent objects of this type
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/service/condpermadmin/Condition.java b/org.osgi/src/main/java/org/osgi/service/condpermadmin/Condition.java
index 76dba1c..6354ac6 100644
--- a/org.osgi/src/main/java/org/osgi/service/condpermadmin/Condition.java
+++ b/org.osgi/src/main/java/org/osgi/service/condpermadmin/Condition.java
@@ -1,97 +1,127 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/Condition.java,v 1.9 2005/05/25 16:22:46 twatson Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.condpermadmin;
-
-import java.util.Dictionary;
-
-/**
- * This interface is used to implement Conditions that are bound to Permissions
- * using ConditionalPermissionCollection. The Permissions of the
- * ConditionalPermissionCollection can only be used if the associated Condition
- * is satisfied.
- */
-public interface Condition {
- /**
- * A condition object that will always evaluate to true and that is never postponed.
- */
- public final static Condition TRUE = new BooleanCondition(true);
-
- /**
- * A condition object that will always evaluate to false and that is never postponed.
- */
- public final static Condition FALSE = new BooleanCondition(false);
-
- /**
- * This method returns true if the evaluation of the Condition must be postponed
- * until the end of the permission check. If it returns false, it must be able
- * to directly answer the isSatisfied method. In other
- * words, isSatisfied() will return very quickly since no external sources,
- * such as for example users, need to be consulted.
- *
- * @return false if evaluation is immediate, otherwise true to indicate the evaluation must be postponed.
- */
- boolean isPostponed();
-
- /**
- * This method returns true if the Condition is satisfied.
- */
- boolean isSatisfied();
-
- /**
- * This method returns true if the satisfiability may change.
- */
- boolean isMutable();
-
- /**
- * This method returns true if the set of Conditions are satisfied. Although
- * this method is not static, it should be implemented as if it were static.
- * All of the passed Conditions will have the same type and will correspond
- * to the class type of the object on which this method is invoked.
- *
- * @param conds the array of Conditions that must be satisfied
- * @param context a Dictionary object that implementors can use to track
- * state. If this method is invoked multiple times in the same permission
- * evaluation, the same Dictionary will be passed multiple times. The
- * SecurityManager treats this Dictionary as an opaque object simply
- * creates an empty dictionary and passes it to subsequent invocations
- * if multiple invocatios are needed.
- * @return true if all the Conditions are satisfied.
- */
- boolean isSatisfied(Condition conds[], Dictionary context);
-
- /**
- * Package internal class used to define the {@link Condition#FALSE} and
- * {@link Condition#TRUE} constants.
- */
- final static class BooleanCondition implements Condition {
- boolean satisfied;
- BooleanCondition(boolean satisfied) {
- this.satisfied = satisfied;
- }
- public boolean isPostponed() {
- return false;
- }
- public boolean isSatisfied() {
- return satisfied;
- }
- public boolean isMutable() {
- return false;
- }
- public boolean isSatisfied(Condition[] conds, Dictionary context) {
- for(int i = 0; i < conds.length; i++) {
- if (!conds[i].isSatisfied())
- return false;
- }
- return true;
- }
-
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/Condition.java,v 1.12 2006/03/14 01:20:40 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.condpermadmin;
+
+import java.util.Dictionary;
+
+/**
+ * The interface implemented by a Condition. Conditions are bound to Permissions
+ * using Conditional Permission Info. The Permissions of a ConditionalPermission
+ * Info can only be used if the associated Conditions are satisfied.
+ *
+ * @version $Revision: 1.12 $
+ */
+public interface Condition {
+ /**
+ * A Condition object that will always evaluate to true and that is never
+ * postponed.
+ */
+ public final static Condition TRUE = new BooleanCondition(true);
+
+ /**
+ * A Condition object that will always evaluate to false and that is never
+ * postponed.
+ */
+ public final static Condition FALSE = new BooleanCondition(false);
+
+ /**
+ * Returns whether the evaluation must be postponed until the end of the
+ * permission check. This method returns <code>true</code> if the
+ * evaluation of the Condition must be postponed until the end of the
+ * permission check. If this method returns <code>false</code>, this
+ * Condition must be able to directly answer the {@link #isSatisfied()}
+ * method. In other words, isSatisfied() will return very quickly since no
+ * external sources, such as for example users, need to be consulted.
+ *
+ * @return <code>true</code> to indicate the evaluation must be postponed.
+ * Otherwise, <code>false</code> if the evaluation can be
+ * immediately performed.
+ */
+ boolean isPostponed();
+
+ /**
+ * Returns whether the Condition is satisfied.
+ *
+ * @return <code>true</code> to indicate the Conditions is satisfied.
+ * Otherwise, <code>false</code> if the Condition is not satisfied.
+ */
+ boolean isSatisfied();
+
+ /**
+ * Returns whether the Condition is mutable.
+ *
+ * @return <code>true</code> to indicate the value returned by
+ * {@link #isSatisfied()} can change. Otherwise, <code>false</code>
+ * if the value returned by {@link #isSatisfied()} will not change.
+ */
+ boolean isMutable();
+
+ /**
+ * Returns whether a the set of Conditions are satisfied. Although this
+ * method is not static, it must be implemented as if it were static. All of
+ * the passed Conditions will be of the same type and will correspond to the
+ * class type of the object on which this method is invoked.
+ *
+ * @param conditions The array of Conditions.
+ * @param context A Dictionary object that implementors can use to track
+ * state. If this method is invoked multiple times in the same
+ * permission evaluation, the same Dictionary will be passed multiple
+ * times. The SecurityManager treats this Dictionary as an opaque
+ * object and simply creates an empty dictionary and passes it to
+ * subsequent invocations if multiple invocatios are needed.
+ * @return <code>true</code> if all the Conditions are satisfied.
+ * Otherwise, <code>false</code> if one of the Conditions is not
+ * satisfied.
+ */
+ boolean isSatisfied(Condition conditions[], Dictionary context);
+
+}
+
+/**
+ * Package internal class used to define the {@link Condition#FALSE} and
+ * {@link Condition#TRUE} constants.
+ */
+final class BooleanCondition implements Condition {
+ final boolean satisfied;
+
+ BooleanCondition(boolean satisfied) {
+ this.satisfied = satisfied;
+ }
+
+ public boolean isPostponed() {
+ return false;
+ }
+
+ public boolean isSatisfied() {
+ return satisfied;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public boolean isSatisfied(Condition[] conds, Dictionary context) {
+ for (int i = 0; i < conds.length; i++) {
+ if (!conds[i].isSatisfied())
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java b/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java
index 6207c4f..71e1e95 100644
--- a/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java
+++ b/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java
@@ -1,314 +1,349 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionInfo.java,v 1.6 2005/05/13 20:33:31 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.condpermadmin;
-
-import java.util.Vector;
-
-/**
- * Condition representation used by the Conditional Permission Admin service.
- *
- * <p>
- * This class encapsulates two pieces of information: a Condition <i>type</i>
- * (class name), which must implement <tt>Condition</tt>, and the arguments
- * passed to its constructor.
- *
- * <p>
- * In order for a Condition represented by a <tt>ConditionInfo</tt> to be
- * instantiated and considered during a permission check, its Condition class
- * must be available from the system classpath.
- *
- */
-
-public class ConditionInfo {
-
- private String type;
-
- private String args[];
-
- /**
- * Constructs a <tt>ConditionInfo</tt> from the given type and args.
- *
- * @param type
- * The fully qualified class name of the condition represented by
- * this <tt>ConditionInfo</tt>. The class must implement
- * <tt>Condition</tt> and must define a constructor that takes
- * a <tt>Bundle</tt> and the correct number of argument
- * strings.
- *
- * @param args
- * The arguments that will be passed to the constructor of the
- * <tt>Conditon</tt> class identified by <tt>type</tt>.
- *
- * @exception java.lang.NullPointerException
- * if <tt>type</tt> is <tt>null</tt>.
- */
- public ConditionInfo(String type, String args[]) {
- this.type = type;
- this.args = args;
- if (type == null) {
- throw new NullPointerException("type is null");
- }
- }
-
- /**
- * Constructs a <tt>ConditionInfo</tt> object from the given encoded
- * <tt>ConditionInfo</tt> string.
- *
- * @param encodedCondition
- * The encoded <tt>ConditionInfo</tt>.
- * @see #getEncoded
- * @exception java.lang.IllegalArgumentException
- * if <tt>encodedCondition</tt> is not properly formatted.
- */
- public ConditionInfo(String encodedCondition) {
- if (encodedCondition == null) {
- throw new NullPointerException("missing encoded permission");
- }
- if (encodedCondition.length() == 0) {
- throw new IllegalArgumentException("empty encoded permission");
- }
-
- try {
- char[] encoded = encodedCondition.toCharArray();
-
- /* the first character must be '[' */
- if (encoded[0] != '[') {
- throw new IllegalArgumentException(
- "first character not open bracket");
- }
-
- /* type is not quoted or encoded */
- int end = 1;
- int begin = end;
-
- while ((encoded[end] != ' ') && (encoded[end] != ')')) {
- end++;
- }
-
- if (end == begin) {
- throw new IllegalArgumentException("expecting type");
- }
-
- this.type = new String(encoded, begin, end - begin);
-
- Vector args = new Vector();
- /* type may be followed by name which is quoted and encoded */
- while (encoded[end] == ' ') {
- end++;
-
- if (encoded[end] != '"') {
- throw new IllegalArgumentException("expecting quoted name");
- }
-
- end++;
- begin = end;
-
- while (encoded[end] != '"') {
- if (encoded[end] == '\\') {
- end++;
- }
-
- end++;
- }
-
- args.add(decodeString(encoded, begin, end));
- end++;
- }
- this.args = (String[]) args.toArray(new String[0]);
- /* the final character must be ')' */
- if ((encoded[end] != ']') || (end + 1 != encoded.length)) {
- throw new IllegalArgumentException("last character not "
- + "close bracket");
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new IllegalArgumentException("parsing terminated abruptly");
- }
- }
-
- /**
- * Returns the string encoding of this <tt>ConditionInfo</tt> in a form
- * suitable for restoring this <tt>ConditionInfo</tt>.
- *
- * <p>
- * The encoding format is:
- *
- * <pre>
- *
- * [type "arg0" "arg1" ...]
- *
- * </pre>
- *
- * where <i>argX</i> are strings that are encoded for proper parsing.
- * Specifically, the <tt>"</tt>, <tt>\</tt>, carriage return, and
- * linefeed characters are escaped using <tt>\"</tt>, <tt>\\</tt>,
- * <tt>\r</tt>, and <tt>\n</tt>, respectively.
- *
- * <p>
- * The encoded string must contain no leading or trailing whitespace
- * characters. A single space character must be used between type and "<i>arg0</i>"
- * and between all arguments.
- *
- * @return The string encoding of this <tt>ConditionInfo</tt>.
- */
- public final String getEncoded() {
- StringBuffer output = new StringBuffer();
- output.append('[');
- output.append(type);
-
- for (int i = 0; i < args.length; i++) {
- output.append(" \"");
- encodeString(args[i], output);
- output.append('\"');
- }
-
- output.append(']');
-
- return (output.toString());
- }
-
- /**
- * Returns the string representation of this <tt>ConditionInfo</tt>. The
- * string is created by calling the <tt>getEncoded</tt> method on this
- * <tt>ConditionInfo</tt>.
- *
- * @return The string representation of this <tt>ConditionInfo</tt>.
- */
- public String toString() {
- return (getEncoded());
- }
-
- /**
- * Returns the fully qualified class name of the condition represented by
- * this <tt>ConditionInfo</tt>.
- *
- * @return The fully qualified class name of the condition represented by
- * this <tt>ConditionInfo</tt>.
- */
- public final String getType() {
- return (type);
- }
-
- /**
- * Returns arguments of this <tt>ConditionInfo</tt>.
- *
- * @return The arguments of this <tt>ConditionInfo</tt>. have a name.
- */
- public final String[] getArgs() {
- return (args);
- }
-
- /**
- * Determines the equality of two <tt>ConditionInfo</tt> objects.
- *
- * This method checks that specified object has the same type and args as
- * this <tt>ConditionInfo</tt> object.
- *
- * @param obj
- * The object to test for equality with this
- * <tt>ConditionInfo</tt> object.
- * @return <tt>true</tt> if <tt>obj</tt> is a <tt>ConditionInfo</tt>,
- * and has the same type and args as this <tt>ConditionInfo</tt>
- * object; <tt>false</tt> otherwise.
- */
- public boolean equals(Object obj) {
- if (obj == this) {
- return (true);
- }
-
- if (!(obj instanceof ConditionInfo)) {
- return (false);
- }
-
- ConditionInfo other = (ConditionInfo) obj;
-
- if (!type.equals(other.type) || args.length != other.args.length)
- return false;
-
- for (int i = 0; i < args.length; i++) {
- if (!args[i].equals(other.args[i]))
- return false;
- }
- return true;
- }
-
- /**
- * Returns the hash code value for this object.
- *
- * @return A hash code value for this object.
- */
-
- public int hashCode() {
- int hash = type.hashCode();
-
- for (int i = 0; i < args.length; i++) {
- hash ^= args[i].hashCode();
- }
- return (hash);
- }
-
- /**
- * This escapes the quotes, backslashes, \n, and \r in the string using a
- * backslash and appends the newly escaped string to a StringBuffer.
- */
- private static void encodeString(String str, StringBuffer output) {
- int len = str.length();
-
- for (int i = 0; i < len; i++) {
- char c = str.charAt(i);
-
- switch (c) {
- case '"':
- case '\\':
- output.append('\\');
- output.append(c);
- break;
- case '\r':
- output.append("\\r");
- break;
- case '\n':
- output.append("\\n");
- break;
- default:
- output.append(c);
- break;
- }
- }
- }
-
- /**
- * Takes an encoded character array and decodes it into a new String.
- */
- private static String decodeString(char[] str, int begin, int end) {
- StringBuffer output = new StringBuffer(end - begin);
-
- for (int i = begin; i < end; i++) {
- char c = str[i];
-
- if (c == '\\') {
- i++;
-
- if (i < end) {
- c = str[i];
-
- if (c == 'n') {
- c = '\n';
- } else if (c == 'r') {
- c = '\r';
- }
- }
- }
-
- output.append(c);
- }
-
- return (output.toString());
- }
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionInfo.java,v 1.12 2006/03/14 01:20:40 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.condpermadmin;
+
+import java.util.ArrayList;
+
+/**
+ * Condition representation used by the Conditional Permission Admin service.
+ *
+ * <p>
+ * This class encapsulates two pieces of information: a Condition <i>type</i>
+ * (class name), which must implement <code>Condition</code>, and the
+ * arguments passed to its constructor.
+ *
+ * <p>
+ * In order for a Condition represented by a <code>ConditionInfo</code> to be
+ * instantiated and considered during a permission check, its Condition class
+ * must be available from the system classpath.
+ *
+ * <p>
+ * The Condition class must either:
+ * <ul>
+ * <li>Declare a public static <code>getCondition</code> method that takes a
+ * <code>Bundle</code> object and a <code>ConditionInfo</code> object as
+ * arguments. That method must return an object that implements the
+ * <code>Condition</code> interface.</li>
+ * <li>Implement the <code>Condition</code> interface and define a public
+ * constructor that takes a <code>Bundle</code> object and a
+ * <code>ConditionInfo</code> object as arguments.
+ * </ul>
+ *
+ * @version $Revision: 1.12 $
+ */
+public class ConditionInfo {
+ private String type;
+ private String[] args;
+
+ /**
+ * Constructs a <code>ConditionInfo</code> from the specified type and
+ * args.
+ *
+ * @param type The fully qualified class name of the Condition represented
+ * by this <code>ConditionInfo</code>.
+ * @param args The arguments for the Condition. These arguments are
+ * available to the newly created Condition by calling the
+ * {@link #getArgs()} method.
+ * @throws java.lang.NullPointerException If <code>type</code> is
+ * <code>null</code>.
+ */
+ public ConditionInfo(String type, String[] args) {
+ this.type = type;
+ this.args = args != null ? args : new String[0];
+ if (type == null) {
+ throw new NullPointerException("type is null");
+ }
+ }
+
+ /**
+ * Constructs a <code>ConditionInfo</code> object from the specified
+ * encoded <code>ConditionInfo</code> string. White space in the encoded
+ * <code>ConditionInfo</code> string is ignored.
+ *
+ * @param encodedCondition The encoded <code>ConditionInfo</code>.
+ * @see #getEncoded
+ * @throws java.lang.IllegalArgumentException If the
+ * <code>encodedCondition</code> is not properly formatted.
+ */
+ public ConditionInfo(String encodedCondition) {
+ if (encodedCondition == null) {
+ throw new NullPointerException("missing encoded condition");
+ }
+ if (encodedCondition.length() == 0) {
+ throw new IllegalArgumentException("empty encoded condition");
+ }
+ try {
+ char[] encoded = encodedCondition.toCharArray();
+ int length = encoded.length;
+ int pos = 0;
+
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+
+ /* the first character must be '[' */
+ if (encoded[pos] != '[') {
+ throw new IllegalArgumentException("expecting open bracket");
+ }
+ pos++;
+
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+
+ /* type is not quoted or encoded */
+ int begin = pos;
+ while (!Character.isWhitespace(encoded[pos])
+ && (encoded[pos] != ']')) {
+ pos++;
+ }
+ if (pos == begin || encoded[begin] == '"') {
+ throw new IllegalArgumentException("expecting type");
+ }
+ this.type = new String(encoded, begin, pos - begin);
+
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+
+ /* type may be followed by args which are quoted and encoded */
+ ArrayList argsList = new ArrayList();
+ while (encoded[pos] == '"') {
+ pos++;
+ begin = pos;
+ while (encoded[pos] != '"') {
+ if (encoded[pos] == '\\') {
+ pos++;
+ }
+ pos++;
+ }
+ argsList.add(unescapeString(encoded, begin, pos));
+ pos++;
+
+ if (Character.isWhitespace(encoded[pos])) {
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+ }
+ }
+ this.args = (String[]) argsList
+ .toArray(new String[argsList.size()]);
+
+ /* the final character must be ']' */
+ char c = encoded[pos];
+ pos++;
+ while ((pos < length) && Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+ if ((c != ']') || (pos != length)) {
+ throw new IllegalArgumentException("expecting close bracket");
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ throw new IllegalArgumentException("parsing terminated abruptly");
+ }
+ }
+
+ /**
+ * Returns the string encoding of this <code>ConditionInfo</code> in a
+ * form suitable for restoring this <code>ConditionInfo</code>.
+ *
+ * <p>
+ * The encoding format is:
+ *
+ * <pre>
+ * [type "arg0" "arg1" ...]
+ * </pre>
+ *
+ * where <i>argN</i> are strings that are encoded for proper parsing.
+ * Specifically, the <code>"</code>, <code>\</code>, carriage return,
+ * and linefeed characters are escaped using <code>\"</code>,
+ * <code>\\</code>, <code>\r</code>, and <code>\n</code>,
+ * respectively.
+ *
+ * <p>
+ * The encoded string contains no leading or trailing whitespace characters.
+ * A single space character is used between type and "<i>arg0</i>" and
+ * between the arguments.
+ *
+ * @return The string encoding of this <code>ConditionInfo</code>.
+ */
+ public final String getEncoded() {
+ StringBuffer output = new StringBuffer();
+ output.append('[');
+ output.append(type);
+
+ for (int i = 0; i < args.length; i++) {
+ output.append(" \"");
+ escapeString(args[i], output);
+ output.append('\"');
+ }
+
+ output.append(']');
+
+ return output.toString();
+ }
+
+ /**
+ * Returns the string representation of this <code>ConditionInfo</code>.
+ * The string is created by calling the <code>getEncoded</code> method on
+ * this <code>ConditionInfo</code>.
+ *
+ * @return The string representation of this <code>ConditionInfo</code>.
+ */
+ public String toString() {
+ return getEncoded();
+ }
+
+ /**
+ * Returns the fully qualified class name of the condition represented by
+ * this <code>ConditionInfo</code>.
+ *
+ * @return The fully qualified class name of the condition represented by
+ * this <code>ConditionInfo</code>.
+ */
+ public final String getType() {
+ return type;
+ }
+
+ /**
+ * Returns arguments of this <code>ConditionInfo</code>.
+ *
+ * @return The arguments of this <code>ConditionInfo</code>. An empty
+ * array is returned if the <code>ConditionInfo</code> has no
+ * arguments.
+ */
+ public final String[] getArgs() {
+ return args;
+ }
+
+ /**
+ * Determines the equality of two <code>ConditionInfo</code> objects.
+ *
+ * This method checks that specified object has the same type and args as
+ * this <code>ConditionInfo</code> object.
+ *
+ * @param obj The object to test for equality with this
+ * <code>ConditionInfo</code> object.
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>ConditionInfo</code>, and has the same type and args as
+ * this <code>ConditionInfo</code> object; <code>false</code>
+ * otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof ConditionInfo)) {
+ return false;
+ }
+
+ ConditionInfo other = (ConditionInfo) obj;
+
+ if (!type.equals(other.type) || args.length != other.args.length)
+ return false;
+
+ for (int i = 0; i < args.length; i++) {
+ if (!args[i].equals(other.args[i]))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+
+ public int hashCode() {
+ int hash = type.hashCode();
+
+ for (int i = 0; i < args.length; i++) {
+ hash ^= args[i].hashCode();
+ }
+ return hash;
+ }
+
+ /**
+ * This escapes the quotes, backslashes, \n, and \r in the string using a
+ * backslash and appends the newly escaped string to a StringBuffer.
+ */
+ private static void escapeString(String str, StringBuffer output) {
+ int len = str.length();
+ for (int i = 0; i < len; i++) {
+ char c = str.charAt(i);
+ switch (c) {
+ case '"' :
+ case '\\' :
+ output.append('\\');
+ output.append(c);
+ break;
+ case '\r' :
+ output.append("\\r");
+ break;
+ case '\n' :
+ output.append("\\n");
+ break;
+ default :
+ output.append(c);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Takes an encoded character array and decodes it into a new String.
+ */
+ private static String unescapeString(char[] str, int begin, int end) {
+ StringBuffer output = new StringBuffer(end - begin);
+ for (int i = begin; i < end; i++) {
+ char c = str[i];
+ if (c == '\\') {
+ i++;
+ if (i < end) {
+ c = str[i];
+ switch (c) {
+ case '"' :
+ case '\\' :
+ break;
+ case 'r' :
+ c = '\r';
+ break;
+ case 'n' :
+ c = '\n';
+ break;
+ default :
+ c = '\\';
+ i--;
+ break;
+ }
+ }
+ }
+ output.append(c);
+ }
+
+ return output.toString();
+ }
+}
diff --git a/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java b/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java
index 16fd7da..0f91691 100644
--- a/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java
+++ b/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java
@@ -1,89 +1,104 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java,v 1.6 2005/07/14 10:47:13 pkriens Exp $
- *
- * Copyright (c) OSGi Alliance (2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.condpermadmin;
-
-import java.security.AccessControlContext;
-import java.util.Enumeration;
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * This is a framework service that allows ConditionalPermissionInfos to be
- * added to, retrieved from, and removed from the framework.
- *
- * @version $Revision: 1.6 $
- */
-public interface ConditionalPermissionAdmin {
- /**
- * Add a new Conditional Permission Info to the repository.
- *
- * The Conditional Permission Info will be given a unique, never reused name.
- *
- * @param conds the Conditions that need to be satisfied to enable the
- * corresponding Permissions.
- * @param perms the Permissions that are enable when the corresponding
- * Conditions are satisfied.
- * @return the ConditionalPermissionInfo that for the newly added Conditions
- * and Permissions.
- */
- ConditionalPermissionInfo addConditionalPermissionInfo(
- ConditionInfo conds[], PermissionInfo perms[]);
-
- /**
- * Set or create a Conditional Permission Info with conditions and
- * permissions.
- *
- * If the given <code>name</code> is null or not used in the repository
- * yet, a new Conditional Permission Info must be created, otherwise the
- * existing Conditional Permission Info must be reused.
- *
- * @param name the name of this Conditional Permission Info, or
- * <code>null</code>.
- * @param conds the Conditions that need to be satisfied to enable the
- * corresponding Permissions.
- * @param perms the Permissions that are enable when the corresponding
- * Conditions are satisfied.
- * @return the ConditionalPermissionInfo that for the newly added Conditions
- * and Permissions.
- */
- ConditionalPermissionInfo setConditionalPermissionInfo(String name,
- ConditionInfo conds[], PermissionInfo perms[]);
-
- /**
- * Returns the ConditionalPermissionInfos that are currently managed by
- * ConditionalPermissionAdmin. The Enumeration is made up of
- * ConditionalPermissionInfos. Calling ConditionalPermissionInfo.delete()
- * will remove the ConditionalPermissionInfo from
- * ConditionalPermissionAdmin.
- *
- * @return the ConditionalPermissionInfos that are currently managed by
- * ConditionalPermissionAdmin. The Enumeration is made up of
- * ConditionalPermissionInfos.
- */
- Enumeration getConditionalPermissionInfos();
-
- /**
- * Return the the Conditional Permission Info with the given name.
- *
- * @param name the name of the Conditional Permission Info that must be
- * returned
- */
- ConditionalPermissionInfo getConditionalPermissionInfo(String name);
-
- /**
- * Returns the AccessControlContext that corresponds to the given signers.
- *
- * @param signers the signers that will be checked agains
- * BundleSignerCondition.
- * @return an AccessControlContext that has the Permissions associated with
- * the signer.
- */
- AccessControlContext getAccessControlContext(String signers[]);
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java,v 1.12 2006/03/14 01:20:40 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (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.condpermadmin;
+
+import java.security.AccessControlContext;
+import java.util.Enumeration;
+
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+/**
+ * Framework service to administer Conditional Permissions. Conditional
+ * Permissions can be added to, retrieved from, and removed from the framework.
+ *
+ * @version $Revision: 1.12 $
+ */
+public interface ConditionalPermissionAdmin {
+ /**
+ * Create a new Conditional Permission Info.
+ *
+ * The Conditional Permission Info will be given a unique, never reused
+ * name.
+ *
+ * @param conds The Conditions that need to be satisfied to enable the
+ * corresponding Permissions.
+ * @param perms The Permissions that are enable when the corresponding
+ * Conditions are satisfied.
+ * @return The ConditionalPermissionInfo for the specified Conditions and
+ * Permissions.
+ * @throws SecurityException If the caller does not have
+ * <code>AllPermission</code>.
+ */
+ public ConditionalPermissionInfo addConditionalPermissionInfo(
+ ConditionInfo conds[], PermissionInfo perms[]);
+
+ /**
+ * Set or create a Conditional Permission Info with a specified name.
+ *
+ * If the specified name is <code>null</code>, a new Conditional
+ * Permission Info must be created and will be given a unique, never reused
+ * name. If there is currently no Conditional Permission Info with the
+ * specified name, a new Conditional Permission Info must be created with
+ * the specified name. Otherwise, the Conditional Permission Info with the
+ * specified name must be updated with the specified Conditions and
+ * Permissions.
+ *
+ * @param name The name of the Conditional Permission Info, or
+ * <code>null</code>.
+ * @param conds The Conditions that need to be satisfied to enable the
+ * corresponding Permissions.
+ * @param perms The Permissions that are enable when the corresponding
+ * Conditions are satisfied.
+ * @return The ConditionalPermissionInfo that for the specified name,
+ * Conditions and Permissions.
+ * @throws SecurityException If the caller does not have
+ * <code>AllPermission</code>.
+ */
+ public ConditionalPermissionInfo setConditionalPermissionInfo(String name,
+ ConditionInfo conds[], PermissionInfo perms[]);
+
+ /**
+ * Returns the Conditional Permission Infos that are currently managed by
+ * Conditional Permission Admin. Calling
+ * {@link ConditionalPermissionInfo#delete()} will remove the Conditional
+ * Permission Info from Conditional Permission Admin.
+ *
+ * @return An enumeration of the Conditional Permission Infos that are
+ * currently managed by Conditional Permission Admin.
+ */
+ public Enumeration getConditionalPermissionInfos();
+
+ /**
+ * Return the Conditional Permission Info with the specified name.
+ *
+ * @param name The name of the Conditional Permission Info to be returned.
+ * @return The Conditional Permission Info with the specified name.
+ */
+ public ConditionalPermissionInfo getConditionalPermissionInfo(String name);
+
+ /**
+ * Returns the Access Control Context that corresponds to the specified
+ * signers.
+ *
+ * @param signers The signers for which to return an Access Control Context.
+ * @return An <code>AccessControlContext</code> that has the Permissions
+ * associated with the signer.
+ */
+ public AccessControlContext getAccessControlContext(String[] signers);
+}
diff --git a/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java b/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java
index c39e4f5..4e99c67 100644
--- a/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java
+++ b/org.osgi/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java
@@ -1,45 +1,63 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java,v 1.7 2005/07/14 10:47:13 pkriens Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.condpermadmin;
-
-import org.osgi.service.permissionadmin.PermissionInfo;
-
-/**
- * This interface describes a binding of a set of Conditions to a set of
- * Permissions. Instances of this interface are obtained from the
- * ConditionalPermissionAdmin service. This interface is also used to remove
- * ConditionalPermissionCollections from ConditionPermissionAdmin.
- */
-public interface ConditionalPermissionInfo {
- /**
- * Returns the ConditionInfos for the Conditions that must be satisfied to
- * enable this ConditionalPermissionCollection.
- */
- ConditionInfo[] getConditionInfos();
-
- /**
- * Returns the PermissionInfos for the Permission in this
- * ConditionalPermissionCollection.
- */
- PermissionInfo[] getPermissionInfos();
-
- /**
- * Removes the ConditionalPermissionCollection from the
- * ConditionalPermissionAdmin.
- */
- void delete();
-
- /**
- * Return the name of this Conditional Permission Info object.
- *
- */
- String getName();
-}
+/*
+ * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java,v 1.10 2006/03/14 01:20:40 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.condpermadmin;
+
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+/**
+ * A binding of a set of Conditions to a set of Permissions. Instances of this
+ * interface are obtained from the Conditional Permission Admin service.
+ *
+ * @version $Revision: 1.10 $
+ */
+public interface ConditionalPermissionInfo {
+ /**
+ * Returns the Condition Infos for the Conditions that must be satisfied to
+ * enable the Permissions.
+ *
+ * @return The Condition Infos for the Conditions in this Conditional
+ * Permission Info.
+ */
+ public ConditionInfo[] getConditionInfos();
+
+ /**
+ * Returns the Permission Infos for the Permission in this Conditional
+ * Permission Info.
+ *
+ * @return The Permission Infos for the Permission in this Conditional
+ * Permission Info.
+ */
+ public PermissionInfo[] getPermissionInfos();
+
+ /**
+ * Removes this Conditional Permission Info from the Conditional Permission
+ * Admin.
+ *
+ * @throws SecurityException If the caller does not have
+ * <code>AllPermission</code>.
+ */
+ public void delete();
+
+ /**
+ * Returns the name of this Conditional Permission Info.
+ *
+ * @return The name of this Conditional Permission Info.
+ */
+ public String getName();
+}
diff --git a/org.osgi/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java b/org.osgi/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
index ac6f362..94aaa41 100644
--- a/org.osgi/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
+++ b/org.osgi/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
@@ -1,90 +1,111 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.packageadmin/src/org/osgi/service/packageadmin/ExportedPackage.java,v 1.8 2005/05/13 20:32:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.packageadmin;
-
-import org.osgi.framework.Bundle;
-
-/**
- * An exported package.
- *
- * Instances implementing this interface are created by the Package Admin
- * service.
- *
- * <p>
- * The information about an exported package provided by this object is valid
- * only until the next time <code>PackageAdmin.refreshPackages()</code> is called.
- * If an <code>ExportedPackage</code> object becomes stale (that is, the package
- * it references has been updated or removed as a result of calling
- * <code>PackageAdmin.refreshPackages()</code>), its <code>getName()</code> and
- * <code>getSpecificationVersion()</code> continue to return their old values,
- * <code>isRemovalPending()</code> returns <code>true</code>, and
- * <code>getExportingBundle()</code> and <code>getImportingBundles()</code> return
- * <code>null</code>.
- *
- * @version $Revision: 1.8 $
- */
-public interface ExportedPackage {
- /**
- * Returns the name of the package associated with this
- * <code>ExportedPackage</code> object.
- *
- * @return The name of this <code>ExportedPackage</code> object.
- */
- public String getName();
-
- /**
- * Returns the bundle exporting the package associated with this
- * <code>ExportedPackage</code> object.
- *
- * @return The exporting bundle, or <code>null</code> if this
- * <code>ExportedPackage</code> object has become stale.
- */
- public Bundle getExportingBundle();
-
- /**
- * Returns the resolved bundles that are currently importing the package
- * associated with this <code>ExportedPackage</code> object.
- *
- * <p>
- * Bundles which require the exporting bundle associated with this
- * <code>ExportedPackage</code> object are considered to be importing bundles
- * and are included in the returned array. See
- * {@link RequiredBundle#getRequiringBundles()}
- *
- * @return The array of resolved bundles currently importing the package
- * associated with this <code>ExportedPackage</code> object, or
- * <code>null</code> if this <code>ExportedPackage</code> object has
- * become stale.
- */
- public Bundle[] getImportingBundles();
-
- /**
- * Returns the specification version of this <code>ExportedPackage</code>, as
- * specified in the exporting bundle's manifest file.
- *
- * @return The specification version of this <code>ExportedPackage</code>
- * object, or <code>null</code> if no version information is
- * available.
- */
- public String getSpecificationVersion();
-
- /**
- * Returns <code>true</code> if the package associated with this
- * <code>ExportedPackage</code> object has been exported by a bundle that has
- * been updated or uninstalled.
- *
- * @return <code>true</code> if the associated package is being exported by a
- * bundle that has been updated or uninstalled, or if this
- * <code>ExportedPackage</code> object has become stale;
- * <code>false</code> otherwise.
- */
- public boolean isRemovalPending();
+/*
+ * $Header: /cvshome/build/org.osgi.service.packageadmin/src/org/osgi/service/packageadmin/ExportedPackage.java,v 1.12 2006/03/14 01:20:05 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.packageadmin;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * An exported package.
+ *
+ * Objects implementing this interface are created by the Package Admin service.
+ *
+ * <p>
+ * The term <i>exported package</i> refers to a package that has been exported
+ * from a resolved bundle. This package may or may not be currently wired to
+ * other bundles.
+ *
+ * <p>
+ * The information about an exported package provided by this object may change.
+ * An <code>ExportedPackage</code> object becomes stale if the package it
+ * references has been updated or removed as a result of calling
+ * <code>PackageAdmin.refreshPackages()</code>.
+ *
+ * If this object becomes stale, its <code>getName()</code> and
+ * <code>getVersion()</code> methods continue to return their original values,
+ * <code>isRemovalPending()</code> returns <code>true</code>, and
+ * <code>getExportingBundle()</code> and <code>getImportingBundles()</code>
+ * return <code>null</code>.
+ *
+ * @version $Revision: 1.12 $
+ */
+public interface ExportedPackage {
+ /**
+ * Returns the name of the package associated with this exported package.
+ *
+ * @return The name of this exported package.
+ */
+ public String getName();
+
+ /**
+ * Returns the bundle exporting the package associated with this exported
+ * package.
+ *
+ * @return The exporting bundle, or <code>null</code> if this
+ * <code>ExportedPackage</code> object has become stale.
+ */
+ public Bundle getExportingBundle();
+
+ /**
+ * Returns the resolved bundles that are currently wired to this exported
+ * package.
+ *
+ * <p>
+ * Bundles which require the exporting bundle associated with this exported
+ * package are considered to be wired to this exported package are included
+ * in the returned array. See {@link RequiredBundle#getRequiringBundles()}.
+ *
+ * @return The array of resolved bundles currently wired to this exported
+ * package, or <code>null</code> if this
+ * <code>ExportedPackage</code> object has become stale.
+ */
+ public Bundle[] getImportingBundles();
+
+ /**
+ * Returns the version of this exported package.
+ *
+ * @return The version of this exported package, or <code>null</code> if
+ * no version information is available.
+ * @deprecated Since 1.2. This method has been replaced by
+ * {@link #getVersion}.
+ */
+ public String getSpecificationVersion();
+
+ /**
+ * Returns the version of this exported package.
+ *
+ * @return The version of this exported package, or
+ * {@link Version#emptyVersion} if no version information is
+ * available.
+ * @since 1.2
+ */
+ public Version getVersion();
+
+ /**
+ * Returns <code>true</code> if the package associated with this
+ * <code>ExportedPackage</code> object has been exported by a bundle that
+ * has been updated or uninstalled.
+ *
+ * @return <code>true</code> if the associated package is being exported
+ * by a bundle that has been updated or uninstalled, or if this
+ * <code>ExportedPackage</code> object has become stale;
+ * <code>false</code> otherwise.
+ */
+ public boolean isRemovalPending();
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java b/org.osgi/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
index 6c5307c..56274ba 100644
--- a/org.osgi/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
+++ b/org.osgi/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
@@ -1,289 +1,278 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.packageadmin/src/org/osgi/service/packageadmin/PackageAdmin.java,v 1.10 2005/05/13 20:32:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.packageadmin;
-
-import org.osgi.framework.Bundle;
-
-/**
- * Framework service which allows bundle programmers to inspect the packages
- * exported in the Framework and eagerly update or uninstall bundles.
- *
- * If present, there will only be a single instance of this service registered
- * with the Framework.
- *
- * <p>
- * The term <i>exported package </i> (and the corresponding interface
- * {@link ExportedPackage})refers to a package that has actually been exported
- * (as opposed to one that is available for export).
- *
- * <p>
- * The information about exported packages returned by this service is valid
- * only until the next time {@link #refreshPackages}is called. If an
- * <code>ExportedPackage</code> object becomes stale, (that is, the package it
- * references has been updated or removed as a result of calling
- * <code>PackageAdmin.refreshPackages()</code>), its <code>getName()</code> and
- * <code>getSpecificationVersion()</code> continue to return their old values,
- * <code>isRemovalPending()</code> returns <code>true</code>, and
- * <code>getExportingBundle()</code> and <code>getImportingBundles()</code> return
- * <code>null</code>.
- *
- * @version $Revision: 1.10 $
- */
-public interface PackageAdmin {
- /**
- * Gets the packages exported by the specified bundle.
- *
- * @param bundle The bundle whose exported packages are to be returned, or
- * <code>null</code> if all the packages currently exported in the
- * Framework are to be returned. If the specified bundle is the
- * system bundle (that is, the bundle with id zero), this method
- * returns all the packages on the system classpath whose name does
- * not start with "java.". In an environment where the exhaustive
- * list of packages on the system classpath is not known in advance,
- * this method will return all currently known packages on the system
- * classpath, that is, all packages on the system classpath that
- * contains one or more classes that have been loaded.
- *
- * @return The array of packages exported by the specified bundle, or
- * <code>null</code> if the specified bundle has not exported any
- * packages.
- */
- public ExportedPackage[] getExportedPackages(Bundle bundle);
-
- /**
- * Gets the <code>ExportedPackage</code> object with the specified package
- * name. All exported packages will be checked for the specified name. The
- * exported package with the highest version will be returned.
- * <p>
- * In an environment where the exhaustive list of packages on the system
- * classpath is not known in advance, this method attempts to see if the
- * named package is on the system classpath. This means that this method may
- * discover an <code>ExportedPackage</code> object that was not present in the
- * list returned by a prior call to <code>getExportedPackages()</code>.
- *
- * @param name The name of the exported package to be returned.
- *
- * @return The exported package with the specified name, or <code>null</code>
- * if no exported packages with that name exists.
- */
- public ExportedPackage getExportedPackage(String name);
-
- /**
- * Forces the update (replacement) or removal of packages exported by the
- * specified bundles.
- *
- * <p>
- * If no bundles are specified, this method will update or remove any
- * packages exported by any bundles that were previously updated or
- * uninstalled since the last call to this method. The technique by which
- * this is accomplished may vary among different Framework implementations.
- * One permissible implementation is to stop and restart the Framework.
- *
- * <p>
- * This method returns to the caller immediately and then performs the
- * following steps in its own thread:
- *
- * <ol>
- * <li>Compute a graph of bundles starting with the specified bundles. If
- * no bundles are specified, compute a graph of bundles starting with
- * previously updated or uninstalled ones. Add to the graph any bundle that
- * imports a package that is currently exported by a bundle in the graph.
- * The graph is fully constructed when there is no bundle outside the graph
- * that imports a package from a bundle in the graph. The graph may contain
- * <code>UNINSTALLED</code> bundles that are currently still exporting
- * packages.
- *
- * <li>Each bundle in the graph that is in the <code>ACTIVE</code> state will
- * be stopped as described in the <code>Bundle.stop</code> method.
- *
- * <li>Each bundle in the graph that is in the <code>RESOLVED</code> state is
- * moved to the <code>INSTALLED</code> state. The effect of this step is that
- * bundles in the graph are no longer <code>RESOLVED</code>.
- *
- * <li>Each bundle in the graph that is in the <code>UNINSTALLED</code> state
- * is removed from the graph and is now completely removed from the
- * Framework.
- *
- * <li>Each bundle in the graph that was in the <code>ACTIVE</code> state
- * prior to Step 2 is started as described in the <code>Bundle.start</code>
- * method, causing all bundles required for the restart to be resolved. It
- * is possible that, as a result of the previous steps, packages that were
- * previously exported no longer are. Therefore, some bundles may be
- * unresolvable until another bundle offering a compatible package for
- * export has been installed in the Framework.
- * <li>A framework event of type <code>FrameworkEvent.PACKAGES_REFRESHED</code>
- * is broadcast.
- * </ol>
- *
- * <p>
- * For any exceptions that are thrown during any of these steps, a
- * <code>FrameworkEvent</code> of type <code>ERROR</code> is broadcast,
- * containing the exception. The source bundle for these events should be
- * the specific bundle to which the exception is related. If no specific
- * bundle can be associated with the exception then the System Bundle must
- * be used as the source bundle for the event.
- *
- * @param bundles the bundles whose exported packages are to be updated or
- * removed, or <code>null</code> for all previously updated or
- * uninstalled bundles.
- *
- * @exception SecurityException if the caller does not have the
- * <code>AdminPermission</code> and the Java runtime environment
- * supports permissions.
- */
- public void refreshPackages(Bundle[] bundles);
-
- /**
- * Get the <code>ExportedPackage</code> objects with the specified
- * package name. All exported packages will be checked for the specified
- * name.
- * <p>
- * In an environment where the exhaustive list of packages on the system
- * classpath is not known in advance, this method attempts to see if the
- * named package is on the system classpath. This means that this method may
- * discover an <code>ExportedPackage</code> object that was not present in the
- * list returned by a prior call to <code>getExportedPackages()</code>.
- *
- * @param name The name of the exported packages to be returned.
- *
- * @return An array of the exported packages with the specified name, or
- * <code>null</code> if no exported packages with that name exists.
- * @since 1.2
- */
- public ExportedPackage[] getExportedPackages(String name);
-
- /**
- * Resolve the specified bundles. The Framework must attempt to resolve the
- * specified bundles that are unresolved. Additional bundles that are not
- * included in the specified bundles may be resolved as a result of calling
- * this method. A permissible implementation of this method is to attempt to
- * resolve all unresolved bundles installed in the framework.
- *
- * <p>
- * If <code>null</code> is specified then the Framework will attempt to
- * resolve all unresolved bundles. This method must not cause any bundle to
- * be refreshed, stopped, or started. This method will not return until the
- * operation has completed.
- *
- * @param bundles The bundles to resolve or <code>null</code> to resolve all
- * unresolved bundles installed in the Framework.
- * @return <code>true</code> if all specified bundles are resolved;
- * @since 1.2
- */
- public boolean resolveBundles(Bundle[] bundles);
-
- /**
- * Returns an array of RequiredBundles with the specified symbolic name. If
- * the symbolic name argument is <code>null</code> then all RequiredBundles
- * are returned.
- *
- * @param symbolicName The symbolic name of the RequiredBundle or
- * <code>null</code> for all RequiredBundles in the Framework.
- * @return An array of RequiredBundles with the specified symbolic name or
- * <code>null</code> if no RequiredBundles exist with that symbolic
- * name.
- * @since 1.2
- */
- public RequiredBundle[] getRequiredBundles(String symbolicName);
-
- /**
- * Returns the bundles with the specified symbolic name within the specified
- * version range. If no bundles are installed that have the specified
- * symbolic name, then <code>null</code> is returned. If a version range is
- * specified, then only the bundles that have the specified symbolic name
- * and belong to the specified version range are returned. The returned
- * bundles are ordered by version in descending version order so that the
- * first element of the array contains the bundle with the highest version.
- *
- * @see org.osgi.framework.Constants#BUNDLE_VERSION_ATTRIBUTE
- * @param symbolicName The symbolic name of the desired bundles.
- * @param versionRange The version range of the desired bundles, or
- * <code>null</code> if all versions are desired.
- * @return An array of bundles with the specified name belonging to the
- * specified version range ordered in descending version order, or
- * <code>null</code> if no bundles are found.
- * @since 1.2
- */
- public Bundle[] getBundles(String symbolicName, String versionRange);
-
- /**
- * Returns an array of attached fragment bundles for the specified bundle.
- * If the specified bundle is a fragment then <code>null</code> is returned.
- * If no fragments are attached to the specified bundle then <code>null</code>
- * is returned.
- * <p>
- * This method does not attempt to resolve the specified bundle. If the
- * specified bundle is not resolved then <code>null</code> is returned.
- *
- * @param bundle The bundle whose attached fragment bundles are to be
- * returned.
- * @return An array of fragment bundles or <code>null</code> if the bundle
- * does not have any attached fragment bundles or the bundle is not
- * resolved.
- * @since 1.2
- */
- public Bundle[] getFragments(Bundle bundle);
-
- /**
- * Returns an array of host bundles to which the specified fragment bundle
- * is attached or <code>null</code> if the specified bundle is not attached to
- * a host or is not a fragment bundle.
- *
- * @param bundle The bundle whose host bundles are to be returned.
- * @return An array of host bundles or <code>null</code> if the bundle does
- * not have any host bundles.
- * @since 1.2
- */
- public Bundle[] getHosts(Bundle bundle);
-
- /**
- * Returns the bundle for which the specified class is loaded from. The
- * classloader of the bundle returned must have been used to load the
- * specified class. If the class was not loaded by a bundle classloader then
- * <code>null</code> is returned.
- *
- * @param clazz the class object to get a bundle for
- * @return the bundle from which the specified class is loaded or
- * <code>null</code> if the class was not loaded by a bundle
- * classloader
- * @since 1.2
- */
- public Bundle getBundle(Class clazz);
-
- /**
- * The bundle is a fragment bundle.
- *
- * <p>
- * The value of <code>BUNDLE_TYPE_FRAGMENT</code> is 0x00000001.
- *
- * @since 1.2
- */
- public static final int BUNDLE_TYPE_FRAGMENT = 0x00000001;
-
- /**
- * Returns the special type of the specified bundle. The bundle type values
- * are:
- * <ul>
- * <li>{@link #BUNDLE_TYPE_FRAGMENT}
- * </ul>
- *
- * A bundle may be more than one type at a time. A type code is used to
- * identify the bundle type for future extendability.
- *
- * <p>
- * If a bundle is not one or more of the defined types then 0x00000000 is
- * returned.
- *
- * @return The special type of the bundle.
- * @since 1.2
- */
- public int getBundleType(Bundle bundle);
+/*
+ * $Header: /cvshome/build/org.osgi.service.packageadmin/src/org/osgi/service/packageadmin/PackageAdmin.java,v 1.18 2006/03/14 01:20:05 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.packageadmin;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Framework service which allows bundle programmers to inspect the package
+ * wiring state of bundles in the Framework as well as other functions related
+ * to the class loader network among bundles.
+ *
+ * <p>
+ * If present, there will only be a single instance of this service registered
+ * with the Framework.
+ *
+ * @version $Revision: 1.18 $
+ * @see org.osgi.service.packageadmin.ExportedPackage
+ * @see org.osgi.service.packageadmin.RequiredBundle
+ */
+public interface PackageAdmin {
+ /**
+ * Gets the exported packages for the specified bundle.
+ *
+ * @param bundle The bundle whose exported packages are to be returned, or
+ * <code>null</code> if all exported packages are to be returned.
+ * If the specified bundle is the system bundle (that is, the bundle
+ * with id zero), this method returns all the packages known to be
+ * exported by the system bundle. This will include the package
+ * specified by the <code>org.osgi.framework.system.packages</code>
+ * system property as well as any other package exported by the
+ * framework implementation.
+ *
+ * @return An array of exported packages, or <code>null</code> if the
+ * specified bundle has no exported packages.
+ */
+ public ExportedPackage[] getExportedPackages(Bundle bundle);
+
+ /**
+ * Gets the exported packages for the specified package name.
+ *
+ * @param name The name of the exported packages to be returned.
+ *
+ * @return An array of the exported packages, or <code>null</code> if no
+ * exported packages with the specified name exists.
+ * @since 1.2
+ */
+ public ExportedPackage[] getExportedPackages(String name);
+
+ /**
+ * Gets the exported package for the specified package name.
+ *
+ * <p>
+ * If there are multiple exported packages with specified name, the exported
+ * package with the highest version will be returned.
+ *
+ * @param name The name of the exported package to be returned.
+ *
+ * @return The exported package, or <code>null</code> if no exported
+ * package with the specified name exists.
+ * @see #getExportedPackages(String)
+ */
+ public ExportedPackage getExportedPackage(String name);
+
+ /**
+ * Forces the update (replacement) or removal of packages exported by the
+ * specified bundles.
+ *
+ * <p>
+ * If no bundles are specified, this method will update or remove any
+ * packages exported by any bundles that were previously updated or
+ * uninstalled since the last call to this method. The technique by which
+ * this is accomplished may vary among different Framework implementations.
+ * One permissible implementation is to stop and restart the Framework.
+ *
+ * <p>
+ * This method returns to the caller immediately and then performs the
+ * following steps on a separate thread:
+ *
+ * <ol>
+ * <li>Compute a graph of bundles starting with the specified bundles. If
+ * no bundles are specified, compute a graph of bundles starting with bundle
+ * updated or uninstalled since the last call to this method. Add to the
+ * graph any bundle that is wired to a package that is currently exported by
+ * a bundle in the graph. The graph is fully constructed when there is no
+ * bundle outside the graph that is wired to a bundle in the graph. The
+ * graph may contain <code>UNINSTALLED</code> bundles that are currently
+ * still exporting packages.
+ *
+ * <li>Each bundle in the graph that is in the <code>ACTIVE</code> state
+ * will be stopped as described in the <code>Bundle.stop</code> method.
+ *
+ * <li>Each bundle in the graph that is in the <code>RESOLVED</code>
+ * state is unresolved and thus moved to the <code>INSTALLED</code> state.
+ * The effect of this step is that bundles in the graph are no longer
+ * <code>RESOLVED</code>.
+ *
+ * <li>Each bundle in the graph that is in the <code>UNINSTALLED</code>
+ * state is removed from the graph and is now completely removed from the
+ * Framework.
+ *
+ * <li>Each bundle in the graph that was in the <code>ACTIVE</code> state
+ * prior to Step 2 is started as described in the <code>Bundle.start</code>
+ * method, causing all bundles required for the restart to be resolved. It
+ * is possible that, as a result of the previous steps, packages that were
+ * previously exported no longer are. Therefore, some bundles may be
+ * unresolvable until another bundle offering a compatible package for
+ * export has been installed in the Framework.
+ * <li>A framework event of type
+ * <code>FrameworkEvent.PACKAGES_REFRESHED</code> is fired.
+ * </ol>
+ *
+ * <p>
+ * For any exceptions that are thrown during any of these steps, a
+ * <code>FrameworkEvent</code> of type <code>ERROR</code> is fired
+ * containing the exception. The source bundle for these events should be
+ * the specific bundle to which the exception is related. If no specific
+ * bundle can be associated with the exception then the System Bundle must
+ * be used as the source bundle for the event.
+ *
+ * @param bundles The bundles whose exported packages are to be updated or
+ * removed, or <code>null</code> for all bundles updated or
+ * uninstalled since the last call to this method.
+ * @throws SecurityException If the caller does not have
+ * <code>AdminPermission[System Bundle,RESOLVE]</code> and the
+ * Java runtime environment supports permissions.
+ */
+ public void refreshPackages(Bundle[] bundles);
+
+ /**
+ * Resolve the specified bundles. The Framework must attempt to resolve the
+ * specified bundles that are unresolved. Additional bundles that are not
+ * included in the specified bundles may be resolved as a result of calling
+ * this method. A permissible implementation of this method is to attempt to
+ * resolve all unresolved bundles installed in the framework.
+ *
+ * <p>
+ * If <code>null</code> is specified then the Framework will attempt to
+ * resolve all unresolved bundles. This method must not cause any bundle to
+ * be refreshed, stopped, or started. This method will not return until the
+ * operation has completed.
+ *
+ * @param bundles The bundles to resolve or <code>null</code> to resolve
+ * all unresolved bundles installed in the Framework.
+ * @return <code>true</code> if all specified bundles are resolved;
+ * @throws SecurityException If the caller does not have
+ * <code>AdminPermission[System Bundle,RESOLVE]</code> and the
+ * Java runtime environment supports permissions.
+ * @since 1.2
+ */
+ public boolean resolveBundles(Bundle[] bundles);
+
+ /**
+ * Returns an array of required bundles having the specified symbolic name.
+ *
+ * <p>
+ * If <code>null</code> is specified, then all required bundles will be
+ * returned.
+ *
+ * @param symbolicName The bundle symbolic name or <code>null</code> for
+ * all required bundles.
+ * @return An array of required bundles or <code>null</code> if no
+ * required bundles exist for the specified symbolic name.
+ * @since 1.2
+ */
+ public RequiredBundle[] getRequiredBundles(String symbolicName);
+
+ /**
+ * Returns the bundles with the specified symbolic name whose bundle version
+ * is within the specified version range. If no bundles are installed that
+ * have the specified symbolic name, then <code>null</code> is returned.
+ * If a version range is specified, then only the bundles that have the
+ * specified symbolic name and whose bundle versions belong to the specified
+ * version range are returned. The returned bundles are ordered by version
+ * in descending version order so that the first element of the array
+ * contains the bundle with the highest version.
+ *
+ * @see org.osgi.framework.Constants#BUNDLE_VERSION_ATTRIBUTE
+ * @param symbolicName The symbolic name of the desired bundles.
+ * @param versionRange The version range of the desired bundles, or
+ * <code>null</code> if all versions are desired.
+ * @return An array of bundles with the specified name belonging to the
+ * specified version range ordered in descending version order, or
+ * <code>null</code> if no bundles are found.
+ * @since 1.2
+ */
+ public Bundle[] getBundles(String symbolicName, String versionRange);
+
+ /**
+ * Returns an array of attached fragment bundles for the specified bundle.
+ * If the specified bundle is a fragment then <code>null</code> is
+ * returned. If no fragments are attached to the specified bundle then
+ * <code>null</code> is returned.
+ * <p>
+ * This method does not attempt to resolve the specified bundle. If the
+ * specified bundle is not resolved then <code>null</code> is returned.
+ *
+ * @param bundle The bundle whose attached fragment bundles are to be
+ * returned.
+ * @return An array of fragment bundles or <code>null</code> if the bundle
+ * does not have any attached fragment bundles or the bundle is not
+ * resolved.
+ * @since 1.2
+ */
+ public Bundle[] getFragments(Bundle bundle);
+
+ /**
+ * Returns an array containing the host bundle to which the specified
+ * fragment bundle is attached or <code>null</code> if the specified
+ * bundle is not attached to a host or is not a fragment bundle. A fragment
+ * may only be attached to a single host bundle.
+ *
+ * @param bundle The bundle whose host bundle is to be returned.
+ * @return An array containing the host bundle or <code>null</code> if the
+ * bundle does not have a host bundle.
+ * @since 1.2
+ */
+ public Bundle[] getHosts(Bundle bundle);
+
+ /**
+ * Returns the bundle from which the specified class is loaded. The class
+ * loader of the returned bundle must have been used to load the specified
+ * class. If the class was not loaded by a bundle class loader then
+ * <code>null</code> is returned.
+ *
+ * @param clazz The class object from which to locate the bundle.
+ * @return The bundle from which the specified class is loaded or
+ * <code>null</code> if the class was not loaded by a bundle class
+ * loader.
+ * @since 1.2
+ */
+ public Bundle getBundle(Class clazz);
+
+ /**
+ * Bundle type indicating the bundle is a fragment bundle.
+ *
+ * <p>
+ * The value of <code>BUNDLE_TYPE_FRAGMENT</code> is 0x00000001.
+ *
+ * @since 1.2
+ */
+ public static final int BUNDLE_TYPE_FRAGMENT = 0x00000001;
+
+ /**
+ * Returns the special type of the specified bundle. The bundle type values
+ * are:
+ * <ul>
+ * <li>{@link #BUNDLE_TYPE_FRAGMENT}
+ * </ul>
+ *
+ * A bundle may be more than one type at a time. A type code is used to
+ * identify the bundle type for future extendability.
+ *
+ * <p>
+ * If a bundle is not one or more of the defined types then 0x00000000 is
+ * returned.
+ *
+ * @param bundle The bundle for which to return the special type.
+ * @return The special type of the bundle.
+ * @since 1.2
+ */
+ public int getBundleType(Bundle bundle);
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java b/org.osgi/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
index 0da07c4..907628b 100644
--- a/org.osgi/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
+++ b/org.osgi/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
@@ -1,77 +1,97 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.packageadmin/src/org/osgi/service/packageadmin/RequiredBundle.java,v 1.5 2005/05/13 20:32:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.packageadmin;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
-
-/**
- * A required bundle.
- *
- * Instances implementing this interface are created by the Package Admin
- * service.
- *
- * <p>
- * The information about a <code>RequiredBundle</code> provided by this object is
- * valid only until the next time <code>PackageAdmin.refreshPackages()</code>
- * called. If a <code>RequiredBundle</code> object becomes stale (that is, the
- * bundle it references has been updated or removed as a result of calling
- * <code>PackageAdmin.refreshPackages()</code>), its <code>getSymbolicName()</code>
- * and <code>getVersion()</code> continue to return their old values,
- * <code>isRemovalPending()</code> returns true, and <code>getBundle()</code> and
- * <code>getRequiringBundles()</code> return <code>null</code>.
- *
- * @since 1.2
- */
-public interface RequiredBundle {
- /**
- * Returns the bundle which defines this RequiredBundle.
- *
- * @return The bundle, or <code>null</code> if this <code>RequiredBundle</code>
- * object has become stale.
- */
- public Bundle getBundle();
-
- /**
- * Returns the resolved bundles that currently require this bundle. If this
- * <code>RequiredBundle</code> object is required and re-exported by another
- * bundle then all the requiring bundles of the re-exporting bundle are
- * included in the returned array.
- *
- * @return An array of resolved bundles currently requiring this bundle, or
- * <code>null</code> if this <code>RequiredBundle</code> object has
- * become stale.
- */
- public Bundle[] getRequiringBundles();
-
- /**
- * Returns the symbolic name of the bundle.
- *
- * @return The symbolic name of the bundle.
- */
- public String getSymbolicName();
-
- /**
- * Returns the version of the bundle.
- *
- * @return The version of the bundle.
- */
- public Version getVersion();
-
- /**
- * Returns <code>true</code> if the bundle has been updated or uninstalled.
- *
- * @return <code>true</code> if the bundle has been updated or uninstalled, or
- * if the <code>RequiredBundle</code> object has become stale;
- * <code>false</code> otherwise.
- */
- public boolean isRemovalPending();
+/*
+ * $Header: /cvshome/build/org.osgi.service.packageadmin/src/org/osgi/service/packageadmin/RequiredBundle.java,v 1.10 2006/03/14 21:02:47 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2004, 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.packageadmin;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * A required bundle.
+ *
+ * Objects implementing this interface are created by the Package Admin service.
+ *
+ * <p>
+ * The term <i>required bundle</i> refers to a resolved bundle that has a
+ * bundle symbolic name and is not a fragment. That is, a bundle that may be
+ * required by other bundles. This bundle may or may not be currently required
+ * by other bundles.
+ *
+ * <p>
+ * The information about a required bundle provided by this object may change. A
+ * <code>RequiredBundle</code> object becomes stale if an exported package of
+ * the bundle it references has been updated or removed as a result of calling
+ * <code>PackageAdmin.refreshPackages()</code>).
+ *
+ * If this object becomes stale, its <code>getSymbolicName()</code> and
+ * <code>getVersion()</code> methods continue to return their original values,
+ * <code>isRemovalPending()</code> returns true, and <code>getBundle()</code>
+ * and <code>getRequiringBundles()</code> return <code>null</code>.
+ *
+ * @since 1.2
+ * @version $Revision: 1.10 $
+ */
+public interface RequiredBundle {
+ /**
+ * Returns the symbolic name of this required bundle.
+ *
+ * @return The symbolic name of this required bundle.
+ */
+ public String getSymbolicName();
+
+ /**
+ * Returns the bundle associated with this required bundle.
+ *
+ * @return The bundle, or <code>null</code> if this
+ * <code>RequiredBundle</code> object has become stale.
+ */
+ public Bundle getBundle();
+
+ /**
+ * Returns the bundles that currently require this required bundle.
+ *
+ * <p>
+ * If this required bundle is required and then re-exported by another
+ * bundle then all the requiring bundles of the re-exporting bundle are
+ * included in the returned array.
+ *
+ * @return An array of bundles currently requiring this required bundle, or
+ * <code>null</code> if this <code>RequiredBundle</code> object
+ * has become stale.
+ */
+ public Bundle[] getRequiringBundles();
+
+ /**
+ * Returns the version of this required bundle.
+ *
+ * @return The version of this required bundle, or
+ * {@link Version#emptyVersion} if no version information is
+ * available.
+ */
+ public Version getVersion();
+
+ /**
+ * Returns <code>true</code> if the bundle associated with this
+ * <code>RequiredBundle</code> object has been updated or uninstalled.
+ *
+ * @return <code>true</code> if the reqiured bundle has been updated or
+ * uninstalled, or if the <code>RequiredBundle</code> object has
+ * become stale; <code>false</code> otherwise.
+ */
+ public boolean isRemovalPending();
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/startlevel/StartLevel.java b/org.osgi/src/main/java/org/osgi/service/startlevel/StartLevel.java
index e2421cd..03ee76f 100644
--- a/org.osgi/src/main/java/org/osgi/service/startlevel/StartLevel.java
+++ b/org.osgi/src/main/java/org/osgi/service/startlevel/StartLevel.java
@@ -1,228 +1,238 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.startlevel/src/org/osgi/service/startlevel/StartLevel.java,v 1.6 2005/05/13 20:34:03 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.startlevel;
-
-import org.osgi.framework.Bundle;
-
-/**
- * The StartLevel service allows management agents to manage a start level
- * assigned to each bundle and the active start level of the Framework. There is
- * at most one StartLevel service present in the OSGi environment.
- *
- * <p>
- * A start level is defined to be a state of execution in which the Framework
- * exists. StartLevel values are defined as unsigned integers with 0 (zero)
- * being the state where the Framework is not launched. Progressively higher
- * integral values represent progressively higher start levels. e.g. 2 is a
- * higher start level than 1.
- * <p>
- * Access to the StartLevel service is protected by corresponding
- * <code>ServicePermission</code>. In addition the <code>AdminPermission</code>
- * that is required to actually modify start level information.
- * <p>
- * Start Level support in the Framework includes the ability to control the
- * beginning start level of the Framework, to modify the active start level of
- * the Framework and to assign a specific start level to a bundle. How the
- * beginning start level of a Framework is specified is implementation
- * dependent. It may be a command line argument when invoking the Framework
- * implementation.
- * <p>
- * When the Framework is first started it must be at start level zero. In this
- * state, no bundles are running. This is the initial state of the Framework
- * before it is launched.
- *
- * When the Framework is launched, the Framework will enter start level one and
- * all bundles which are assigned to start level one and are persistently marked
- * to be started are started as described in the <code>Bundle.start</code> method.
- * Within a start level, bundles are started in ascending order by
- * <code>Bundle.getBundleId</code>. The Framework will continue to increase the
- * start level, starting bundles at each start level, until the Framework has
- * reached a beginning start level. At this point the Framework has completed
- * starting bundles and will then broadcast a Framework event of type
- * <code>FrameworkEvent.STARTED</code> to announce it has completed its launch.
- *
- * <p>
- * The StartLevel service can be used by management bundles to alter the active
- * start level of the framework.
- *
- * @version $Revision: 1.6 $
- */
-public interface StartLevel {
- /**
- * Return the active start level value of the Framework.
- *
- * If the Framework is in the process of changing the start level this
- * method must return the active start level if this differs from the
- * requested start level.
- *
- * @return The active start level value of the Framework.
- */
- public abstract int getStartLevel();
-
- /**
- * Modify the active start level of the Framework.
- *
- * <p>
- * The Framework will move to the requested start level. This method will
- * return immediately to the caller and the start level change will occur
- * asynchronously on another thread.
- *
- * <p>
- * If the specified start level is higher than the active start level, the
- * Framework will continue to increase the start level until the Framework
- * has reached the specified start level, starting bundles at each start
- * level which are persistently marked to be started as described in the
- * <code>Bundle.start</code> method.
- *
- * At each intermediate start level value on the way to and including the
- * target start level, the framework must:
- * <ol>
- * <li>Change the active start level to the intermediate start level value.
- * <li>Start bundles at the intermediate start level in ascending order by
- * <code>Bundle.getBundleId</code>.
- * </ol>
- * When this process completes after the specified start level is reached,
- * the Framework will broadcast a Framework event of type
- * <code>FrameworkEvent.STARTLEVEL_CHANGED</code> to announce it has moved to
- * the specified start level.
- *
- * <p>
- * If the specified start level is lower than the active start level, the
- * Framework will continue to decrease the start level until the Framework
- * has reached the specified start level stopping bundles at each start
- * level as described in the <code>Bundle.stop</code> method except that their
- * persistently recorded state indicates that they must be restarted in the
- * future.
- *
- * At each intermediate start level value on the way to and including the
- * specified start level, the framework must:
- * <ol>
- * <li>Stop bundles at the intermediate start level in descending order by
- * <code>Bundle.getBundleId</code>.
- * <li>Change the active start level to the intermediate start level value.
- * </ol>
- * When this process completes after the specified start level is reached,
- * the Framework will broadcast a Framework event of type
- * <code>FrameworkEvent.STARTLEVEL_CHANGED</code> to announce it has moved to
- * the specified start level.
- *
- * <p>
- * If the specified start level is equal to the active start level, then no
- * bundles are started or stopped, however, the Framework must broadcast a
- * Framework event of type <code>FrameworkEvent.STARTLEVEL_CHANGED</code> to
- * announce it has finished moving to the specified start level. This event
- * may arrive before the this method return.
- *
- * @param startlevel The requested start level for the Framework.
- * @throws IllegalArgumentException If the specified start level is less
- * than or equal to zero.
- * @throws SecurityException If the caller does not have the
- * <code>AdminPermission</code> and the Java runtime environment
- * supports permissions.
- */
- public abstract void setStartLevel(int startlevel);
-
- /**
- * Return the assigned start level value for the specified Bundle.
- *
- * @param bundle The target bundle.
- * @return The start level value of the specified Bundle.
- * @exception java.lang.IllegalArgumentException If the specified bundle has
- * been uninstalled.
- */
- public abstract int getBundleStartLevel(Bundle bundle);
-
- /**
- * Assign a start level value to the specified Bundle.
- *
- * <p>
- * The specified bundle will be assigned the specified start level. The
- * start level value assigned to the bundle will be persistently recorded by
- * the Framework.
- *
- * If the new start level for the bundle is lower than or equal to the
- * active start level of the Framework, the Framework will start the
- * specified bundle as described in the <code>Bundle.start</code> method if
- * the bundle is persistently marked to be started. The actual starting of
- * this bundle must occur asynchronously.
- *
- * If the new start level for the bundle is higher than the active start
- * level of the Framework, the Framework will stop the specified bundle as
- * described in the <code>Bundle.stop</code> method except that the
- * persistently recorded state for the bundle indicates that the bundle must
- * be restarted in the future. The actual stopping of this bundle must occur
- * asynchronously.
- *
- * @param bundle The target bundle.
- * @param startlevel The new start level for the specified Bundle.
- * @throws IllegalArgumentException If the specified bundle has been
- * uninstalled or if the specified start level is less than or equal
- * to zero, or the specified bundle is the system bundle.
- * @throws SecurityException if the caller does not have the
- * <code>AdminPermission</code> and the Java runtime environment
- * supports permissions.
- */
- public abstract void setBundleStartLevel(Bundle bundle, int startlevel);
-
- /**
- * Return the initial start level value that is assigned to a Bundle when it
- * is first installed.
- *
- * @return The initial start level value for Bundles.
- * @see #setInitialBundleStartLevel
- */
- public abstract int getInitialBundleStartLevel();
-
- /**
- * Set the initial start level value that is assigned to a Bundle when it is
- * first installed.
- *
- * <p>
- * The initial bundle start level will be set to the specified start level.
- * The initial bundle start level value will be persistently recorded by the
- * Framework.
- *
- * <p>
- * When a Bundle is installed via <code>BundleContext.installBundle</code>,
- * it is assigned the initial bundle start level value.
- *
- * <p>
- * The default initial bundle start level value is 1 unless this method has
- * been called to assign a different initial bundle start level value.
- *
- * <p>
- * Thie method does not change the start level values of installed bundles.
- *
- * @param startlevel The initial start level for newly installed bundles.
- * @throws IllegalArgumentException If the specified start level is less
- * than or equal to zero.
- * @throws SecurityException if the caller does not have the
- * <code>AdminPermission</code> and the Java runtime environment
- * supports permissions.
- */
- public abstract void setInitialBundleStartLevel(int startlevel);
-
- /**
- * Return the persistent state of the specified bundle.
- *
- * <p>
- * This method returns the persistent state of a bundle. The persistent
- * state of a bundle indicates whether a bundle is persistently marked to be
- * started when it's start level is reached.
- *
- * @return <code>true</code> if the bundle is persistently marked to be
- * started, <code>false</code> if the bundle is not persistently
- * marked to be started.
- * @exception java.lang.IllegalArgumentException If the specified bundle has
- * been uninstalled.
- */
- public abstract boolean isBundlePersistentlyStarted(Bundle bundle);
+/*
+ * $Header: /cvshome/build/org.osgi.service.startlevel/src/org/osgi/service/startlevel/StartLevel.java,v 1.12 2006/03/14 01:21:38 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.startlevel;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * The StartLevel service allows management agents to manage a start level
+ * assigned to each bundle and the active start level of the Framework. There is
+ * at most one StartLevel service present in the OSGi environment.
+ *
+ * <p>
+ * A start level is defined to be a state of execution in which the Framework
+ * exists. StartLevel values are defined as unsigned integers with 0 (zero)
+ * being the state where the Framework is not launched. Progressively higher
+ * integral values represent progressively higher start levels. e.g. 2 is a
+ * higher start level than 1.
+ * <p>
+ * Access to the StartLevel service is protected by corresponding
+ * <code>ServicePermission</code>. In addition <code>AdminPermission</code>
+ * is required to actually modify start level information.
+ * <p>
+ * Start Level support in the Framework includes the ability to control the
+ * beginning start level of the Framework, to modify the active start level of
+ * the Framework and to assign a specific start level to a bundle. How the
+ * beginning start level of a Framework is specified is implementation
+ * dependent. It may be a command line argument when invoking the Framework
+ * implementation.
+ * <p>
+ * When the Framework is first started it must be at start level zero. In this
+ * state, no bundles are running. This is the initial state of the Framework
+ * before it is launched.
+ *
+ * When the Framework is launched, the Framework will enter start level one and
+ * all bundles which are assigned to start level one and are persistently marked
+ * to be started are started as described in the <code>Bundle.start</code>
+ * method. Within a start level, bundles are started in ascending order by
+ * <code>Bundle.getBundleId</code>. The Framework will continue to increase
+ * the start level, starting bundles at each start level, until the Framework
+ * has reached a beginning start level. At this point the Framework has
+ * completed starting bundles and will then fire a Framework event of type
+ * <code>FrameworkEvent.STARTED</code> to announce it has completed its
+ * launch.
+ *
+ * <p>
+ * The StartLevel service can be used by management bundles to alter the active
+ * start level of the framework.
+ *
+ * @version $Revision: 1.12 $
+ */
+public interface StartLevel {
+ /**
+ * Return the active start level value of the Framework.
+ *
+ * If the Framework is in the process of changing the start level this
+ * method must return the active start level if this differs from the
+ * requested start level.
+ *
+ * @return The active start level value of the Framework.
+ */
+ public int getStartLevel();
+
+ /**
+ * Modify the active start level of the Framework.
+ *
+ * <p>
+ * The Framework will move to the requested start level. This method will
+ * return immediately to the caller and the start level change will occur
+ * asynchronously on another thread.
+ *
+ * <p>
+ * If the specified start level is higher than the active start level, the
+ * Framework will continue to increase the start level until the Framework
+ * has reached the specified start level, starting bundles at each start
+ * level which are persistently marked to be started as described in the
+ * <code>Bundle.start</code> method.
+ *
+ * At each intermediate start level value on the way to and including the
+ * target start level, the framework must:
+ * <ol>
+ * <li>Change the active start level to the intermediate start level value.
+ * <li>Start bundles at the intermediate start level in ascending order by
+ * <code>Bundle.getBundleId</code>.
+ * </ol>
+ * When this process completes after the specified start level is reached,
+ * the Framework will fire a Framework event of type
+ * <code>FrameworkEvent.STARTLEVEL_CHANGED</code> to announce it has moved
+ * to the specified start level.
+ *
+ * <p>
+ * If the specified start level is lower than the active start level, the
+ * Framework will continue to decrease the start level until the Framework
+ * has reached the specified start level stopping bundles at each start
+ * level as described in the <code>Bundle.stop</code> method except that
+ * their persistently recorded state indicates that they must be restarted
+ * in the future.
+ *
+ * At each intermediate start level value on the way to and including the
+ * specified start level, the framework must:
+ * <ol>
+ * <li>Stop bundles at the intermediate start level in descending order by
+ * <code>Bundle.getBundleId</code>.
+ * <li>Change the active start level to the intermediate start level value.
+ * </ol>
+ * When this process completes after the specified start level is reached,
+ * the Framework will fire a Framework event of type
+ * <code>FrameworkEvent.STARTLEVEL_CHANGED</code> to announce it has moved
+ * to the specified start level.
+ *
+ * <p>
+ * If the specified start level is equal to the active start level, then no
+ * bundles are started or stopped, however, the Framework must fire a
+ * Framework event of type <code>FrameworkEvent.STARTLEVEL_CHANGED</code>
+ * to announce it has finished moving to the specified start level. This
+ * event may arrive before the this method return.
+ *
+ * @param startlevel The requested start level for the Framework.
+ * @throws IllegalArgumentException If the specified start level is less
+ * than or equal to zero.
+ * @throws SecurityException If the caller does not have
+ * <code>AdminPermission[System Bundle,STARTLEVEL]</code> and the Java runtime
+ * environment supports permissions.
+ */
+ public void setStartLevel(int startlevel);
+
+ /**
+ * Return the assigned start level value for the specified Bundle.
+ *
+ * @param bundle The target bundle.
+ * @return The start level value of the specified Bundle.
+ * @throws java.lang.IllegalArgumentException If the specified bundle has
+ * been uninstalled.
+ */
+ public int getBundleStartLevel(Bundle bundle);
+
+ /**
+ * Assign a start level value to the specified Bundle.
+ *
+ * <p>
+ * The specified bundle will be assigned the specified start level. The
+ * start level value assigned to the bundle will be persistently recorded by
+ * the Framework.
+ *
+ * If the new start level for the bundle is lower than or equal to the
+ * active start level of the Framework, the Framework will start the
+ * specified bundle as described in the <code>Bundle.start</code> method
+ * if the bundle is persistently marked to be started. The actual starting
+ * of this bundle must occur asynchronously.
+ *
+ * If the new start level for the bundle is higher than the active start
+ * level of the Framework, the Framework will stop the specified bundle as
+ * described in the <code>Bundle.stop</code> method except that the
+ * persistently recorded state for the bundle indicates that the bundle must
+ * be restarted in the future. The actual stopping of this bundle must occur
+ * asynchronously.
+ *
+ * @param bundle The target bundle.
+ * @param startlevel The new start level for the specified Bundle.
+ * @throws IllegalArgumentException If the specified bundle has been
+ * uninstalled or if the specified start level is less than or equal
+ * to zero, or the specified bundle is the system bundle.
+ * @throws SecurityException If the caller does not have
+ * <code>AdminPermission[bundle,EXECUTE]</code> and the Java runtime
+ * environment supports permissions.
+ */
+ public void setBundleStartLevel(Bundle bundle, int startlevel);
+
+ /**
+ * Return the initial start level value that is assigned to a Bundle when it
+ * is first installed.
+ *
+ * @return The initial start level value for Bundles.
+ * @see #setInitialBundleStartLevel
+ */
+ public int getInitialBundleStartLevel();
+
+ /**
+ * Set the initial start level value that is assigned to a Bundle when it is
+ * first installed.
+ *
+ * <p>
+ * The initial bundle start level will be set to the specified start level.
+ * The initial bundle start level value will be persistently recorded by the
+ * Framework.
+ *
+ * <p>
+ * When a Bundle is installed via <code>BundleContext.installBundle</code>,
+ * it is assigned the initial bundle start level value.
+ *
+ * <p>
+ * The default initial bundle start level value is 1 unless this method has
+ * been called to assign a different initial bundle start level value.
+ *
+ * <p>
+ * Thie method does not change the start level values of installed bundles.
+ *
+ * @param startlevel The initial start level for newly installed bundles.
+ * @throws IllegalArgumentException If the specified start level is less
+ * than or equal to zero.
+ * @throws SecurityException If the caller does not have
+ * <code>AdminPermission[System Bundle,STARTLEVEL]</code> and the Java runtime
+ * environment supports permissions.
+ */
+ public void setInitialBundleStartLevel(int startlevel);
+
+ /**
+ * Return the persistent state of the specified bundle.
+ *
+ * <p>
+ * This method returns the persistent state of a bundle. The persistent
+ * state of a bundle indicates whether a bundle is persistently marked to be
+ * started when it's start level is reached.
+ *
+ * @param bundle The bundle for which to return the persistently started state.
+ * @return <code>true</code> if the bundle is persistently marked to be
+ * started, <code>false</code> if the bundle is not persistently
+ * marked to be started.
+ * @throws java.lang.IllegalArgumentException If the specified bundle has
+ * been uninstalled.
+ */
+ public boolean isBundlePersistentlyStarted(Bundle bundle);
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java b/org.osgi/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
index 03bfd1b..d8bc1ef 100644
--- a/org.osgi/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
+++ b/org.osgi/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
@@ -1,142 +1,150 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/AbstractURLStreamHandlerService.java,v 1.6 2005/05/13 20:32:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.url;
-
-import java.net.*;
-
-/**
- * Abstract implementation of the <code>URLStreamHandlerService</code> interface.
- * All the methods simply invoke the corresponding methods on
- * <code>java.net.URLStreamHandler</code> except for <code>parseURL</code> and
- * <code>setURL</code>, which use the <code>URLStreamHandlerSetter</code>
- * parameter. Subclasses of this abstract class should not need to override the
- * <code>setURL</code> and <code>parseURL(URLStreamHandlerSetter,...)</code>
- * methods.
- *
- * @version $Revision: 1.6 $
- */
-public abstract class AbstractURLStreamHandlerService extends URLStreamHandler
- implements URLStreamHandlerService {
- /**
- * @see "java.net.URLStreamHandler.openConnection"
- */
- public abstract URLConnection openConnection(URL u)
- throws java.io.IOException;
-
- /**
- * The <code>URLStreamHandlerSetter</code> object passed to the parseURL
- * method.
- */
- protected URLStreamHandlerSetter realHandler;
-
- /**
- * Parse a URL using the <code>URLStreamHandlerSetter</code> object. This
- * method sets the <code>realHandler</code> field with the specified
- * <code>URLStreamHandlerSetter</code> object and then calls
- * <code>parseURL(URL,String,int,int)</code>.
- *
- * @param realHandler The object on which the <code>setURL</code> method must
- * be invoked for the specified URL.
- * @see "java.net.URLStreamHandler.parseURL"
- */
- public void parseURL(URLStreamHandlerSetter realHandler, URL u,
- String spec, int start, int limit) {
- this.realHandler = realHandler;
- parseURL(u, spec, start, limit);
- }
-
- /**
- * This method calls <code>super.toExternalForm</code>.
- *
- * @see "java.net.URLStreamHandler.toExternalForm"
- */
- public String toExternalForm(URL u) {
- return super.toExternalForm(u);
- }
-
- /**
- * This method calls <code>super.equals(URL,URL)</code>.
- *
- * @see "java.net.URLStreamHandler.equals(URL,URL)"
- */
- public boolean equals(URL u1, URL u2) {
- return super.equals(u1, u2);
- }
-
- /**
- * This method calls <code>super.getDefaultPort</code>.
- *
- * @see "java.net.URLStreamHandler.getDefaultPort"
- */
- public int getDefaultPort() {
- return super.getDefaultPort();
- }
-
- /**
- * This method calls <code>super.getHostAddress</code>.
- *
- * @see "java.net.URLStreamHandler.getHostAddress"
- */
- public InetAddress getHostAddress(URL u) {
- return super.getHostAddress(u);
- }
-
- /**
- * This method calls <code>super.hashCode(URL)</code>.
- *
- * @see "java.net.URLStreamHandler.hashCode(URL)"
- */
- public int hashCode(URL u) {
- return super.hashCode(u);
- }
-
- /**
- * This method calls <code>super.hostsEqual</code>.
- *
- * @see "java.net.URLStreamHandler.hostsEqual"
- */
- public boolean hostsEqual(URL u1, URL u2) {
- return super.hostsEqual(u1, u2);
- }
-
- /**
- * This method calls <code>super.sameFile</code>.
- *
- * @see "java.net.URLStreamHandler.sameFile"
- */
- public boolean sameFile(URL u1, URL u2) {
- return super.sameFile(u1, u2);
- }
-
- /**
- * This method calls
- * <code>realHandler.setURL(URL,String,String,int,String,String)</code>.
- *
- * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
- * @deprecated This method is only for compatibility with handlers written
- * for JDK 1.1.
- */
- protected void setURL(URL u, String proto, String host, int port,
- String file, String ref) {
- realHandler.setURL(u, proto, host, port, file, ref);
- }
-
- /**
- * This method calls
- * <code>realHandler.setURL(URL,String,String,int,String,String,String,String)</code>.
- *
- * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
- */
- protected void setURL(URL u, String proto, String host, int port,
- String auth, String user, String path, String query, String ref) {
- realHandler.setURL(u, proto, host, port, auth, user, path, query, ref);
- }
+/*
+ * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/AbstractURLStreamHandlerService.java,v 1.7 2006/03/14 01:21:36 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.url;
+
+import java.net.*;
+
+/**
+ * Abstract implementation of the <code>URLStreamHandlerService</code> interface.
+ * All the methods simply invoke the corresponding methods on
+ * <code>java.net.URLStreamHandler</code> except for <code>parseURL</code> and
+ * <code>setURL</code>, which use the <code>URLStreamHandlerSetter</code>
+ * parameter. Subclasses of this abstract class should not need to override the
+ * <code>setURL</code> and <code>parseURL(URLStreamHandlerSetter,...)</code>
+ * methods.
+ *
+ * @version $Revision: 1.7 $
+ */
+public abstract class AbstractURLStreamHandlerService extends URLStreamHandler
+ implements URLStreamHandlerService {
+ /**
+ * @see "java.net.URLStreamHandler.openConnection"
+ */
+ public abstract URLConnection openConnection(URL u)
+ throws java.io.IOException;
+
+ /**
+ * The <code>URLStreamHandlerSetter</code> object passed to the parseURL
+ * method.
+ */
+ protected URLStreamHandlerSetter realHandler;
+
+ /**
+ * Parse a URL using the <code>URLStreamHandlerSetter</code> object. This
+ * method sets the <code>realHandler</code> field with the specified
+ * <code>URLStreamHandlerSetter</code> object and then calls
+ * <code>parseURL(URL,String,int,int)</code>.
+ *
+ * @param realHandler The object on which the <code>setURL</code> method must
+ * be invoked for the specified URL.
+ * @see "java.net.URLStreamHandler.parseURL"
+ */
+ public void parseURL(URLStreamHandlerSetter realHandler, URL u,
+ String spec, int start, int limit) {
+ this.realHandler = realHandler;
+ parseURL(u, spec, start, limit);
+ }
+
+ /**
+ * This method calls <code>super.toExternalForm</code>.
+ *
+ * @see "java.net.URLStreamHandler.toExternalForm"
+ */
+ public String toExternalForm(URL u) {
+ return super.toExternalForm(u);
+ }
+
+ /**
+ * This method calls <code>super.equals(URL,URL)</code>.
+ *
+ * @see "java.net.URLStreamHandler.equals(URL,URL)"
+ */
+ public boolean equals(URL u1, URL u2) {
+ return super.equals(u1, u2);
+ }
+
+ /**
+ * This method calls <code>super.getDefaultPort</code>.
+ *
+ * @see "java.net.URLStreamHandler.getDefaultPort"
+ */
+ public int getDefaultPort() {
+ return super.getDefaultPort();
+ }
+
+ /**
+ * This method calls <code>super.getHostAddress</code>.
+ *
+ * @see "java.net.URLStreamHandler.getHostAddress"
+ */
+ public InetAddress getHostAddress(URL u) {
+ return super.getHostAddress(u);
+ }
+
+ /**
+ * This method calls <code>super.hashCode(URL)</code>.
+ *
+ * @see "java.net.URLStreamHandler.hashCode(URL)"
+ */
+ public int hashCode(URL u) {
+ return super.hashCode(u);
+ }
+
+ /**
+ * This method calls <code>super.hostsEqual</code>.
+ *
+ * @see "java.net.URLStreamHandler.hostsEqual"
+ */
+ public boolean hostsEqual(URL u1, URL u2) {
+ return super.hostsEqual(u1, u2);
+ }
+
+ /**
+ * This method calls <code>super.sameFile</code>.
+ *
+ * @see "java.net.URLStreamHandler.sameFile"
+ */
+ public boolean sameFile(URL u1, URL u2) {
+ return super.sameFile(u1, u2);
+ }
+
+ /**
+ * This method calls
+ * <code>realHandler.setURL(URL,String,String,int,String,String)</code>.
+ *
+ * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
+ * @deprecated This method is only for compatibility with handlers written
+ * for JDK 1.1.
+ */
+ protected void setURL(URL u, String proto, String host, int port,
+ String file, String ref) {
+ realHandler.setURL(u, proto, host, port, file, ref);
+ }
+
+ /**
+ * This method calls
+ * <code>realHandler.setURL(URL,String,String,int,String,String,String,String)</code>.
+ *
+ * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
+ */
+ protected void setURL(URL u, String proto, String host, int port,
+ String auth, String user, String path, String query, String ref) {
+ realHandler.setURL(u, proto, host, port, auth, user, path, query, ref);
+ }
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/url/URLConstants.java b/org.osgi/src/main/java/org/osgi/service/url/URLConstants.java
index 6915096..69877e3 100644
--- a/org.osgi/src/main/java/org/osgi/service/url/URLConstants.java
+++ b/org.osgi/src/main/java/org/osgi/service/url/URLConstants.java
@@ -1,36 +1,44 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/URLConstants.java,v 1.6 2005/05/13 20:32:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.url;
-
-/**
- * Defines standard names for property keys associated with
- * {@link URLStreamHandlerService}and <code>java.net.ContentHandler</code>
- * services.
- *
- * <p>
- * The values associated with these keys are of type <code>java.lang.String[]</code>,
- * unless otherwise indicated.
- *
- * @version $Revision: 1.6 $
- */
-public interface URLConstants {
- /**
- * Service property naming the protocols serviced by a
- * URLStreamHandlerService. The property's value is an array of protocol
- * names.
- */
- public static final String URL_HANDLER_PROTOCOL = "url.handler.protocol";
- /**
- * Service property naming the MIME types serviced by a
- * java.net.ContentHandler. The property's value is an array of MIME types.
- */
- public static final String URL_CONTENT_MIMETYPE = "url.content.mimetype";
+/*
+ * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/URLConstants.java,v 1.7 2006/03/14 01:21:36 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.url;
+
+/**
+ * Defines standard names for property keys associated with
+ * {@link URLStreamHandlerService}and <code>java.net.ContentHandler</code>
+ * services.
+ *
+ * <p>
+ * The values associated with these keys are of type <code>java.lang.String[]</code>,
+ * unless otherwise indicated.
+ *
+ * @version $Revision: 1.7 $
+ */
+public interface URLConstants {
+ /**
+ * Service property naming the protocols serviced by a
+ * URLStreamHandlerService. The property's value is an array of protocol
+ * names.
+ */
+ public static final String URL_HANDLER_PROTOCOL = "url.handler.protocol";
+ /**
+ * Service property naming the MIME types serviced by a
+ * java.net.ContentHandler. The property's value is an array of MIME types.
+ */
+ public static final String URL_CONTENT_MIMETYPE = "url.content.mimetype";
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerService.java b/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
index 9dea3ff..3a56aae 100644
--- a/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
+++ b/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
@@ -1,84 +1,92 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/URLStreamHandlerService.java,v 1.6 2005/05/13 20:32:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.url;
-
-import java.net.*;
-
-/**
- * Service interface with public versions of the protected
- * <code>java.net.URLStreamHandler</code> methods.
- * <p>
- * The important differences between this interface and the
- * <code>URLStreamHandler</code> class are that the <code>setURL</code> method is
- * absent and the <code>parseURL</code> method takes a
- * {@link URLStreamHandlerSetter}object as the first argument. Classes
- * implementing this interface must call the <code>setURL</code> method on the
- * <code>URLStreamHandlerSetter</code> object received in the <code>parseURL</code>
- * method instead of <code>URLStreamHandler.setURL</code> to avoid a
- * <code>SecurityException</code>.
- *
- * @see AbstractURLStreamHandlerService
- *
- * @version $Revision: 1.6 $
- */
-public interface URLStreamHandlerService {
- /**
- * @see "java.net.URLStreamHandler.openConnection"
- */
- public URLConnection openConnection(URL u) throws java.io.IOException;
-
- /**
- * Parse a URL. This method is called by the <code>URLStreamHandler</code>
- * proxy, instead of <code>java.net.URLStreamHandler.parseURL</code>, passing
- * a <code>URLStreamHandlerSetter</code> object.
- *
- * @param realHandler The object on which <code>setURL</code> must be invoked
- * for this URL.
- * @see "java.net.URLStreamHandler.parseURL"
- */
- public void parseURL(URLStreamHandlerSetter realHandler, URL u,
- String spec, int start, int limit);
-
- /**
- * @see "java.net.URLStreamHandler.toExternalForm"
- */
- public String toExternalForm(URL u);
-
- /**
- * @see "java.net.URLStreamHandler.equals(URL, URL)"
- */
- public boolean equals(URL u1, URL u2);
-
- /**
- * @see "java.net.URLStreamHandler.getDefaultPort"
- */
- public int getDefaultPort();
-
- /**
- * @see "java.net.URLStreamHandler.getHostAddress"
- */
- public InetAddress getHostAddress(URL u);
-
- /**
- * @see "java.net.URLStreamHandler.hashCode(URL)"
- */
- public int hashCode(URL u);
-
- /**
- * @see "java.net.URLStreamHandler.hostsEqual"
- */
- public boolean hostsEqual(URL u1, URL u2);
-
- /**
- * @see "java.net.URLStreamHandler.sameFile"
- */
- public boolean sameFile(URL u1, URL u2);
+/*
+ * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/URLStreamHandlerService.java,v 1.7 2006/03/14 01:21:36 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.url;
+
+import java.net.*;
+
+/**
+ * Service interface with public versions of the protected
+ * <code>java.net.URLStreamHandler</code> methods.
+ * <p>
+ * The important differences between this interface and the
+ * <code>URLStreamHandler</code> class are that the <code>setURL</code> method is
+ * absent and the <code>parseURL</code> method takes a
+ * {@link URLStreamHandlerSetter}object as the first argument. Classes
+ * implementing this interface must call the <code>setURL</code> method on the
+ * <code>URLStreamHandlerSetter</code> object received in the <code>parseURL</code>
+ * method instead of <code>URLStreamHandler.setURL</code> to avoid a
+ * <code>SecurityException</code>.
+ *
+ * @see AbstractURLStreamHandlerService
+ *
+ * @version $Revision: 1.7 $
+ */
+public interface URLStreamHandlerService {
+ /**
+ * @see "java.net.URLStreamHandler.openConnection"
+ */
+ public URLConnection openConnection(URL u) throws java.io.IOException;
+
+ /**
+ * Parse a URL. This method is called by the <code>URLStreamHandler</code>
+ * proxy, instead of <code>java.net.URLStreamHandler.parseURL</code>, passing
+ * a <code>URLStreamHandlerSetter</code> object.
+ *
+ * @param realHandler The object on which <code>setURL</code> must be invoked
+ * for this URL.
+ * @see "java.net.URLStreamHandler.parseURL"
+ */
+ public void parseURL(URLStreamHandlerSetter realHandler, URL u,
+ String spec, int start, int limit);
+
+ /**
+ * @see "java.net.URLStreamHandler.toExternalForm"
+ */
+ public String toExternalForm(URL u);
+
+ /**
+ * @see "java.net.URLStreamHandler.equals(URL, URL)"
+ */
+ public boolean equals(URL u1, URL u2);
+
+ /**
+ * @see "java.net.URLStreamHandler.getDefaultPort"
+ */
+ public int getDefaultPort();
+
+ /**
+ * @see "java.net.URLStreamHandler.getHostAddress"
+ */
+ public InetAddress getHostAddress(URL u);
+
+ /**
+ * @see "java.net.URLStreamHandler.hashCode(URL)"
+ */
+ public int hashCode(URL u);
+
+ /**
+ * @see "java.net.URLStreamHandler.hostsEqual"
+ */
+ public boolean hostsEqual(URL u1, URL u2);
+
+ /**
+ * @see "java.net.URLStreamHandler.sameFile"
+ */
+ public boolean sameFile(URL u1, URL u2);
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java b/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
index 1d59988..3899024 100644
--- a/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
+++ b/org.osgi/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
@@ -1,44 +1,52 @@
-/*
- * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/URLStreamHandlerSetter.java,v 1.6 2005/05/13 20:32:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.service.url;
-
-import java.net.URL;
-
-/**
- * Interface used by <code>URLStreamHandlerService</code> objects to call the
- * <code>setURL</code> method on the proxy <code>URLStreamHandler</code> object.
- *
- * <p>
- * Objects of this type are passed to the
- * {@link URLStreamHandlerService#parseURL}method. Invoking the <code>setURL</code>
- * method on the <code>URLStreamHandlerSetter</code> object will invoke the
- * <code>setURL</code> method on the proxy <code>URLStreamHandler</code> object that
- * is actually registered with <code>java.net.URL</code> for the protocol.
- *
- * @version $Revision: 1.6 $
- */
-public interface URLStreamHandlerSetter {
- /**
- * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
- *
- * @deprecated This method is only for compatibility with handlers written
- * for JDK 1.1.
- */
- public void setURL(URL u, String protocol, String host, int port,
- String file, String ref);
-
- /**
- * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
- */
- public void setURL(URL u, String protocol, String host, int port,
- String authority, String userInfo, String path, String query,
- String ref);
+/*
+ * $Header: /cvshome/build/org.osgi.service.url/src/org/osgi/service/url/URLStreamHandlerSetter.java,v 1.7 2006/03/14 01:21:36 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.url;
+
+import java.net.URL;
+
+/**
+ * Interface used by <code>URLStreamHandlerService</code> objects to call the
+ * <code>setURL</code> method on the proxy <code>URLStreamHandler</code> object.
+ *
+ * <p>
+ * Objects of this type are passed to the
+ * {@link URLStreamHandlerService#parseURL}method. Invoking the <code>setURL</code>
+ * method on the <code>URLStreamHandlerSetter</code> object will invoke the
+ * <code>setURL</code> method on the proxy <code>URLStreamHandler</code> object that
+ * is actually registered with <code>java.net.URL</code> for the protocol.
+ *
+ * @version $Revision: 1.7 $
+ */
+public interface URLStreamHandlerSetter {
+ /**
+ * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
+ *
+ * @deprecated This method is only for compatibility with handlers written
+ * for JDK 1.1.
+ */
+ public void setURL(URL u, String protocol, String host, int port,
+ String file, String ref);
+
+ /**
+ * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
+ */
+ public void setURL(URL u, String protocol, String host, int port,
+ String authority, String userInfo, String path, String query,
+ String ref);
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTracker.java b/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTracker.java
index 19ffb44..816374f 100644
--- a/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTracker.java
+++ b/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTracker.java
@@ -1,982 +1,1139 @@
-/*
- * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.13 2005/05/13 20:33:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.util.tracker;
-
-import java.util.*;
-
-import org.osgi.framework.*;
-
-/**
- * The <code>ServiceTracker</code> class simplifies using services from the
- * Framework's service registry.
- * <p>
- * A <code>ServiceTracker</code> object is constructed with search criteria
- * and a <code>ServiceTrackerCustomizer</code> object. A
- * <code>ServiceTracker</code> object can use the
- * <code>ServiceTrackerCustomizer</code> object to customize the service
- * objects to be tracked. The <code>ServiceTracker</code> object can then be
- * opened to begin tracking all services in the Framework's service registry
- * that match the specified search criteria. The <code>ServiceTracker</code>
- * object correctly handles all of the details of listening to
- * <code>ServiceEvent</code> objects and getting and ungetting services.
- * <p>
- * The <code>getServiceReferences</code> method can be called to get
- * references to the services being tracked. The <code>getService</code> and
- * <code>getServices</code> methods can be called to get the service objects
- * for the tracked service.
- *
- * @version $Revision: 1.13 $
- */
-public class ServiceTracker implements ServiceTrackerCustomizer {
- /* set this to true to compile in debug messages */
- static final boolean DEBUG = false;
- /**
- * Bundle context this <code>ServiceTracker</code> object is tracking
- * against.
- */
- protected final BundleContext context;
- /**
- * Filter specifying search criteria for the services to track.
- *
- * @since 1.1
- */
- protected final Filter filter;
- /**
- * <code>ServiceTrackerCustomizer</code> object for this tracker.
- */
- private final ServiceTrackerCustomizer customizer;
- /**
- * Filter string for use when adding the ServiceListener. If this field is
- * set, then certain optimizations can be taken since we don't have a user
- * supplied filter.
- */
- private final String listenerFilter;
- /**
- * Class name to be tracked. If this field is set, then we are tracking by
- * class name.
- */
- private final String trackClass;
- /**
- * Reference to be tracked. If this field is set, then we are tracking a
- * single ServiceReference.
- */
- private final ServiceReference trackReference;
- /**
- * Tracked services: <code>ServiceReference</code> object -> customized
- * Object and <code>ServiceListener</code> object
- */
- private Tracked tracked;
- /**
- * Modification count. This field is initialized to zero by open, set to -1
- * by close and incremented by modified. This field is volatile since it is
- * accessed by multiple threads.
- */
- private volatile int trackingCount = -1;
- /**
- * Cached ServiceReference for getServiceReference. This field is volatile
- * since it is accessed by multiple threads.
- */
- private volatile ServiceReference cachedReference;
- /**
- * Cached service object for getService. This field is volatile since it is
- * accessed by multiple threads.
- */
- private volatile Object cachedService;
-
- /**
- * Create a <code>ServiceTracker</code> object on the specified
- * <code>ServiceReference</code> object.
- *
- * <p>
- * The service referenced by the specified <code>ServiceReference</code>
- * object will be tracked by this <code>ServiceTracker</code> object.
- *
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param reference <code>ServiceReference</code> object for the service
- * to be tracked.
- * @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> object will be used as the
- * <code>ServiceTrackerCustomizer</code> object and the
- * <code>ServiceTracker</code> object will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
- */
- public ServiceTracker(BundleContext context, ServiceReference reference,
- ServiceTrackerCustomizer customizer) {
- this.context = context;
- this.trackReference = reference;
- this.trackClass = null;
- this.customizer = (customizer == null) ? this : customizer;
- this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- try {
- this.filter = context.createFilter(listenerFilter);
- }
- catch (InvalidSyntaxException e) { // we could only get this exception
- // if the ServiceReference was
- // invalid
- throw new IllegalArgumentException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
- }
-
- /**
- * Create a <code>ServiceTracker</code> object on the specified class
- * name.
- *
- * <p>
- * Services registered under the specified class name will be tracked by
- * this <code>ServiceTracker</code> object.
- *
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param clazz Class name of the services to be tracked.
- * @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> object will be used as the
- * <code>ServiceTrackerCustomizer</code> object and the
- * <code>ServiceTracker</code> object will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
- */
- public ServiceTracker(BundleContext context, String clazz,
- ServiceTrackerCustomizer customizer) {
- this.context = context;
- this.trackReference = null;
- this.trackClass = clazz;
- this.customizer = (customizer == null) ? this : customizer;
- this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- try {
- this.filter = context.createFilter(listenerFilter);
- }
- catch (InvalidSyntaxException e) { // we could only get this exception
- // if the clazz argument was
- // malformed
- throw new IllegalArgumentException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
- }
-
- /**
- * Create a <code>ServiceTracker</code> object on the specified
- * <code>Filter</code> object.
- *
- * <p>
- * Services which match the specified <code>Filter</code> object will be
- * tracked by this <code>ServiceTracker</code> object.
- *
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param filter <code>Filter</code> object to select the services to be
- * tracked.
- * @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is null, then this <code>ServiceTracker</code>
- * object will be used as the <code>ServiceTrackerCustomizer</code>
- * object and the <code>ServiceTracker</code> object will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
- * @since 1.1
- */
- public ServiceTracker(BundleContext context, Filter filter,
- ServiceTrackerCustomizer customizer) {
- this.context = context;
- this.trackReference = null;
- this.trackClass = null;
- this.listenerFilter = null;
- this.filter = filter;
- this.customizer = (customizer == null) ? this : customizer;
- if ((context == null) || (filter == null)) { // we throw a NPE here
- // to
- // be consistent with the
- // other constructors
- throw new NullPointerException();
- }
- }
-
- /**
- * Open this <code>ServiceTracker</code> object and begin tracking
- * services.
- *
- * <p>
- * This method calls <code>open(false)</code>.
- *
- * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
- * object with which this <code>ServiceTracker</code> object was
- * created is no longer valid.
- * @see #open(boolean)
- */
- public void open() {
- open(false);
- }
-
- /**
- * Open this <code>ServiceTracker</code> object and begin tracking
- * services.
- *
- * <p>
- * Services which match the search criteria specified when this
- * <code>ServiceTracker</code> object was created are now tracked by this
- * <code>ServiceTracker</code> object.
- *
- * @param trackAllServices If <code>true</code>, then this
- * <code>ServiceTracker</code> will track all matching services
- * regardless of class loader accessibility. If <code>false</code>,
- * then this <code>ServiceTracker</code> will only track matching
- * services which are class loader accessibile to the bundle whose
- * <code>BundleContext</code> is used by this
- * <code>ServiceTracker</code>.
- * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
- * object with which this <code>ServiceTracker</code> object was
- * created is no longer valid.
- * @since 1.3
- */
- public synchronized void open(boolean trackAllServices) {
- if (tracked != null) {
- return;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
- }
- tracked = trackAllServices ? new AllTracked() : new Tracked();
- trackingCount = 0;
- ServiceReference[] references;
- synchronized (tracked) {
- try {
- context.addServiceListener(tracked, listenerFilter);
- if (listenerFilter == null) { // user supplied filter
- references = getInitialReferences(trackAllServices, null,
- filter.toString());
- }
- else { // constructor supplied filter
- if (trackClass == null) {
- references = new ServiceReference[] {trackReference};
- }
- else {
- references = getInitialReferences(trackAllServices,
- trackClass, null);
- }
- }
- }
- catch (InvalidSyntaxException e) {
- throw new RuntimeException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
- }
- /* Call tracked outside of synchronized region */
- if (references != null) {
- int length = references.length;
- for (int i = 0; i < length; i++) {
- ServiceReference reference = references[i];
- /* if the service is still registered */
- if (reference.getBundle() != null) {
- tracked.track(reference);
- }
- }
- }
- }
-
- /**
- * Returns the list of initial <code>ServiceReference</code> objects that
- * will be tracked by this <code>ServiceTracker</code> object.
- *
- * @param trackAllServices If true, use getAllServiceReferences.
- * @param trackClass the class name with which the service was registered,
- * or null for all services.
- * @param filterString the filter criteria or null for all services.
- * @return the list of initial <code>ServiceReference</code> objects.
- * @throws InvalidSyntaxException if the filter uses an invalid syntax.
- */
- private ServiceReference[] getInitialReferences(boolean trackAllServices,
- String trackClass, String filterString)
- throws InvalidSyntaxException {
- if (trackAllServices) {
- return context.getAllServiceReferences(trackClass, filterString);
- }
- else {
- return context.getServiceReferences(trackClass, filterString);
- }
- }
-
- /**
- * Close this <code>ServiceTracker</code> object.
- *
- * <p>
- * This method should be called when this <code>ServiceTracker</code>
- * object should end the tracking of services.
- */
- public synchronized void close() {
- if (tracked == null) {
- return;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
- }
- tracked.close();
- ServiceReference[] references = getServiceReferences();
- Tracked outgoing = tracked;
- tracked = null;
- try {
- context.removeServiceListener(outgoing);
- }
- catch (IllegalStateException e) {
- /* In case the context was stopped. */
- }
- if (references != null) {
- for (int i = 0; i < references.length; i++) {
- outgoing.untrack(references[i]);
- }
- }
- trackingCount = -1;
- if (DEBUG) {
- if ((cachedReference == null) && (cachedService == null)) {
- System.out
- .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
- }
- }
- }
-
- /**
- * Default implementation of the
- * <code>ServiceTrackerCustomizer.addingService</code> method.
- *
- * <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
- *
- * The default implementation returns the result of calling
- * <code>getService</code>, on the <code>BundleContext</code> object
- * with which this <code>ServiceTracker</code> object was created, passing
- * the specified <code>ServiceReference</code> object.
- * <p>
- * This method can be overridden in a subclass to customize the service
- * object to be tracked for the service being added. In that case, take care
- * not to rely on the default implementation of removedService that will
- * unget the service.
- *
- * @param reference Reference to service being added to this
- * <code>ServiceTracker</code> object.
- * @return The service object to be tracked for the service added to this
- * <code>ServiceTracker</code> object.
- * @see ServiceTrackerCustomizer
- */
- public Object addingService(ServiceReference reference) {
- return context.getService(reference);
- }
-
- /**
- * Default implementation of the
- * <code>ServiceTrackerCustomizer.modifiedService</code> method.
- *
- * <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
- *
- * The default implementation does nothing.
- *
- * @param reference Reference to modified service.
- * @param service The service object for the modified service.
- * @see ServiceTrackerCustomizer
- */
- public void modifiedService(ServiceReference reference, Object service) {
- }
-
- /**
- * Default implementation of the
- * <code>ServiceTrackerCustomizer.removedService</code> method.
- *
- * <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
- *
- * The default implementation calls <code>ungetService</code>, on the
- * <code>BundleContext</code> object with which this
- * <code>ServiceTracker</code> object was created, passing the specified
- * <code>ServiceReference</code> object.
- * <p>
- * This method can be overridden in a subclass. If the default
- * implementation of <code>addingService</code> method was used, this
- * method must unget the service.
- *
- * @param reference Reference to removed service.
- * @param service The service object for the removed service.
- * @see ServiceTrackerCustomizer
- */
- public void removedService(ServiceReference reference, Object service) {
- context.ungetService(reference);
- }
-
- /**
- * Wait for at least one service to be tracked by this
- * <code>ServiceTracker</code> object.
- * <p>
- * It is strongly recommended that <code>waitForService</code> is not used
- * during the calling of the <code>BundleActivator</code> methods.
- * <code>BundleActivator</code> methods are expected to complete in a
- * short period of time.
- *
- * @param timeout time interval in milliseconds to wait. If zero, the method
- * will wait indefinately.
- * @return Returns the result of <code>getService()</code>.
- * @throws IllegalArgumentException If the value of timeout is negative.
- */
- public Object waitForService(long timeout) throws InterruptedException {
- if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$
- }
- Object object = getService();
- while (object == null) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) /* if ServiceTracker is not open */
- {
- return null;
- }
- synchronized (tracked) {
- if (tracked.size() == 0) {
- tracked.wait(timeout);
- }
- }
- object = getService();
- if (timeout > 0) {
- return object;
- }
- }
- return object;
- }
-
- /**
- * Return an array of <code>ServiceReference</code> objects for all
- * services being tracked by this <code>ServiceTracker</code> object.
- *
- * @return Array of <code>ServiceReference</code> objects or
- * <code>null</code> if no service are being tracked.
- */
- public ServiceReference[] getServiceReferences() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) /* if ServiceTracker is not open */
- {
- return null;
- }
- synchronized (tracked) {
- int length = tracked.size();
- if (length == 0) {
- return null;
- }
- ServiceReference[] references = new ServiceReference[length];
- Enumeration keys = tracked.keys();
- for (int i = 0; i < length; i++) {
- references[i] = (ServiceReference) keys.nextElement();
- }
- return references;
- }
- }
-
- /**
- * Returns a <code>ServiceReference</code> object for one of the services
- * being tracked by this <code>ServiceTracker</code> object.
- *
- * <p>
- * If multiple services are being tracked, the service with the highest
- * ranking (as specified in its <code>service.ranking</code> property) is
- * returned.
- *
- * <p>
- * If there is a tie in ranking, the service with the lowest service ID (as
- * specified in its <code>service.id</code> property); that is, the
- * service that was registered first is returned.
- * <p>
- * This is the same algorithm used by
- * <code>BundleContext.getServiceReference</code>.
- *
- * @return <code>ServiceReference</code> object or <code>null</code> if
- * no service is being tracked.
- * @since 1.1
- */
- public ServiceReference getServiceReference() {
- ServiceReference reference = cachedReference;
- if (reference != null) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
- }
- return reference;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
- }
- ServiceReference[] references = getServiceReferences();
- int length = (references == null) ? 0 : references.length;
- if (length == 0) /* if no service is being tracked */
- {
- return null;
- }
- int index = 0;
- if (length > 1) /* if more than one service, select highest ranking */
- {
- int rankings[] = new int[length];
- int count = 0;
- int maxRanking = Integer.MIN_VALUE;
- for (int i = 0; i < length; i++) {
- Object property = references[i]
- .getProperty(Constants.SERVICE_RANKING);
- int ranking = (property instanceof Integer) ? ((Integer) property)
- .intValue()
- : 0;
- rankings[i] = ranking;
- if (ranking > maxRanking) {
- index = i;
- maxRanking = ranking;
- count = 1;
- }
- else {
- if (ranking == maxRanking) {
- count++;
- }
- }
- }
- if (count > 1) /* if still more than one service, select lowest id */
- {
- long minId = Long.MAX_VALUE;
- for (int i = 0; i < length; i++) {
- if (rankings[i] == maxRanking) {
- long id = ((Long) (references[i]
- .getProperty(Constants.SERVICE_ID)))
- .longValue();
- if (id < minId) {
- index = i;
- minId = id;
- }
- }
- }
- }
- }
- return cachedReference = references[index];
- }
-
- /**
- * Returns the service object for the specified
- * <code>ServiceReference</code> object if the referenced service is being
- * tracked by this <code>ServiceTracker</code> object.
- *
- * @param reference Reference to the desired service.
- * @return Service object or <code>null</code> if the service referenced
- * by the specified <code>ServiceReference</code> object is not
- * being tracked.
- */
- public Object getService(ServiceReference reference) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) /* if ServiceTracker is not open */
- {
- return null;
- }
- synchronized (tracked) {
- return tracked.get(reference);
- }
- }
-
- /**
- * Return an array of service objects for all services being tracked by this
- * <code>ServiceTracker</code> object.
- *
- * @return Array of service objects or <code>null</code> if no service are
- * being tracked.
- */
- public Object[] getServices() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) /* if ServiceTracker is not open */
- {
- return null;
- }
- synchronized (tracked) {
- ServiceReference[] references = getServiceReferences();
- int length = (references == null) ? 0 : references.length;
- if (length == 0) {
- return null;
- }
- Object[] objects = new Object[length];
- for (int i = 0; i < length; i++) {
- objects[i] = getService(references[i]);
- }
- return objects;
- }
- }
-
- /**
- * Returns a service object for one of the services being tracked by this
- * <code>ServiceTracker</code> object.
- *
- * <p>
- * If any services are being tracked, this method returns the result of
- * calling <code>getService(getServiceReference())</code>.
- *
- * @return Service object or <code>null</code> if no service is being
- * tracked.
- */
- public Object getService() {
- Object service = cachedService;
- if (service != null) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
- }
- return service;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
- }
- ServiceReference reference = getServiceReference();
- if (reference == null) {
- return null;
- }
- return cachedService = getService(reference);
- }
-
- /**
- * Remove a service from this <code>ServiceTracker</code> object.
- *
- * The specified service will be removed from this
- * <code>ServiceTracker</code> object. If the specified service was being
- * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
- * method will be called for that service.
- *
- * @param reference Reference to the service to be removed.
- */
- public void remove(ServiceReference reference) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) /* if ServiceTracker is not open */
- {
- return;
- }
- tracked.untrack(reference);
- }
-
- /**
- * Return the number of services being tracked by this
- * <code>ServiceTracker</code> object.
- *
- * @return Number of services being tracked.
- */
- public int size() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) /* if ServiceTracker is not open */
- {
- return 0;
- }
- return tracked.size();
- }
-
- /**
- * Returns the tracking count for this <code>ServiceTracker</code> object.
- *
- * The tracking count is initialized to 0 when this
- * <code>ServiceTracker</code> object is opened. Every time a service is
- * added or removed from this <code>ServiceTracker</code> object the
- * tracking count is incremented.
- *
- * <p>
- * The tracking count can be used to determine if this
- * <code>ServiceTracker</code> object has added or removed a service by
- * comparing a tracking count value previously collected with the current
- * tracking count value. If the value has not changed, then no service has
- * been added or removed from this <code>ServiceTracker</code> object
- * since the previous tracking count was collected.
- *
- * @since 1.2
- * @return The tracking count for this <code>ServiceTracker</code> object
- * or -1 if this <code>ServiceTracker</code> object is not open.
- */
- public int getTrackingCount() {
- return trackingCount;
- }
-
- /**
- * Called by the Tracked object whenever the set of tracked services is
- * modified. Increments the tracking count and clears the cache.
- */
- /*
- * This method must not be synchronized since it is called by Tracked while
- * Tracked is synchronized. We don't want synchronization interactions
- * between the ServiceListener thread and the user thread.
- */
- private void modified() {
- trackingCount++; /* increment modification count */
- cachedReference = null; /* clear cached value */
- cachedService = null; /* clear cached value */
- if (DEBUG) {
- System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
- }
- }
-
- /**
- * Inner class to track services. If a <code>ServiceTracker</code> object
- * is reused (closed then reopened), then a new Tracked object is used. This
- * class is a hashtable mapping <code>ServiceReference</code> object ->
- * customized Object. This class is the <code>ServiceListener</code>
- * object for the tracker. This class is used to synchronize access to the
- * tracked services. This is not a public class. It is only for use by the
- * implementation of the <code>ServiceTracker</code> class.
- *
- */
- class Tracked extends Hashtable implements ServiceListener {
- static final long serialVersionUID = -7420065199791006079L;
- /**
- * List of ServiceReferences in the process of being added.
- */
- private ArrayList adding;
- /**
- * true if the tracked object is closed. This field is volatile because
- * it is set by one thread and read by another.
- */
- private volatile boolean closed;
-
- /**
- * Tracked constructor.
- */
- protected Tracked() {
- super();
- closed = false;
- adding = new ArrayList(6);
- }
-
- /**
- * Called by the owning <code>ServiceTracker</code> object when it is
- * closed.
- */
- protected void close() {
- closed = true;
- }
-
- /**
- * <code>ServiceListener</code> method for the
- * <code>ServiceTracker</code> class. This method must NOT be
- * synchronized to avoid deadlock potential.
- *
- * @param event <code>ServiceEvent</code> object from the framework.
- */
- public void serviceChanged(ServiceEvent event) {
- /*
- * Check if we had a delayed call (which could happen when we
- * close).
- */
- if (closed) {
- return;
- }
- ServiceReference reference = event.getServiceReference();
- switch (event.getType()) {
- case ServiceEvent.REGISTERED :
- case ServiceEvent.MODIFIED :
- if (listenerFilter != null) { // constructor supplied
- // filter
- track(reference);
- /*
- * If the customizer throws an unchecked exception, it
- * is safe to let it propagate
- */
- }
- else { // user supplied filter
- if (filter.match(reference)) {
- track(reference);
- /*
- * If the customizer throws an unchecked exception,
- * it is safe to let it propagate
- */
- }
- else {
- untrack(reference);
- /*
- * If the customizer throws an unchecked exception,
- * it is safe to let it propagate
- */
- }
- }
- break;
- case ServiceEvent.UNREGISTERING :
- untrack(reference);
- /*
- * If the customizer throws an unchecked exception, it is
- * safe to let it propagate
- */
- break;
- }
- }
-
- /**
- * Begin to track the referenced service.
- *
- * @param reference Reference to a service to be tracked.
- */
- protected void track(ServiceReference reference) {
- Object object;
- synchronized (this) {
- object = this.get(reference);
- }
- if (object != null) /* we are already tracking the service */
- {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.modifiedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe
- * to let it propagate
- */
- return;
- }
- synchronized (this) {
- if (adding.contains(reference)) /*
- * if this service is already in
- * the process of being added.
- */
- {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
- }
- return;
- }
- adding.add(reference); /* mark this service is being added */
- }
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[adding]: " + reference); //$NON-NLS-1$
- }
- boolean becameUntracked = false;
- /* Call customizer outside of synchronized region */
- try {
- object = customizer.addingService(reference);
- /*
- * If the customizer throws an unchecked exception, it will
- * propagate after the finally
- */
- }
- finally {
- synchronized (this) {
- if (adding.remove(reference)) /*
- * if the service was not
- * untracked during the
- * customizer callback
- */
- {
- if (object != null) {
- this.put(reference, object);
- modified(); /* increment modification count */
- notifyAll();
- }
- }
- else {
- becameUntracked = true;
- }
- }
- }
- /*
- * The service became untracked during the customizer callback.
- */
- if (becameUntracked) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[removed]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.removedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe
- * to let it propagate
- */
- }
- }
-
- /**
- * Discontinue tracking the referenced service.
- *
- * @param reference Reference to the tracked service.
- */
- protected void untrack(ServiceReference reference) {
- Object object;
- synchronized (this) {
- if (adding.remove(reference)) /*
- * if the service is in the
- * process of being added
- */
- {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
- }
- return; /*
- * in case the service is untracked while in the
- * process of adding
- */
- }
- object = this.remove(reference); /*
- * must remove from tracker
- * before calling customizer
- * callback
- */
- if (object == null) /* are we actually tracking the service */
- {
- return;
- }
- modified(); /* increment modification count */
- }
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.removedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe to
- * let it propagate
- */
- }
- }
-
- /**
- * Subclass of Tracked which implements the AllServiceListener interface.
- * This class is used by the ServiceTracker if isAllServiceTracker returns
- * true.
- *
- * @since 1.3
- */
- class AllTracked extends Tracked implements AllServiceListener {
- static final long serialVersionUID = 4050764875305137716L;
-
- /**
- * Tracked constructor.
- */
- protected AllTracked() {
- super();
- }
- }
+/*
+ * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.18 2006/03/14 01:20:01 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.util.tracker;
+
+import java.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * The <code>ServiceTracker</code> class simplifies using services from the
+ * Framework's service registry.
+ * <p>
+ * A <code>ServiceTracker</code> object is constructed with search criteria
+ * and a <code>ServiceTrackerCustomizer</code> object. A
+ * <code>ServiceTracker</code> object can use the
+ * <code>ServiceTrackerCustomizer</code> object to customize the service
+ * objects to be tracked. The <code>ServiceTracker</code> object can then be
+ * opened to begin tracking all services in the Framework's service registry
+ * that match the specified search criteria. The <code>ServiceTracker</code>
+ * object correctly handles all of the details of listening to
+ * <code>ServiceEvent</code> objects and getting and ungetting services.
+ * <p>
+ * The <code>getServiceReferences</code> method can be called to get
+ * references to the services being tracked. The <code>getService</code> and
+ * <code>getServices</code> methods can be called to get the service objects
+ * for the tracked service.
+ *
+ * @version $Revision: 1.18 $
+ */
+public class ServiceTracker implements ServiceTrackerCustomizer {
+ /* set this to true to compile in debug messages */
+ static final boolean DEBUG = false;
+ /**
+ * Bundle context this <code>ServiceTracker</code> object is tracking
+ * against.
+ */
+ protected final BundleContext context;
+ /**
+ * Filter specifying search criteria for the services to track.
+ *
+ * @since 1.1
+ */
+ protected final Filter filter;
+ /**
+ * <code>ServiceTrackerCustomizer</code> object for this tracker.
+ */
+ final ServiceTrackerCustomizer customizer;
+ /**
+ * Filter string for use when adding the ServiceListener. If this field is
+ * set, then certain optimizations can be taken since we don't have a user
+ * supplied filter.
+ */
+ final String listenerFilter;
+ /**
+ * Class name to be tracked. If this field is set, then we are tracking by
+ * class name.
+ */
+ private final String trackClass;
+ /**
+ * Reference to be tracked. If this field is set, then we are tracking a
+ * single ServiceReference.
+ */
+ private final ServiceReference trackReference;
+ /**
+ * Tracked services: <code>ServiceReference</code> object -> customized
+ * Object and <code>ServiceListener</code> object
+ */
+ private Tracked tracked;
+ /**
+ * Modification count. This field is initialized to zero by open, set to -1
+ * by close and incremented by modified.
+ *
+ * This field is volatile since it is accessed by multiple threads.
+ */
+ private volatile int trackingCount = -1;
+ /**
+ * Cached ServiceReference for getServiceReference.
+ *
+ * This field is volatile since it is accessed by multiple threads.
+ */
+ private volatile ServiceReference cachedReference;
+ /**
+ * Cached service object for getService.
+ *
+ * This field is volatile since it is accessed by multiple threads.
+ */
+ private volatile Object cachedService;
+
+ /**
+ * Create a <code>ServiceTracker</code> object on the specified
+ * <code>ServiceReference</code> object.
+ *
+ * <p>
+ * The service referenced by the specified <code>ServiceReference</code>
+ * object will be tracked by this <code>ServiceTracker</code> object.
+ *
+ * @param context <code>BundleContext</code> object against which the
+ * tracking is done.
+ * @param reference <code>ServiceReference</code> object for the service
+ * to be tracked.
+ * @param customizer The customizer object to call when services are added,
+ * modified, or removed in this <code>ServiceTracker</code> object.
+ * If customizer is <code>null</code>, then this
+ * <code>ServiceTracker</code> object will be used as the
+ * <code>ServiceTrackerCustomizer</code> object and the
+ * <code>ServiceTracker</code> object will call the
+ * <code>ServiceTrackerCustomizer</code> methods on itself.
+ */
+ public ServiceTracker(BundleContext context, ServiceReference reference,
+ ServiceTrackerCustomizer customizer) {
+ this.context = context;
+ this.trackReference = reference;
+ this.trackClass = null;
+ this.customizer = (customizer == null) ? this : customizer;
+ this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ try {
+ this.filter = context.createFilter(listenerFilter);
+ }
+ catch (InvalidSyntaxException e) { // we could only get this exception
+ // if the ServiceReference was
+ // invalid
+ throw new IllegalArgumentException(
+ "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Create a <code>ServiceTracker</code> object on the specified class
+ * name.
+ *
+ * <p>
+ * Services registered under the specified class name will be tracked by
+ * this <code>ServiceTracker</code> object.
+ *
+ * @param context <code>BundleContext</code> object against which the
+ * tracking is done.
+ * @param clazz Class name of the services to be tracked.
+ * @param customizer The customizer object to call when services are added,
+ * modified, or removed in this <code>ServiceTracker</code> object.
+ * If customizer is <code>null</code>, then this
+ * <code>ServiceTracker</code> object will be used as the
+ * <code>ServiceTrackerCustomizer</code> object and the
+ * <code>ServiceTracker</code> object will call the
+ * <code>ServiceTrackerCustomizer</code> methods on itself.
+ */
+ public ServiceTracker(BundleContext context, String clazz,
+ ServiceTrackerCustomizer customizer) {
+ this.context = context;
+ this.trackReference = null;
+ this.trackClass = clazz;
+ this.customizer = (customizer == null) ? this : customizer;
+ this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ try {
+ this.filter = context.createFilter(listenerFilter);
+ }
+ catch (InvalidSyntaxException e) { // we could only get this exception
+ // if the clazz argument was
+ // malformed
+ throw new IllegalArgumentException(
+ "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Create a <code>ServiceTracker</code> object on the specified
+ * <code>Filter</code> object.
+ *
+ * <p>
+ * Services which match the specified <code>Filter</code> object will be
+ * tracked by this <code>ServiceTracker</code> object.
+ *
+ * @param context <code>BundleContext</code> object against which the
+ * tracking is done.
+ * @param filter <code>Filter</code> object to select the services to be
+ * tracked.
+ * @param customizer The customizer object to call when services are added,
+ * modified, or removed in this <code>ServiceTracker</code> object.
+ * If customizer is null, then this <code>ServiceTracker</code>
+ * object will be used as the <code>ServiceTrackerCustomizer</code>
+ * object and the <code>ServiceTracker</code> object will call the
+ * <code>ServiceTrackerCustomizer</code> methods on itself.
+ * @since 1.1
+ */
+ public ServiceTracker(BundleContext context, Filter filter,
+ ServiceTrackerCustomizer customizer) {
+ this.context = context;
+ this.trackReference = null;
+ this.trackClass = null;
+ this.listenerFilter = null;
+ this.filter = filter;
+ this.customizer = (customizer == null) ? this : customizer;
+ if ((context == null) || (filter == null)) { // we throw a NPE here
+ // to
+ // be consistent with the
+ // other constructors
+ throw new NullPointerException();
+ }
+ }
+
+ /**
+ * Open this <code>ServiceTracker</code> object and begin tracking
+ * services.
+ *
+ * <p>
+ * This method calls <code>open(false)</code>.
+ *
+ * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
+ * object with which this <code>ServiceTracker</code> object was
+ * created is no longer valid.
+ * @see #open(boolean)
+ */
+ public void open() {
+ open(false);
+ }
+
+ /**
+ * Open this <code>ServiceTracker</code> object and begin tracking
+ * services.
+ *
+ * <p>
+ * Services which match the search criteria specified when this
+ * <code>ServiceTracker</code> object was created are now tracked by this
+ * <code>ServiceTracker</code> object.
+ *
+ * @param trackAllServices If <code>true</code>, then this
+ * <code>ServiceTracker</code> will track all matching services
+ * regardless of class loader accessibility. If <code>false</code>,
+ * then this <code>ServiceTracker</code> will only track matching
+ * services which are class loader accessibile to the bundle whose
+ * <code>BundleContext</code> is used by this
+ * <code>ServiceTracker</code>.
+ * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
+ * object with which this <code>ServiceTracker</code> object was
+ * created is no longer valid.
+ * @since 1.3
+ */
+ public synchronized void open(boolean trackAllServices) {
+ if (tracked != null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
+ }
+ tracked = trackAllServices ? new AllTracked() : new Tracked();
+ trackingCount = 0;
+ synchronized (tracked) {
+ try {
+ context.addServiceListener(tracked, listenerFilter);
+ ServiceReference[] references;
+ if (listenerFilter == null) { // user supplied filter
+ references = getInitialReferences(trackAllServices, null,
+ filter.toString());
+ }
+ else { // constructor supplied filter
+ if (trackClass == null) {
+ references = new ServiceReference[] {trackReference};
+ }
+ else {
+ references = getInitialReferences(trackAllServices,
+ trackClass, null);
+ }
+ }
+
+ tracked.setInitialServices(references); // set tracked with
+ // the initial
+ // references
+ }
+ catch (InvalidSyntaxException e) {
+ throw new RuntimeException(
+ "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+ }
+ }
+ /* Call tracked outside of synchronized region */
+ tracked.trackInitialServices(); // process the initial references
+ }
+
+ /**
+ * Returns the list of initial <code>ServiceReference</code> objects that
+ * will be tracked by this <code>ServiceTracker</code> object.
+ *
+ * @param trackAllServices If true, use getAllServiceReferences.
+ * @param trackClass the class name with which the service was registered,
+ * or null for all services.
+ * @param filterString the filter criteria or null for all services.
+ * @return the list of initial <code>ServiceReference</code> objects.
+ * @throws InvalidSyntaxException if the filter uses an invalid syntax.
+ */
+ private ServiceReference[] getInitialReferences(boolean trackAllServices,
+ String trackClass, String filterString)
+ throws InvalidSyntaxException {
+ if (trackAllServices) {
+ return context.getAllServiceReferences(trackClass, filterString);
+ }
+ else {
+ return context.getServiceReferences(trackClass, filterString);
+ }
+ }
+
+ /**
+ * Close this <code>ServiceTracker</code> object.
+ *
+ * <p>
+ * This method should be called when this <code>ServiceTracker</code>
+ * object should end the tracking of services.
+ */
+ public synchronized void close() {
+ if (tracked == null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
+ }
+ tracked.close();
+ ServiceReference[] references = getServiceReferences();
+ Tracked outgoing = tracked;
+ tracked = null;
+ try {
+ context.removeServiceListener(outgoing);
+ }
+ catch (IllegalStateException e) {
+ /* In case the context was stopped. */
+ }
+ if (references != null) {
+ for (int i = 0; i < references.length; i++) {
+ outgoing.untrack(references[i]);
+ }
+ }
+ trackingCount = -1;
+ if (DEBUG) {
+ if ((cachedReference == null) && (cachedService == null)) {
+ System.out
+ .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Default implementation of the
+ * <code>ServiceTrackerCustomizer.addingService</code> method.
+ *
+ * <p>
+ * This method is only called when this <code>ServiceTracker</code> object
+ * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+ * argument.
+ *
+ * The default implementation returns the result of calling
+ * <code>getService</code>, on the <code>BundleContext</code> object
+ * with which this <code>ServiceTracker</code> object was created, passing
+ * the specified <code>ServiceReference</code> object.
+ * <p>
+ * This method can be overridden in a subclass to customize the service
+ * object to be tracked for the service being added. In that case, take care
+ * not to rely on the default implementation of removedService that will
+ * unget the service.
+ *
+ * @param reference Reference to service being added to this
+ * <code>ServiceTracker</code> object.
+ * @return The service object to be tracked for the service added to this
+ * <code>ServiceTracker</code> object.
+ * @see ServiceTrackerCustomizer
+ */
+ public Object addingService(ServiceReference reference) {
+ return context.getService(reference);
+ }
+
+ /**
+ * Default implementation of the
+ * <code>ServiceTrackerCustomizer.modifiedService</code> method.
+ *
+ * <p>
+ * This method is only called when this <code>ServiceTracker</code> object
+ * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+ * argument.
+ *
+ * The default implementation does nothing.
+ *
+ * @param reference Reference to modified service.
+ * @param service The service object for the modified service.
+ * @see ServiceTrackerCustomizer
+ */
+ public void modifiedService(ServiceReference reference, Object service) {
+ }
+
+ /**
+ * Default implementation of the
+ * <code>ServiceTrackerCustomizer.removedService</code> method.
+ *
+ * <p>
+ * This method is only called when this <code>ServiceTracker</code> object
+ * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+ * argument.
+ *
+ * The default implementation calls <code>ungetService</code>, on the
+ * <code>BundleContext</code> object with which this
+ * <code>ServiceTracker</code> object was created, passing the specified
+ * <code>ServiceReference</code> object.
+ * <p>
+ * This method can be overridden in a subclass. If the default
+ * implementation of <code>addingService</code> method was used, this
+ * method must unget the service.
+ *
+ * @param reference Reference to removed service.
+ * @param service The service object for the removed service.
+ * @see ServiceTrackerCustomizer
+ */
+ public void removedService(ServiceReference reference, Object service) {
+ context.ungetService(reference);
+ }
+
+ /**
+ * Wait for at least one service to be tracked by this
+ * <code>ServiceTracker</code> object.
+ * <p>
+ * It is strongly recommended that <code>waitForService</code> is not used
+ * during the calling of the <code>BundleActivator</code> methods.
+ * <code>BundleActivator</code> methods are expected to complete in a
+ * short period of time.
+ *
+ * @param timeout time interval in milliseconds to wait. If zero, the method
+ * will wait indefinately.
+ * @return Returns the result of <code>getService()</code>.
+ * @throws InterruptedException If another thread has interrupted the
+ * current thread.
+ * @throws IllegalArgumentException If the value of timeout is negative.
+ */
+ public Object waitForService(long timeout) throws InterruptedException {
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$
+ }
+ Object object = getService();
+ while (object == null) {
+ Tracked tracked = this.tracked; /*
+ * use local var since we are not
+ * synchronized
+ */
+ if (tracked == null) { /* if ServiceTracker is not open */
+ return null;
+ }
+ synchronized (tracked) {
+ if (tracked.size() == 0) {
+ tracked.wait(timeout);
+ }
+ }
+ object = getService();
+ if (timeout > 0) {
+ return object;
+ }
+ }
+ return object;
+ }
+
+ /**
+ * Return an array of <code>ServiceReference</code> objects for all
+ * services being tracked by this <code>ServiceTracker</code> object.
+ *
+ * @return Array of <code>ServiceReference</code> objects or
+ * <code>null</code> if no service are being tracked.
+ */
+ public ServiceReference[] getServiceReferences() {
+ Tracked tracked = this.tracked; /*
+ * use local var since we are not
+ * synchronized
+ */
+ if (tracked == null) { /* if ServiceTracker is not open */
+ return null;
+ }
+ synchronized (tracked) {
+ int length = tracked.size();
+ if (length == 0) {
+ return null;
+ }
+ ServiceReference[] references = new ServiceReference[length];
+ Enumeration keys = tracked.keys();
+ for (int i = 0; i < length; i++) {
+ references[i] = (ServiceReference) keys.nextElement();
+ }
+ return references;
+ }
+ }
+
+ /**
+ * Returns a <code>ServiceReference</code> object for one of the services
+ * being tracked by this <code>ServiceTracker</code> object.
+ *
+ * <p>
+ * If multiple services are being tracked, the service with the highest
+ * ranking (as specified in its <code>service.ranking</code> property) is
+ * returned.
+ *
+ * <p>
+ * If there is a tie in ranking, the service with the lowest service ID (as
+ * specified in its <code>service.id</code> property); that is, the
+ * service that was registered first is returned.
+ * <p>
+ * This is the same algorithm used by
+ * <code>BundleContext.getServiceReference</code>.
+ *
+ * @return <code>ServiceReference</code> object or <code>null</code> if
+ * no service is being tracked.
+ * @since 1.1
+ */
+ public ServiceReference getServiceReference() {
+ ServiceReference reference = cachedReference;
+ if (reference != null) {
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
+ }
+ return reference;
+ }
+ if (DEBUG) {
+ System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
+ }
+ ServiceReference[] references = getServiceReferences();
+ int length = (references == null) ? 0 : references.length;
+ if (length == 0) /* if no service is being tracked */
+ {
+ return null;
+ }
+ int index = 0;
+ if (length > 1) /* if more than one service, select highest ranking */
+ {
+ int rankings[] = new int[length];
+ int count = 0;
+ int maxRanking = Integer.MIN_VALUE;
+ for (int i = 0; i < length; i++) {
+ Object property = references[i]
+ .getProperty(Constants.SERVICE_RANKING);
+ int ranking = (property instanceof Integer) ? ((Integer) property)
+ .intValue()
+ : 0;
+ rankings[i] = ranking;
+ if (ranking > maxRanking) {
+ index = i;
+ maxRanking = ranking;
+ count = 1;
+ }
+ else {
+ if (ranking == maxRanking) {
+ count++;
+ }
+ }
+ }
+ if (count > 1) /* if still more than one service, select lowest id */
+ {
+ long minId = Long.MAX_VALUE;
+ for (int i = 0; i < length; i++) {
+ if (rankings[i] == maxRanking) {
+ long id = ((Long) (references[i]
+ .getProperty(Constants.SERVICE_ID)))
+ .longValue();
+ if (id < minId) {
+ index = i;
+ minId = id;
+ }
+ }
+ }
+ }
+ }
+ return cachedReference = references[index];
+ }
+
+ /**
+ * Returns the service object for the specified
+ * <code>ServiceReference</code> object if the referenced service is being
+ * tracked by this <code>ServiceTracker</code> object.
+ *
+ * @param reference Reference to the desired service.
+ * @return Service object or <code>null</code> if the service referenced
+ * by the specified <code>ServiceReference</code> object is not
+ * being tracked.
+ */
+ public Object getService(ServiceReference reference) {
+ Tracked tracked = this.tracked; /*
+ * use local var since we are not
+ * synchronized
+ */
+ if (tracked == null) { /* if ServiceTracker is not open */
+ return null;
+ }
+ synchronized (tracked) {
+ return tracked.get(reference);
+ }
+ }
+
+ /**
+ * Return an array of service objects for all services being tracked by this
+ * <code>ServiceTracker</code> object.
+ *
+ * @return Array of service objects or <code>null</code> if no service are
+ * being tracked.
+ */
+ public Object[] getServices() {
+ Tracked tracked = this.tracked; /*
+ * use local var since we are not
+ * synchronized
+ */
+ if (tracked == null) { /* if ServiceTracker is not open */
+ return null;
+ }
+ synchronized (tracked) {
+ ServiceReference[] references = getServiceReferences();
+ int length = (references == null) ? 0 : references.length;
+ if (length == 0) {
+ return null;
+ }
+ Object[] objects = new Object[length];
+ for (int i = 0; i < length; i++) {
+ objects[i] = getService(references[i]);
+ }
+ return objects;
+ }
+ }
+
+ /**
+ * Returns a service object for one of the services being tracked by this
+ * <code>ServiceTracker</code> object.
+ *
+ * <p>
+ * If any services are being tracked, this method returns the result of
+ * calling <code>getService(getServiceReference())</code>.
+ *
+ * @return Service object or <code>null</code> if no service is being
+ * tracked.
+ */
+ public Object getService() {
+ Object service = cachedService;
+ if (service != null) {
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
+ }
+ return service;
+ }
+ if (DEBUG) {
+ System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
+ }
+ ServiceReference reference = getServiceReference();
+ if (reference == null) {
+ return null;
+ }
+ return cachedService = getService(reference);
+ }
+
+ /**
+ * Remove a service from this <code>ServiceTracker</code> object.
+ *
+ * The specified service will be removed from this
+ * <code>ServiceTracker</code> object. If the specified service was being
+ * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
+ * method will be called for that service.
+ *
+ * @param reference Reference to the service to be removed.
+ */
+ public void remove(ServiceReference reference) {
+ Tracked tracked = this.tracked; /*
+ * use local var since we are not
+ * synchronized
+ */
+ if (tracked == null) { /* if ServiceTracker is not open */
+ return;
+ }
+ tracked.untrack(reference);
+ }
+
+ /**
+ * Return the number of services being tracked by this
+ * <code>ServiceTracker</code> object.
+ *
+ * @return Number of services being tracked.
+ */
+ public int size() {
+ Tracked tracked = this.tracked; /*
+ * use local var since we are not
+ * synchronized
+ */
+ if (tracked == null) { /* if ServiceTracker is not open */
+ return 0;
+ }
+ return tracked.size();
+ }
+
+ /**
+ * Returns the tracking count for this <code>ServiceTracker</code> object.
+ *
+ * The tracking count is initialized to 0 when this
+ * <code>ServiceTracker</code> object is opened. Every time a service is
+ * added or removed from this <code>ServiceTracker</code> object the
+ * tracking count is incremented.
+ *
+ * <p>
+ * The tracking count can be used to determine if this
+ * <code>ServiceTracker</code> object has added or removed a service by
+ * comparing a tracking count value previously collected with the current
+ * tracking count value. If the value has not changed, then no service has
+ * been added or removed from this <code>ServiceTracker</code> object
+ * since the previous tracking count was collected.
+ *
+ * @since 1.2
+ * @return The tracking count for this <code>ServiceTracker</code> object
+ * or -1 if this <code>ServiceTracker</code> object is not open.
+ */
+ public int getTrackingCount() {
+ return trackingCount;
+ }
+
+ /**
+ * Called by the Tracked object whenever the set of tracked services is
+ * modified. Increments the tracking count and clears the cache.
+ */
+ /*
+ * This method must not be synchronized since it is called by Tracked while
+ * Tracked is synchronized. We don't want synchronization interactions
+ * between the ServiceListener thread and the user thread.
+ */
+ void modified() {
+ trackingCount++; /* increment modification count */
+ cachedReference = null; /* clear cached value */
+ cachedService = null; /* clear cached value */
+ if (DEBUG) {
+ System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Finalize. This method no longer performs any function but it kept to
+ * maintain binary compatibility with prior versions of this class.
+ */
+ protected void finalize() throws Throwable {
+ }
+
+ /**
+ * Inner class to track services. If a <code>ServiceTracker</code> object
+ * is reused (closed then reopened), then a new Tracked object is used. This
+ * class is a hashtable mapping <code>ServiceReference</code> object ->
+ * customized Object. This class is the <code>ServiceListener</code>
+ * object for the tracker. This class is used to synchronize access to the
+ * tracked services. This is not a public class. It is only for use by the
+ * implementation of the <code>ServiceTracker</code> class.
+ *
+ */
+ class Tracked extends Hashtable implements ServiceListener {
+ static final long serialVersionUID = -7420065199791006079L;
+ /**
+ * List of ServiceReferences in the process of being added. This is used
+ * to deal with nesting of ServiceEvents. Since ServiceEvents are
+ * synchronously delivered, ServiceEvents can be nested. For example,
+ * when processing the adding of a service and the customizer causes the
+ * service to be unregistered, notification to the nested call to
+ * untrack that the service was unregistered can be made to the track
+ * method.
+ *
+ * Since the ArrayList implementation is not synchronized, all access to
+ * this list must be protected by the same synchronized object for
+ * thread safety.
+ */
+ private ArrayList adding;
+
+ /**
+ * true if the tracked object is closed.
+ *
+ * This field is volatile because it is set by one thread and read by
+ * another.
+ */
+ private volatile boolean closed;
+
+ /**
+ * Initial list of ServiceReferences for the tracker. This is used to
+ * correctly process the initial services which could become
+ * unregistered before they are tracked. This is necessary since the
+ * initial set of tracked services are not "announced" by ServiceEvents
+ * and therefore the ServiceEvent for unregistration could be delivered
+ * before we track the service.
+ *
+ * A service must not be in both the initial and adding lists at the
+ * same time. A service must be moved from the initial list to the
+ * adding list "atomically" before we begin tracking it.
+ *
+ * Since the LinkedList implementation is not synchronized, all access
+ * to this list must be protected by the same synchronized object for
+ * thread safety.
+ */
+ private LinkedList initial;
+
+ /**
+ * Tracked constructor.
+ */
+ protected Tracked() {
+ super();
+ closed = false;
+ adding = new ArrayList(6);
+ initial = new LinkedList();
+ }
+
+ /**
+ * Set initial list of services into tracker before ServiceEvents begin
+ * to be received.
+ *
+ * This method must be called from ServiceTracker.open while
+ * synchronized on this object in the same synchronized block as the
+ * addServiceListener call.
+ *
+ * @param references The initial list of services to be tracked.
+ */
+ protected void setInitialServices(ServiceReference[] references) {
+ if (references == null) {
+ return;
+ }
+ int size = references.length;
+ for (int i = 0; i < size; i++) {
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
+ }
+ initial.add(references[i]);
+ }
+ }
+
+ /**
+ * Track the initial list of services. This is called after
+ * ServiceEvents can begin to be received.
+ *
+ * This method must be called from ServiceTracker.open while not
+ * synchronized on this object after the addServiceListener call.
+ *
+ */
+ protected void trackInitialServices() {
+ while (true) {
+ ServiceReference reference;
+ synchronized (this) {
+ if (initial.size() == 0) {
+ /*
+ * if there are no more inital services
+ */
+ return; /* we are done */
+ }
+ /*
+ * move the first service from the initial list to the
+ * adding list within this synchronized block.
+ */
+ reference = (ServiceReference) initial.removeFirst();
+ if (this.get(reference) != null) {
+ /* if we are already tracking this service */
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
+ }
+ continue; /* skip this service */
+ }
+ if (adding.contains(reference)) {
+ /*
+ * if this service is already in the process of being
+ * added.
+ */
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
+ }
+ continue; /* skip this service */
+ }
+ adding.add(reference);
+ }
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
+ }
+ trackAdding(reference); /*
+ * Begin tracking it. We call
+ * trackAdding since we have already put
+ * the reference in the adding list.
+ */
+ }
+ }
+
+ /**
+ * Called by the owning <code>ServiceTracker</code> object when it is
+ * closed.
+ */
+ protected void close() {
+ closed = true;
+ }
+
+ /**
+ * <code>ServiceListener</code> method for the
+ * <code>ServiceTracker</code> class. This method must NOT be
+ * synchronized to avoid deadlock potential.
+ *
+ * @param event <code>ServiceEvent</code> object from the framework.
+ */
+ public void serviceChanged(ServiceEvent event) {
+ /*
+ * Check if we had a delayed call (which could happen when we
+ * close).
+ */
+ if (closed) {
+ return;
+ }
+ ServiceReference reference = event.getServiceReference();
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ switch (event.getType()) {
+ case ServiceEvent.REGISTERED :
+ case ServiceEvent.MODIFIED :
+ if (listenerFilter != null) { // constructor supplied
+ // filter
+ track(reference);
+ /*
+ * If the customizer throws an unchecked exception, it
+ * is safe to let it propagate
+ */
+ }
+ else { // user supplied filter
+ if (filter.match(reference)) {
+ track(reference);
+ /*
+ * If the customizer throws an unchecked exception,
+ * it is safe to let it propagate
+ */
+ }
+ else {
+ untrack(reference);
+ /*
+ * If the customizer throws an unchecked exception,
+ * it is safe to let it propagate
+ */
+ }
+ }
+ break;
+ case ServiceEvent.UNREGISTERING :
+ untrack(reference);
+ /*
+ * If the customizer throws an unchecked exception, it is
+ * safe to let it propagate
+ */
+ break;
+ }
+ }
+
+ /**
+ * Begin to track the referenced service.
+ *
+ * @param reference Reference to a service to be tracked.
+ */
+ protected void track(ServiceReference reference) {
+ Object object;
+ synchronized (this) {
+ object = this.get(reference);
+ }
+ if (object != null) /* we are already tracking the service */
+ {
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
+ }
+ /* Call customizer outside of synchronized region */
+ customizer.modifiedService(reference, object);
+ /*
+ * If the customizer throws an unchecked exception, it is safe
+ * to let it propagate
+ */
+ return;
+ }
+ synchronized (this) {
+ if (adding.contains(reference)) { /*
+ * if this service is
+ * already in the process of
+ * being added.
+ */
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
+ }
+ return;
+ }
+ adding.add(reference); /* mark this service is being added */
+ }
+
+ trackAdding(reference); /*
+ * call trackAdding now that we have put the
+ * reference in the adding list
+ */
+ }
+
+ /**
+ * Common logic to add a service to the tracker used by track and
+ * trackInitialServices. The specified reference must have been placed
+ * in the adding list before calling this method.
+ *
+ * @param reference Reference to a service to be tracked.
+ */
+ private void trackAdding(ServiceReference reference) {
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
+ }
+ Object object = null;
+ boolean becameUntracked = false;
+ /* Call customizer outside of synchronized region */
+ try {
+ object = customizer.addingService(reference);
+ /*
+ * If the customizer throws an unchecked exception, it will
+ * propagate after the finally
+ */
+ }
+ finally {
+ synchronized (this) {
+ if (adding.remove(reference)) { /*
+ * if the service was not
+ * untracked during the
+ * customizer callback
+ */
+ if (object != null) {
+ this.put(reference, object);
+ modified(); /* increment modification count */
+ notifyAll(); /*
+ * notify any waiters in
+ * waitForService
+ */
+ }
+ }
+ else {
+ becameUntracked = true;
+ }
+ }
+ }
+ /*
+ * The service became untracked during the customizer callback.
+ */
+ if (becameUntracked) {
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
+ }
+ /* Call customizer outside of synchronized region */
+ customizer.removedService(reference, object);
+ /*
+ * If the customizer throws an unchecked exception, it is safe
+ * to let it propagate
+ */
+ }
+ }
+
+ /**
+ * Discontinue tracking the referenced service.
+ *
+ * @param reference Reference to the tracked service.
+ */
+ protected void untrack(ServiceReference reference) {
+ Object object;
+ synchronized (this) {
+ if (initial.remove(reference)) { /*
+ * if this service is
+ * already in the list of
+ * initial references to
+ * process
+ */
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
+ }
+ return; /*
+ * we have removed it from the list and it will not
+ * be processed
+ */
+ }
+
+ if (adding.remove(reference)) { /*
+ * if the service is in the
+ * process of being added
+ */
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
+ }
+ return; /*
+ * in case the service is untracked while in the
+ * process of adding
+ */
+ }
+ object = this.remove(reference); /*
+ * must remove from tracker
+ * before calling customizer
+ * callback
+ */
+ if (object == null) { /* are we actually tracking the service */
+ return;
+ }
+ modified(); /* increment modification count */
+ }
+ if (DEBUG) {
+ System.out
+ .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
+ }
+ /* Call customizer outside of synchronized region */
+ customizer.removedService(reference, object);
+ /*
+ * If the customizer throws an unchecked exception, it is safe to
+ * let it propagate
+ */
+ }
+ }
+
+ /**
+ * Subclass of Tracked which implements the AllServiceListener interface.
+ * This class is used by the ServiceTracker if open is called with true.
+ *
+ * @since 1.3
+ */
+ class AllTracked extends Tracked implements AllServiceListener {
+ static final long serialVersionUID = 4050764875305137716L;
+
+ /**
+ * AllTracked constructor.
+ */
+ protected AllTracked() {
+ super();
+ }
+ }
}
\ No newline at end of file
diff --git a/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
index be4459e..a9d7e0f 100644
--- a/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
+++ b/org.osgi/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
@@ -1,84 +1,92 @@
-/*
- * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java,v 1.7 2005/05/13 20:33:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this
- * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
- */
-
-package org.osgi.util.tracker;
-
-import org.osgi.framework.ServiceReference;
-
-/**
- * The <code>ServiceTrackerCustomizer</code> interface allows a
- * <code>ServiceTracker</code> object to customize the service objects that are
- * tracked. The <code>ServiceTrackerCustomizer</code> object is called when a
- * service is being added to the <code>ServiceTracker</code> object. The
- * <code>ServiceTrackerCustomizer</code> can then return an object for the tracked
- * service. The <code>ServiceTrackerCustomizer</code> object is also called when a
- * tracked service is modified or has been removed from the
- * <code>ServiceTracker</code> object.
- *
- * <p>
- * The methods in this interface may be called as the result of a
- * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code> object.
- * Since <code>ServiceEvent</code> s are synchronously delivered by the Framework,
- * it is highly recommended that implementations of these methods do not
- * register (<code>BundleContext.registerService</code>), modify (
- * <code>ServiceRegistration.setProperties</code>) or unregister (
- * <code>ServiceRegistration.unregister</code>) a service while being
- * synchronized on any object.
- *
- * @version $Revision: 1.7 $
- */
-public interface ServiceTrackerCustomizer {
- /**
- * A service is being added to the <code>ServiceTracker</code> object.
- *
- * <p>
- * This method is called before a service which matched the search
- * parameters of the <code>ServiceTracker</code> object is added to it. This
- * method should return the service object to be tracked for this
- * <code>ServiceReference</code> object. The returned service object is stored
- * in the <code>ServiceTracker</code> object and is available from the
- * <code>getService</code> and <code>getServices</code> methods.
- *
- * @param reference Reference to service being added to the
- * <code>ServiceTracker</code> object.
- * @return The service object to be tracked for the
- * <code>ServiceReference</code> object or <code>null</code> if the
- * <code>ServiceReference</code> object should not be tracked.
- */
- public abstract Object addingService(ServiceReference reference);
-
- /**
- * A service tracked by the <code>ServiceTracker</code> object has been
- * modified.
- *
- * <p>
- * This method is called when a service being tracked by the
- * <code>ServiceTracker</code> object has had it properties modified.
- *
- * @param reference Reference to service that has been modified.
- * @param service The service object for the modified service.
- */
- public abstract void modifiedService(ServiceReference reference,
- Object service);
-
- /**
- * A service tracked by the <code>ServiceTracker</code> object has been
- * removed.
- *
- * <p>
- * This method is called after a service is no longer being tracked by the
- * <code>ServiceTracker</code> object.
- *
- * @param reference Reference to service that has been removed.
- * @param service The service object for the removed service.
- */
- public abstract void removedService(ServiceReference reference,
- Object service);
+/*
+ * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java,v 1.9 2006/03/14 01:20:01 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 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.util.tracker;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ServiceTrackerCustomizer</code> interface allows a
+ * <code>ServiceTracker</code> object to customize the service objects that are
+ * tracked. The <code>ServiceTrackerCustomizer</code> object is called when a
+ * service is being added to the <code>ServiceTracker</code> object. The
+ * <code>ServiceTrackerCustomizer</code> can then return an object for the tracked
+ * service. The <code>ServiceTrackerCustomizer</code> object is also called when a
+ * tracked service is modified or has been removed from the
+ * <code>ServiceTracker</code> object.
+ *
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code> object.
+ * Since <code>ServiceEvent</code> s are synchronously delivered by the Framework,
+ * it is highly recommended that implementations of these methods do not
+ * register (<code>BundleContext.registerService</code>), modify (
+ * <code>ServiceRegistration.setProperties</code>) or unregister (
+ * <code>ServiceRegistration.unregister</code>) a service while being
+ * synchronized on any object.
+ *
+ * @version $Revision: 1.9 $
+ */
+public interface ServiceTrackerCustomizer {
+ /**
+ * A service is being added to the <code>ServiceTracker</code> object.
+ *
+ * <p>
+ * This method is called before a service which matched the search
+ * parameters of the <code>ServiceTracker</code> object is added to it. This
+ * method should return the service object to be tracked for this
+ * <code>ServiceReference</code> object. The returned service object is stored
+ * in the <code>ServiceTracker</code> object and is available from the
+ * <code>getService</code> and <code>getServices</code> methods.
+ *
+ * @param reference Reference to service being added to the
+ * <code>ServiceTracker</code> object.
+ * @return The service object to be tracked for the
+ * <code>ServiceReference</code> object or <code>null</code> if the
+ * <code>ServiceReference</code> object should not be tracked.
+ */
+ public Object addingService(ServiceReference reference);
+
+ /**
+ * A service tracked by the <code>ServiceTracker</code> object has been
+ * modified.
+ *
+ * <p>
+ * This method is called when a service being tracked by the
+ * <code>ServiceTracker</code> object has had it properties modified.
+ *
+ * @param reference Reference to service that has been modified.
+ * @param service The service object for the modified service.
+ */
+ public void modifiedService(ServiceReference reference,
+ Object service);
+
+ /**
+ * A service tracked by the <code>ServiceTracker</code> object has been
+ * removed.
+ *
+ * <p>
+ * This method is called after a service is no longer being tracked by the
+ * <code>ServiceTracker</code> object.
+ *
+ * @param reference Reference to service that has been removed.
+ * @param service The service object for the removed service.
+ */
+ public void removedService(ServiceReference reference,
+ Object service);
}
\ No newline at end of file