You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2012/01/05 15:16:38 UTC
svn commit: r1227602 [9/10] - in /karaf/trunk: ./ admin/command/ admin/core/
admin/core/src/test/java/org/apache/karaf/jpm/ admin/management/
deployer/blueprint/ deployer/features/ deployer/kar/ deployer/spring/
deployer/wrap/ diagnostic/command/ diagn...
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/Condition.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/Condition.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/Condition.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/Condition.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). 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.
+ *
+ * @ThreadSafe
+ * @version $Id: 7e80cf578718db713c347568e7d3232010beac0a $
+ */
+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. If this method returns {@code false} (or this
+ * Condition is immutable), then 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 or networks, need to be consulted. <br/>
+ * This method must always return the same value whenever it is called so
+ * that the Conditional Permission Admin can cache its result.
+ *
+ * @return {@code true} to indicate the evaluation must be postponed.
+ * Otherwise, {@code false} if the evaluation can be performed
+ * immediately.
+ */
+ boolean isPostponed();
+
+ /**
+ * Returns whether the Condition is satisfied. This method is only called
+ * for immediate Condition objects or immutable postponed conditions, and
+ * must always be called inside a permission check. Mutable postponed
+ * Condition objects will be called with the grouped version
+ * {@link #isSatisfied(Condition[],Dictionary)} at the end of the permission
+ * check.
+ *
+ * @return {@code true} to indicate the Conditions is satisfied.
+ * Otherwise, {@code false} if the Condition is not satisfied.
+ */
+ boolean isSatisfied();
+
+ /**
+ * Returns whether the Condition is mutable. A Condition can go from mutable
+ * ({@code true}) to immutable ({@code false}) over time but never
+ * from immutable ({@code false}) to mutable ({@code true}).
+ *
+ * @return {@code true} {@link #isSatisfied()} can change. Otherwise,
+ * {@code false} if the value returned by
+ * {@link #isSatisfied()} will not change for this condition.
+ */
+ boolean isMutable();
+
+ /**
+ * Returns whether the specified set of Condition objects are satisfied.
+ * Although this method is not static, it must be implemented as if it
+ * were static. All of the passed Condition objects will be of the same
+ * type and will correspond to the class type of the object on which this
+ * method is invoked. This method must be called inside a permission check
+ * only.
+ *
+ * @param conditions The array of Condition objects, which must all be of
+ * the same class and mutable. The receiver must be one of those
+ * Condition objects.
+ * @param context A Dictionary object that implementors can use to track
+ * state. If this method is invoked multiple times in the same
+ * permission check, 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 invocations are needed.
+ * @return {@code true} if all the Condition objects are satisfied.
+ * Otherwise, {@code false} if one of the Condition objects is
+ * not satisfied.
+ */
+ boolean isSatisfied(Condition conditions[],
+ Dictionary<Object, Object> context);
+}
+
+/**
+ * Package private class used to define the {@link Condition#FALSE} and
+ * {@link Condition#TRUE} constants.
+ *
+ * @Immutable
+ */
+final class BooleanCondition implements Condition {
+ private 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<Object, Object> context) {
+ for (int i = 0, length = conds.length; i < length; i++) {
+ if (!conds[i].isSatisfied())
+ return false;
+ }
+ return true;
+ }
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionInfo.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). 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;
+import java.util.List;
+
+/**
+ * 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}, and the
+ * arguments passed to its constructor.
+ *
+ * <p>
+ * In order for a Condition represented by a {@code ConditionInfo} 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} method that takes a
+ * {@code Bundle} object and a {@code ConditionInfo} object as
+ * arguments. That method must return an object that implements the
+ * {@code Condition} interface.</li>
+ * <li>Implement the {@code Condition} interface and define a public
+ * constructor that takes a {@code Bundle} object and a
+ * {@code ConditionInfo} object as arguments.
+ * </ul>
+ *
+ * @Immutable
+ * @version $Id: dd1d84aa3175b2a2dfec879d04c93887f05161be $
+ */
+public class ConditionInfo {
+ private final String type;
+ private final String[] args;
+
+ /**
+ * Constructs a {@code ConditionInfo} from the specified type and args.
+ *
+ * @param type The fully qualified class name of the Condition represented
+ * by this {@code ConditionInfo}.
+ * @param args The arguments for the Condition. These arguments are
+ * available to the newly created Condition by calling the
+ * {@link #getArgs()} method.
+ * @throws NullPointerException If {@code type} is {@code null}.
+ */
+ public ConditionInfo(String type, String[] args) {
+ this.type = type;
+ this.args = (args != null) ? args.clone() : new String[0];
+ if (type == null) {
+ throw new NullPointerException("type is null");
+ }
+ }
+
+ /**
+ * Constructs a {@code ConditionInfo} object from the specified encoded
+ * {@code ConditionInfo} string. White space in the encoded
+ * {@code ConditionInfo} string is ignored.
+ *
+ * @param encodedCondition The encoded {@code ConditionInfo}.
+ * @see #getEncoded
+ * @throws IllegalArgumentException If the specified
+ * {@code encodedCondition} 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 */
+ List<String> argsList = new ArrayList<String>();
+ 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 = 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} in a form
+ * suitable for restoring this {@code ConditionInfo}.
+ *
+ * <p>
+ * The encoded format is:
+ *
+ * <pre>
+ * [type "arg0" "arg1" ...]
+ * </pre>
+ *
+ * where <i>argN</i> are strings that must be encoded for proper parsing.
+ * Specifically, the {@code "}, {@code \}, carriage return,
+ * and line feed characters must be escaped using {@code \"},
+ * {@code \\}, {@code \r}, and {@code \n}, 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}.
+ */
+ 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}.
+ * The string is created by calling the {@code getEncoded} method on
+ * this {@code ConditionInfo}.
+ *
+ * @return The string representation of this {@code ConditionInfo}.
+ */
+ public String toString() {
+ return getEncoded();
+ }
+
+ /**
+ * Returns the fully qualified class name of the condition represented by
+ * this {@code ConditionInfo}.
+ *
+ * @return The fully qualified class name of the condition represented by
+ * this {@code ConditionInfo}.
+ */
+ public final String getType() {
+ return type;
+ }
+
+ /**
+ * Returns arguments of this {@code ConditionInfo}.
+ *
+ * @return The arguments of this {@code ConditionInfo}. An empty
+ * array is returned if the {@code ConditionInfo} has no
+ * arguments.
+ */
+ public final String[] getArgs() {
+ return args.clone();
+ }
+
+ /**
+ * Determines the equality of two {@code ConditionInfo} objects.
+ *
+ * This method checks that specified object has the same type and args as
+ * this {@code ConditionInfo} object.
+ *
+ * @param obj The object to test for equality with this
+ * {@code ConditionInfo} object.
+ * @return {@code true} if {@code obj} is a
+ * {@code ConditionInfo}, and has the same type and args as
+ * this {@code ConditionInfo} object; {@code false}
+ * 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 h = 31 * 17 + type.hashCode();
+ for (int i = 0; i < args.length; i++) {
+ h = 31 * h + args[i].hashCode();
+ }
+ return h;
+ }
+
+ /**
+ * 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();
+ }
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2010). 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.
+ * Conditional Permissions are conceptually managed in an ordered table called
+ * the Conditional Permission Table.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 887450b65e453145d57197e2db75db0bb2918ef4 $
+ */
+public interface ConditionalPermissionAdmin {
+ /**
+ * Create a new Conditional Permission Info in the Conditional Permission
+ * Table.
+ * <p>
+ * The Conditional Permission Info will be given a unique, never reused
+ * name. This entry will be added at the beginning of the Conditional
+ * Permission Table with an access decision of
+ * {@link ConditionalPermissionInfo#ALLOW ALLOW}.
+ * <p>
+ * Since this method changes the Conditional Permission Table any
+ * {@link ConditionalPermissionUpdate}s that were created prior to calling
+ * this method can no longer be committed.
+ *
+ * @param conditions The conditions that need to be satisfied to enable the
+ * specified permissions. This argument can be {@code null} or
+ * an empty array indicating the specified permissions are not
+ * guarded by any conditions.
+ * @param permissions The permissions that are enabled when the specified
+ * conditions, if any, are satisfied. This argument must not be
+ * {@code null} and must specify at least one permission.
+ * @return The ConditionalPermissionInfo for the specified Conditions and
+ * Permissions.
+ * @throws IllegalArgumentException If no permissions are specified.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}.
+ * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+ * instead.
+ */
+ ConditionalPermissionInfo addConditionalPermissionInfo(
+ ConditionInfo conditions[], PermissionInfo permissions[]);
+
+ /**
+ * Set or create a Conditional Permission Info with a specified name in the
+ * Conditional Permission Table.
+ * <p>
+ * If the specified name is {@code null}, 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. If a new entry was created in the Conditional Permission
+ * Table it will be added at the beginning of the table with an access
+ * decision of {@link ConditionalPermissionInfo#ALLOW ALLOW}.
+ * <p>
+ * Since this method changes the underlying permission table any
+ * {@link ConditionalPermissionUpdate}s that were created prior to calling
+ * this method can no longer be committed.
+ *
+ * @param name The name of the Conditional Permission Info, or
+ * {@code null}.
+ * @param conditions The conditions that need to be satisfied to enable the
+ * specified permissions. This argument can be {@code null} or
+ * an empty array indicating the specified permissions are not
+ * guarded by any conditions.
+ * @param permissions The permissions that are enabled when the specified
+ * conditions, if any, are satisfied. This argument must not be
+ * {@code null} and must specify at least one permission.
+ * @return The ConditionalPermissionInfo for the specified name, Conditions
+ * and Permissions.
+ * @throws IllegalArgumentException If no permissions are specified.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}.
+ * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+ * instead.
+ */
+ ConditionalPermissionInfo setConditionalPermissionInfo(String name,
+ ConditionInfo conditions[], PermissionInfo permissions[]);
+
+ /**
+ * Returns the Conditional Permission Infos from the Conditional Permission
+ * Table.
+ * <p>
+ * The returned Enumeration will return elements in the order they are kept
+ * in the Conditional Permission Table.
+ * <p>
+ * The Enumeration returned is based on a copy of the Conditional Permission
+ * Table and therefore will not throw exceptions if the Conditional
+ * Permission Table is changed during the course of reading elements from
+ * the Enumeration.
+ *
+ * @return An enumeration of the Conditional Permission Infos that are
+ * currently in the Conditional Permission Table.
+ * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+ * instead.
+ */
+ Enumeration<ConditionalPermissionInfo> 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 or
+ * {@code null} if no Conditional Permission Info with the
+ * specified name exists in the Conditional Permission Table.
+ * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+ * instead.
+ */
+ ConditionalPermissionInfo getConditionalPermissionInfo(String name);
+
+ /**
+ * Returns the Access Control Context that corresponds to the specified
+ * signers.
+ *
+ * The returned Access Control Context must act as if its protection domain
+ * came from a bundle that has the following characteristics:
+ * <ul>
+ * <li>It is signed by all of the given signers</li>
+ * <li>It has a bundle id of -1</li>
+ * <li>Its location is the empty string</li>
+ * <li>Its state is UNINSTALLED</li>
+ * <li>It has no headers</li>
+ * <li>It has the empty version (0.0.0)</li>
+ * <li>Its last modified time=0</li>
+ * <li>Many methods will throw {@code IllegalStateException} because the state is UNINSTALLED</li>
+ * <li>All other methods return a {@code null}</li>
+ * </ul>
+ * @param signers The signers for which to return an Access Control Context.
+ * @return An {@code AccessControlContext} that has the Permissions
+ * associated with the signer.
+ */
+ AccessControlContext getAccessControlContext(String[] signers);
+
+ /**
+ * Creates a new update for the Conditional Permission Table. The update is
+ * a working copy of the current Conditional Permission Table. If the
+ * running Conditional Permission Table is modified before commit is called
+ * on the returned update, then the call to commit on the returned update
+ * will fail. That is, the commit method will return false and no change
+ * will be made to the running Conditional Permission Table. There is no
+ * requirement that commit is eventually called on the returned update.
+ *
+ * @return A new update for the Conditional Permission Table.
+ * @since 1.1
+ */
+ ConditionalPermissionUpdate newConditionalPermissionUpdate();
+
+ /**
+ * Creates a new ConditionalPermissionInfo with the specified fields
+ * suitable for insertion into a {@link ConditionalPermissionUpdate}. The
+ * {@code delete} method on {@code ConditionalPermissionInfo}
+ * objects created with this method must throw
+ * UnsupportedOperationException.
+ *
+ * @param name The name of the created
+ * {@code ConditionalPermissionInfo} or {@code null} to
+ * have a unique name generated when the returned
+ * {@code ConditionalPermissionInfo} is committed in an update
+ * to the Conditional Permission Table.
+ * @param conditions The conditions that need to be satisfied to enable the
+ * specified permissions. This argument can be {@code null} or
+ * an empty array indicating the specified permissions are not
+ * guarded by any conditions.
+ * @param permissions The permissions that are enabled when the specified
+ * conditions, if any, are satisfied. This argument must not be
+ * {@code null} and must specify at least one permission.
+ * @param access Access decision. Must be one of the following values:
+ * <ul>
+ * <li>{@link ConditionalPermissionInfo#ALLOW allow}</li>
+ * <li>{@link ConditionalPermissionInfo#DENY deny}</li>
+ * </ul>
+ * The specified access decision value must be evaluated case
+ * insensitively.
+ * @return A {@code ConditionalPermissionInfo} object suitable for
+ * insertion into a {@link ConditionalPermissionUpdate}.
+ * @throws IllegalArgumentException If no permissions are specified or if
+ * the specified access decision is not a valid value.
+ * @since 1.1
+ */
+ ConditionalPermissionInfo newConditionalPermissionInfo(String name,
+ ConditionInfo conditions[], PermissionInfo permissions[],
+ String access);
+
+ /**
+ * Creates a new {@code ConditionalPermissionInfo} from the specified
+ * encoded {@code ConditionalPermissionInfo} string suitable for
+ * insertion into a {@link ConditionalPermissionUpdate}. The
+ * {@code delete} method on {@code ConditionalPermissionInfo}
+ * objects created with this method must throw
+ * UnsupportedOperationException.
+ *
+ * @param encodedConditionalPermissionInfo The encoded
+ * {@code ConditionalPermissionInfo}. White space in the encoded
+ * {@code ConditionalPermissionInfo} is ignored. The access
+ * decision value in the encoded
+ * {@code ConditionalPermissionInfo} must be evaluated case
+ * insensitively. If the encoded
+ * {@code ConditionalPermissionInfo} does not contain the
+ * optional name, {@code null} must be used for the name and a
+ * unique name will be generated when the returned
+ * {@code ConditionalPermissionInfo} is committed in an update
+ * to the Conditional Permission Table.
+ * @return A {@code ConditionalPermissionInfo} object suitable for
+ * insertion into a {@link ConditionalPermissionUpdate}.
+ * @throws IllegalArgumentException If the specified
+ * {@code encodedConditionalPermissionInfo} is not properly
+ * formatted.
+ * @see ConditionalPermissionInfo#getEncoded
+ * @since 1.1
+ */
+ ConditionalPermissionInfo newConditionalPermissionInfo(
+ String encodedConditionalPermissionInfo);
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). 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 list of Permissions guarded by a list of conditions with an access
+ * decision. Instances of this interface are obtained from the Conditional
+ * Permission Admin service.
+ *
+ * @Immutable
+ * @noimplement
+ * @version $Id: ca51e4dd6dfa350959bb2a2e420bdb2c996323e9 $
+ */
+public interface ConditionalPermissionInfo {
+ /**
+ * This string is used to indicate that a row in the Conditional Permission
+ * Table should return an access decision of "allow" if the
+ * conditions are all satisfied and at least one of the permissions is
+ * implied.
+ *
+ * @since 1.1
+ */
+ public final static String ALLOW = "allow";
+
+ /**
+ * This string is used to indicate that a row in the Conditional Permission
+ * Table should return an access decision of "deny" if the
+ * conditions are all satisfied and at least one of the permissions is
+ * implied.
+ *
+ * @since 1.1
+ */
+ public final static String DENY = "deny";
+
+ /**
+ * 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.
+ */
+ ConditionInfo[] getConditionInfos();
+
+ /**
+ * Returns the Permission Infos for the Permissions in this Conditional
+ * Permission Info.
+ *
+ * @return The Permission Infos for the Permissions in this Conditional
+ * Permission Info.
+ */
+ PermissionInfo[] getPermissionInfos();
+
+ /**
+ * Removes this Conditional Permission Info from the Conditional Permission
+ * Table.
+ * <p>
+ * Since this method changes the underlying permission table, any
+ * {@link ConditionalPermissionUpdate}s that were created prior to calling
+ * this method can no longer be committed.
+ *
+ * @throws UnsupportedOperationException If this object was created by
+ * {@link ConditionalPermissionAdmin#newConditionalPermissionInfo}
+ * or obtained from a {@link ConditionalPermissionUpdate}. This
+ * method only functions if this object was obtained from one of the
+ * {@link ConditionalPermissionAdmin} methods deprecated in version
+ * 1.1.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}.
+ * @deprecated Since 1.1. Use
+ * {@link ConditionalPermissionAdmin#newConditionalPermissionUpdate()}
+ * instead to manage the Conditional Permissions.
+ */
+ void delete();
+
+ /**
+ * Returns the name of this Conditional Permission Info.
+ *
+ * @return The name of this Conditional Permission Info. This can be
+ * {@code null} if this Conditional Permission Info was created
+ * without a name.
+ */
+ String getName();
+
+ /**
+ * Returns the access decision for this Conditional Permission Info.
+ *
+ * @return One of the following values:
+ * <ul>
+ * <li>{@link #ALLOW allow} - The access decision is
+ * "allow".</li>
+ * <li>{@link #DENY deny} - The access decision is "deny".
+ * </li>
+ * </ul>
+ * @since 1.1
+ */
+ String getAccessDecision();
+
+ /**
+ * Returns the string encoding of this {@code ConditionalPermissionInfo} in
+ * a form suitable for restoring this {@code ConditionalPermissionInfo}.
+ *
+ * <p>
+ * The encoded format is:
+ *
+ * <pre>
+ * access {conditions permissions} name
+ * </pre>
+ *
+ * where <i>access</i> is the access decision, <i>conditions</i> is zero or
+ * more {@link ConditionInfo#getEncoded() encoded conditions},
+ * <i>permissions</i> is one or more {@link PermissionInfo#getEncoded()
+ * encoded permissions} and <i>name</i> is the name of the
+ * {@code ConditionalPermissionInfo}.
+ *
+ * <p>
+ * <i>name</i> is optional. If <i>name</i> is present in the encoded string,
+ * it must quoted, beginning and ending with {@code "}. The <i>name</i>
+ * value must be encoded for proper parsing. Specifically, the
+ * {@code "}, {@code \}, carriage return, and line feed characters must
+ * be escaped using {@code \"}, {@code \\}, {@code \r}, and {@code \n},
+ * respectively.
+ *
+ * <p>
+ * The encoded string contains no leading or trailing whitespace characters.
+ * A single space character is used between <i>access</i> and <code>{</code>
+ * and between <code>}</code> and <i>name</i>, if <i>name</i> is present.
+ * All encoded conditions and permissions are separated by a single space
+ * character.
+ *
+ * @return The string encoding of this {@code ConditionalPermissionInfo}.
+ * @since 1.1
+ */
+ String getEncoded();
+
+ /**
+ * Returns the string representation of this
+ * {@code ConditionalPermissionInfo}. The string is created by calling
+ * the {@code getEncoded} method on this
+ * {@code ConditionalPermissionInfo}.
+ *
+ * @return The string representation of this
+ * {@code ConditionalPermissionInfo}.
+ * @since 1.1
+ */
+ String toString();
+
+ /**
+ * Determines the equality of two {@code ConditionalPermissionInfo}
+ * objects.
+ *
+ * This method checks that specified object has the same access decision,
+ * conditions, permissions and name as this
+ * {@code ConditionalPermissionInfo} object.
+ *
+ * @param obj The object to test for equality with this
+ * {@code ConditionalPermissionInfo} object.
+ * @return {@code true} if {@code obj} is a
+ * {@code ConditionalPermissionInfo}, and has the same access
+ * decision, conditions, permissions and name as this
+ * {@code ConditionalPermissionInfo} object; {@code false}
+ * otherwise.
+ * @since 1.1
+ */
+ boolean equals(Object obj);
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ * @since 1.1
+ */
+ int hashCode();
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2010). 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.List;
+
+/**
+ * Update the Conditional Permission Table. There may be many update objects in
+ * the system at one time. If commit is called and the Conditional Permission
+ * Table has been modified since this update was created, then the call to
+ * commit will fail and this object should be discarded.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 3b16b47db71fa449d60d5acdcc9f7dddc7679a25 $
+ * @since 1.1
+ */
+public interface ConditionalPermissionUpdate {
+ /**
+ * This method returns the list of {@link ConditionalPermissionInfo}s for
+ * this update. This list is originally based on the Conditional Permission
+ * Table at the time this update was created. The list returned by this
+ * method will be replace the Conditional Permission Table if commit is
+ * called and is successful.
+ * <p>
+ * The {@link ConditionalPermissionInfo#delete delete} method of the
+ * ConditionalPermissionInfos in the list must throw
+ * UnsupportedOperationException.
+ * <p>
+ * The list returned by this method is ordered and the most significant
+ * table entry is the first entry in the list.
+ *
+ * @return A {@code List} of the {@link ConditionalPermissionInfo}s
+ * which represent the Conditional Permissions maintained by this
+ * update. Modifications to this list will not affect the
+ * Conditional Permission Table until successfully committed. The
+ * list may be empty if the Conditional Permission Table was empty
+ * when this update was created.
+ */
+ List<ConditionalPermissionInfo> getConditionalPermissionInfos();
+
+ /**
+ * Commit this update. If no changes have been made to the Conditional
+ * Permission Table since this update was created, then this method will
+ * replace the Conditional Permission Table with this update's Conditional
+ * Permissions. This method may only be successfully called once on this
+ * object.
+ * <p>
+ * If any of the {@link ConditionalPermissionInfo}s in the update list has
+ * {@code null} as a name it will be replaced with a new
+ * {@link ConditionalPermissionInfo} object that has a generated name which
+ * is unique within the list.
+ * <p>
+ * No two entries in this update's Conditional Permissions may have the same
+ * name. Other consistency checks may also be performed. If this update's
+ * Conditional Permissions are determined to be inconsistent in some way
+ * then an {@code IllegalStateException} will be thrown.
+ * <p>
+ * This method returns {@code false} if the commit did not occur
+ * because the Conditional Permission Table has been modified since the
+ * creation of this update.
+ *
+ * @return {@code true} if the commit was successful.
+ * {@code false} if the commit did not occur because the
+ * Conditional Permission Table has been modified since the creation
+ * of this update.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}.
+ * @throws IllegalStateException If this update's Conditional Permissions
+ * are not valid or inconsistent. For example, this update has two
+ * Conditional Permissions in it with the same name.
+ */
+ boolean commit();
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/package-info.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/package-info.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/package-info.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/package-info.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). 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.
+ */
+
+/**
+ * Conditional Permission Admin Package Version 1.1.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.condpermadmin; version="[1.1,2.0)"}
+ *
+ * @version $Id: cb84fc1342d7f8863ec8eae2dd244843246b2fc1 $
+ */
+
+package org.osgi.service.condpermadmin;
Added: karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/packageinfo
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/packageinfo?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/packageinfo (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/condpermadmin/packageinfo Thu Jan 5 14:16:33 2012
@@ -0,0 +1 @@
+version 1.1.1
Added: karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2010). 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} object becomes stale if the package it
+ * references has been updated or removed as a result of calling
+ * {@code PackageAdmin.refreshPackages()}.
+ *
+ * If this object becomes stale, its {@code getName()} and
+ * {@code getVersion()} methods continue to return their original values,
+ * {@code isRemovalPending()} returns {@code true}, and
+ * {@code getExportingBundle()} and {@code getImportingBundles()}
+ * return {@code null}.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @deprecated The PackageAdmin service has been replaced by the
+ * <code>org.osgi.framework.wiring</code> package.
+ * @version $Id: c56b99465e3f62a9808297a47de8cb7edb802119 $
+ */
+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} if this
+ * {@code ExportedPackage} 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} if this
+ * {@code ExportedPackage} object has become stale. The array
+ * will be empty if no bundles are wired to this exported package.
+ */
+ public Bundle[] getImportingBundles();
+
+ /**
+ * Returns the version of this exported package.
+ *
+ * @return The version of this exported package, or {@code null} if
+ * no version information is available.
+ * @deprecated As of 1.2, 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} if the package associated with this
+ * {@code ExportedPackage} object has been exported by a bundle that
+ * has been updated or uninstalled.
+ *
+ * @return {@code true} if the associated package is being exported
+ * by a bundle that has been updated or uninstalled, or if this
+ * {@code ExportedPackage} object has become stale;
+ * {@code false} otherwise.
+ */
+ public boolean isRemovalPending();
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2010). 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.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: a268c3bdc986080fa16bdb2f56ba1d3800d030dd $
+ * @deprecated This service has been replaced by the
+ * <code>org.osgi.framework.wiring</code> package.
+ * @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} 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}
+ * system property as well as any other package exported by the
+ * framework implementation.
+ *
+ * @return An array of exported packages, or {@code null} if the
+ * specified bundle has no exported packages.
+ * @throws IllegalArgumentException If the specified {@code Bundle} was
+ * not created by the same framework instance that registered this
+ * {@code PackageAdmin} service.
+ */
+ 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} 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} 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} bundles that are currently
+ * still exporting packages.
+ *
+ * <li>Each bundle in the graph that is in the {@code ACTIVE} state
+ * will be stopped as described in the {@code Bundle.stop} method.
+ *
+ * <li>Each bundle in the graph that is in the {@code RESOLVED} state
+ * is unresolved and thus moved to the {@code INSTALLED} state. The
+ * effect of this step is that bundles in the graph are no longer
+ * {@code RESOLVED}.
+ *
+ * <li>Each bundle in the graph that is in the {@code UNINSTALLED}
+ * 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} state
+ * prior to Step 2 is started as described in the {@code Bundle.start}
+ * 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} is fired.
+ * </ol>
+ *
+ * <p>
+ * For any exceptions that are thrown during any of these steps, a
+ * {@code FrameworkEvent} of type {@code ERROR} 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} 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]} and the Java
+ * runtime environment supports permissions.
+ * @throws IllegalArgumentException If the specified {@code Bundle}s
+ * were not created by the same framework instance that registered
+ * this {@code PackageAdmin} service.
+ */
+ 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} 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} to resolve all
+ * unresolved bundles installed in the Framework.
+ * @return {@code true} if all specified bundles are resolved;
+ * @throws SecurityException If the caller does not have
+ * {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+ * runtime environment supports permissions.
+ * @throws IllegalArgumentException If the specified {@code Bundle}s
+ * were not created by the same framework instance that registered
+ * this {@code PackageAdmin} service.
+ * @since 1.2
+ */
+ public boolean resolveBundles(Bundle[] bundles);
+
+ /**
+ * Returns an array of required bundles having the specified symbolic name.
+ *
+ * <p>
+ * If {@code null} is specified, then all required bundles will be
+ * returned.
+ *
+ * @param symbolicName The bundle symbolic name or {@code null} for
+ * all required bundles.
+ * @return An array of required bundles or {@code null} 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} 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} 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} 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} is returned.
+ * If no fragments are attached to the specified bundle then
+ * {@code null} is returned.
+ * <p>
+ * This method does not attempt to resolve the specified bundle. If the
+ * specified bundle is not resolved then {@code null} is returned.
+ *
+ * @param bundle The bundle whose attached fragment bundles are to be
+ * returned.
+ * @return An array of fragment bundles or {@code null} if the bundle
+ * does not have any attached fragment bundles or the bundle is not
+ * resolved.
+ * @throws IllegalArgumentException If the specified {@code Bundle} was
+ * not created by the same framework instance that registered this
+ * {@code PackageAdmin} service.
+ * @since 1.2
+ */
+ public Bundle[] getFragments(Bundle bundle);
+
+ /**
+ * Returns the host bundles to which the specified fragment bundle is
+ * attached.
+ *
+ * @param bundle The fragment bundle whose host bundles are to be returned.
+ * @return An array containing the host bundles to which the specified
+ * fragment is attached or {@code null} if the specified bundle
+ * is not a fragment or is not attached to any host bundles.
+ * @throws IllegalArgumentException If the specified {@code Bundle} was
+ * not created by the same framework instance that registered this
+ * {@code PackageAdmin} service.
+ * @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} 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} if the class was not loaded by a bundle class
+ * loader created by the same framework instance that registered
+ * this {@code PackageAdmin} service.
+ * @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} 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.
+ * @throws IllegalArgumentException If the specified {@code Bundle} was
+ * not created by the same framework instance that registered this
+ * {@code PackageAdmin} service.
+ * @since 1.2
+ */
+ public int getBundleType(Bundle bundle);
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). 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} 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()}).
+ *
+ * If this object becomes stale, its {@code getSymbolicName()} and
+ * {@code getVersion()} methods continue to return their original values,
+ * {@code isRemovalPending()} returns true, and {@code getBundle()}
+ * and {@code getRequiringBundles()} return {@code null}.
+ *
+ * @since 1.2
+ * @ThreadSafe
+ * @noimplement
+ * @deprecated The PackageAdmin service has been replaced by the
+ * <code>org.osgi.framework.wiring</code> package.
+ * @version $Id: 1606b0422cae6769b7eedc2d565df61841da1e22 $
+ */
+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} if this
+ * {@code RequiredBundle} 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} if this {@code RequiredBundle} object
+ * has become stale. The array will be empty if no bundles require
+ * this required package.
+ */
+ 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} if the bundle associated with this
+ * {@code RequiredBundle} object has been updated or uninstalled.
+ *
+ * @return {@code true} if the required bundle has been updated or
+ * uninstalled, or if the {@code RequiredBundle} object has
+ * become stale; {@code false} otherwise.
+ */
+ public boolean isRemovalPending();
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/package-info.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/package-info.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/package-info.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/package-info.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). 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 Admin Package Version 1.2.
+ *
+ * <p>
+ * <b>Deprecated.</b>
+ * <i>This package is deprecated and has been replaced by the
+ * {@code org.osgi.framework.wiring} package.</i>
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.packageadmin; version="[1.2,2.0)"}
+ *
+ * @version $Id: b1c7db22b9c84e48d3c6c711f0ed976e825053c9 $
+ */
+
+package org.osgi.service.packageadmin;
Added: karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/packageinfo
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/packageinfo?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/packageinfo (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/packageadmin/packageinfo Thu Jan 5 14:16:33 2012
@@ -0,0 +1 @@
+version 1.2
Added: karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionAdmin.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionAdmin.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionAdmin.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionAdmin.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2010). 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.permissionadmin;
+
+/**
+ * The Permission Admin service allows management agents to manage the
+ * permissions of bundles. There is at most one Permission Admin service present
+ * in the OSGi environment.
+ * <p>
+ * Access to the Permission Admin service is protected by corresponding
+ * {@code ServicePermission}. In addition {@code AdminPermission}
+ * is required to actually set permissions.
+ *
+ * <p>
+ * Bundle permissions are managed using a permission table. A bundle's location
+ * serves as the key into this permission table. The value of a table entry is
+ * the set of permissions (of type {@code PermissionInfo}) granted to
+ * the bundle named by the given location. A bundle may have an entry in the
+ * permission table prior to being installed in the Framework.
+ *
+ * <p>
+ * The permissions specified in {@code setDefaultPermissions} are used as
+ * the default permissions which are granted to all bundles that do not have an
+ * entry in the permission table.
+ *
+ * <p>
+ * Any changes to a bundle's permissions in the permission table will take
+ * effect no later than when bundle's
+ * {@code java.security.ProtectionDomain} is next involved in a
+ * permission check, and will be made persistent.
+ *
+ * <p>
+ * Only permission classes on the system classpath or from an exported package
+ * are considered during a permission check. Additionally, only permission
+ * classes that are subclasses of {@code java.security.Permission} and
+ * define a 2-argument constructor that takes a <i>name </i> string and an
+ * <i>actions </i> string can be used.
+ * <p>
+ * Permissions implicitly granted by the Framework (for example, a bundle's
+ * permission to access its persistent storage area) cannot be changed, and are
+ * not reflected in the permissions returned by {@code getPermissions}
+ * and {@code getDefaultPermissions}.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 91132d707097c085fdb3fb7241c9599335427082 $
+ */
+public interface PermissionAdmin {
+ /**
+ * Gets the permissions assigned to the bundle with the specified location.
+ *
+ * @param location The location of the bundle whose permissions are to be
+ * returned.
+ *
+ * @return The permissions assigned to the bundle with the specified
+ * location, or {@code null} if that bundle has not been
+ * assigned any permissions.
+ */
+ PermissionInfo[] getPermissions(String location);
+
+ /**
+ * Assigns the specified permissions to the bundle with the specified
+ * location.
+ *
+ * @param location The location of the bundle that will be assigned the
+ * permissions.
+ * @param permissions The permissions to be assigned, or {@code null}
+ * if the specified location is to be removed from the permission
+ * table.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}.
+ */
+ void setPermissions(String location, PermissionInfo[] permissions);
+
+ /**
+ * Returns the bundle locations that have permissions assigned to them, that
+ * is, bundle locations for which an entry exists in the permission table.
+ *
+ * @return The locations of bundles that have been assigned any permissions,
+ * or {@code null} if the permission table is empty.
+ */
+ String[] getLocations();
+
+ /**
+ * Gets the default permissions.
+ *
+ * <p>
+ * These are the permissions granted to any bundle that does not have
+ * permissions assigned to its location.
+ *
+ * @return The default permissions, or {@code null} if no default
+ * permissions are set.
+ */
+ PermissionInfo[] getDefaultPermissions();
+
+ /**
+ * Sets the default permissions.
+ *
+ * <p>
+ * These are the permissions granted to any bundle that does not have
+ * permissions assigned to its location.
+ *
+ * @param permissions The default permissions, or {@code null} if the
+ * default permissions are to be removed from the permission table.
+ * @throws SecurityException If the caller does not have
+ * {@code AllPermission}.
+ */
+ void setDefaultPermissions(PermissionInfo[] permissions);
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionInfo.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionInfo.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionInfo.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/PermissionInfo.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2010). 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.permissionadmin;
+
+/**
+ * Permission representation used by the Permission Admin service.
+ *
+ * <p>
+ * This class encapsulates three pieces of information: a Permission <i>type
+ * </i> (class name), which must be a subclass of
+ * {@code java.security.Permission}, and the <i>name</i> and <i>actions</i>
+ * arguments passed to its constructor.
+ *
+ * <p>
+ * In order for a permission represented by a {@code PermissionInfo} to be
+ * instantiated and considered during a permission check, its Permission class
+ * must be available from the system classpath or an exported package. This
+ * means that the instantiation of a permission represented by a
+ * {@code PermissionInfo} may be delayed until the package containing its
+ * Permission class has been exported by a bundle.
+ *
+ * @Immutable
+ * @version $Id: b9516d07ada162fb8fc750f09e1e3a686189c46b $
+ */
+public class PermissionInfo {
+ private final String type;
+ private final String name;
+ private final String actions;
+
+ /**
+ * Constructs a {@code PermissionInfo} from the specified type, name,
+ * and actions.
+ *
+ * @param type The fully qualified class name of the permission represented
+ * by this {@code PermissionInfo}. The class must be a subclass
+ * of {@code java.security.Permission} and must define a
+ * 2-argument constructor that takes a <i>name</i> string and an
+ * <i>actions</i> string.
+ *
+ * @param name The permission name that will be passed as the first argument
+ * to the constructor of the {@code Permission} class identified
+ * by {@code type}.
+ *
+ * @param actions The permission actions that will be passed as the second
+ * argument to the constructor of the {@code Permission} class
+ * identified by {@code type}.
+ *
+ * @throws NullPointerException If {@code type} is {@code null}.
+ * @throws IllegalArgumentException If {@code action} is not
+ * {@code null} and {@code name} is {@code null}.
+ */
+ public PermissionInfo(String type, String name, String actions) {
+ this.type = type;
+ this.name = name;
+ this.actions = actions;
+ if (type == null) {
+ throw new NullPointerException("type is null");
+ }
+ if ((name == null) && (actions != null)) {
+ throw new IllegalArgumentException("name missing");
+ }
+ }
+
+ /**
+ * Constructs a {@code PermissionInfo} object from the specified
+ * encoded {@code PermissionInfo} string. White space in the encoded
+ * {@code PermissionInfo} string is ignored.
+ *
+ *
+ * @param encodedPermission The encoded {@code PermissionInfo}.
+ * @see #getEncoded
+ * @throws IllegalArgumentException If the specified
+ * {@code encodedPermission} is not properly formatted.
+ */
+ public PermissionInfo(String encodedPermission) {
+ if (encodedPermission == null) {
+ throw new NullPointerException("missing encoded permission");
+ }
+ if (encodedPermission.length() == 0) {
+ throw new IllegalArgumentException("empty encoded permission");
+ }
+ String parsedType = null;
+ String parsedName = null;
+ String parsedActions = null;
+ try {
+ char[] encoded = encodedPermission.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 parenthesis");
+ }
+ 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");
+ }
+ parsedType = new String(encoded, begin, pos - begin);
+
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+
+ /* type may be followed by name which is quoted and encoded */
+ if (encoded[pos] == '"') {
+ pos++;
+ begin = pos;
+ while (encoded[pos] != '"') {
+ if (encoded[pos] == '\\') {
+ pos++;
+ }
+ pos++;
+ }
+ parsedName = unescapeString(encoded, begin, pos);
+ pos++;
+
+ if (Character.isWhitespace(encoded[pos])) {
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+
+ /*
+ * name may be followed by actions which is quoted and
+ * encoded
+ */
+ if (encoded[pos] == '"') {
+ pos++;
+ begin = pos;
+ while (encoded[pos] != '"') {
+ if (encoded[pos] == '\\') {
+ pos++;
+ }
+ pos++;
+ }
+ parsedActions = unescapeString(encoded, begin, pos);
+ pos++;
+
+ /* skip whitespace */
+ while (Character.isWhitespace(encoded[pos])) {
+ pos++;
+ }
+ }
+ }
+ }
+
+ /* 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 parenthesis");
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ throw new IllegalArgumentException("parsing terminated abruptly");
+ }
+
+ type = parsedType;
+ name = parsedName;
+ actions = parsedActions;
+ }
+
+ /**
+ * Returns the string encoding of this {@code PermissionInfo} in a form
+ * suitable for restoring this {@code PermissionInfo}.
+ *
+ * <p>
+ * The encoded format is:
+ *
+ * <pre>
+ * (type)
+ * </pre>
+ *
+ * or
+ *
+ * <pre>
+ * (type "name")
+ * </pre>
+ *
+ * or
+ *
+ * <pre>
+ * (type "name" "actions")
+ * </pre>
+ *
+ * where <i>name</i> and <i>actions</i> are strings that must be encoded for
+ * proper parsing. Specifically, the {@code "},{@code \},
+ * carriage return, and line feed characters must be escaped using
+ * {@code \"}, {@code \\},{@code \r}, and
+ * {@code \n}, respectively.
+ *
+ * <p>
+ * The encoded string contains no leading or trailing whitespace characters.
+ * A single space character is used between <i>type</i> and
+ * "<i>name</i>" and between "<i>name</i>" and
+ * "<i>actions</i>".
+ *
+ * @return The string encoding of this {@code PermissionInfo}.
+ */
+ public final String getEncoded() {
+ StringBuffer output = new StringBuffer(
+ 8
+ + type.length()
+ + ((((name == null) ? 0 : name.length()) + ((actions == null) ? 0
+ : actions.length())) << 1));
+ output.append('(');
+ output.append(type);
+ if (name != null) {
+ output.append(" \"");
+ escapeString(name, output);
+ if (actions != null) {
+ output.append("\" \"");
+ escapeString(actions, output);
+ }
+ output.append('\"');
+ }
+ output.append(')');
+ return output.toString();
+ }
+
+ /**
+ * Returns the string representation of this {@code PermissionInfo}.
+ * The string is created by calling the {@code getEncoded} method on
+ * this {@code PermissionInfo}.
+ *
+ * @return The string representation of this {@code PermissionInfo}.
+ */
+ public String toString() {
+ return getEncoded();
+ }
+
+ /**
+ * Returns the fully qualified class name of the permission represented by
+ * this {@code PermissionInfo}.
+ *
+ * @return The fully qualified class name of the permission represented by
+ * this {@code PermissionInfo}.
+ */
+ public final String getType() {
+ return type;
+ }
+
+ /**
+ * Returns the name of the permission represented by this
+ * {@code PermissionInfo}.
+ *
+ * @return The name of the permission represented by this
+ * {@code PermissionInfo}, or {@code null} if the
+ * permission does not have a name.
+ */
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the actions of the permission represented by this
+ * {@code PermissionInfo}.
+ *
+ * @return The actions of the permission represented by this
+ * {@code PermissionInfo}, or {@code null} if the
+ * permission does not have any actions associated with it.
+ */
+ public final String getActions() {
+ return actions;
+ }
+
+ /**
+ * Determines the equality of two {@code PermissionInfo} objects.
+ *
+ * This method checks that specified object has the same type, name and
+ * actions as this {@code PermissionInfo} object.
+ *
+ * @param obj The object to test for equality with this
+ * {@code PermissionInfo} object.
+ * @return {@code true} if {@code obj} is a
+ * {@code PermissionInfo}, and has the same type, name and
+ * actions as this {@code PermissionInfo} object;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof PermissionInfo)) {
+ return false;
+ }
+ PermissionInfo other = (PermissionInfo) obj;
+ if (!type.equals(other.type) || ((name == null) ^ (other.name == null))
+ || ((actions == null) ^ (other.actions == null))) {
+ return false;
+ }
+ if (name != null) {
+ if (actions != null) {
+ return name.equals(other.name) && actions.equals(other.actions);
+ }
+ else {
+ return name.equals(other.name);
+ }
+ }
+ else {
+ return true;
+ }
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode() {
+ int h = 31 * 17 + type.hashCode();
+ if (name != null) {
+ h = 31 * h + name.hashCode();
+ if (actions != null) {
+ h = 31 * h + actions.hashCode();
+ }
+ }
+ return h;
+ }
+
+ /**
+ * 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();
+ }
+}
Added: karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/package-info.java
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/package-info.java?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/package-info.java (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/package-info.java Thu Jan 5 14:16:33 2012
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). 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.
+ */
+
+/**
+ * Permission Admin Package Version 1.2.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.permissionadmin; version="[1.2,2.0)"}
+ *
+ * @version $Id: 4e7435396ab10ff2d4f5cce1edbffc3b0ccd5e84 $
+ */
+
+package org.osgi.service.permissionadmin;
Added: karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/packageinfo
URL: http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/packageinfo?rev=1227602&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/packageinfo (added)
+++ karaf/trunk/main/src/main/java/org/osgi/service/permissionadmin/packageinfo Thu Jan 5 14:16:33 2012
@@ -0,0 +1 @@
+version 1.2