/*
 * $Date$
 *
 * Copyright (c) OSGi Alliance (2004, 2007). 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 $Revision$
 */
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 invocations 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 private 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;
	}

}

@@ -54,9 +54,9 @@
  200
-7
+8
 ). A
@@ -1503,20 +1503,16 @@
 %3E if the
-%0A%09 *
  evaluat
@@ -1514,16 +1514,20 @@
 aluation
+%0A%09 *
  of the 
@@ -1566,36 +1566,32 @@
 l the end of the
-%0A%09 *
  permission chec
@@ -1592,16 +1592,20 @@
 n check.
+%0A%09 *
  If this
@@ -1644,20 +1644,16 @@
 e%3E, this
-%0A%09 *
  Conditi
@@ -1670,16 +1670,20 @@
  able to
+%0A%09 *
  directl
@@ -1717,20 +1717,16 @@
 sfied()%7D
-%0A%09 *
  method.
@@ -1741,16 +1741,20 @@
 r words,
+%0A%09 *
  isSatis
@@ -1793,20 +1793,16 @@
 since no
-%0A%09 *
  externa
@@ -1819,16 +1819,20 @@
  such as
+%0A%09 *
  for exa
@@ -2268,36 +2268,24 @@
 ition is not
-%0A%09 *        
  satisfied.%0A
@@ -3463,32 +3463,43 @@
 s are satisfied.
+ Otherwise,
 %0A%09 *         Oth
@@ -3490,35 +3490,24 @@
 %0A%09 *        
- Otherwise,
  %3Ccode%3Efalse
@@ -3545,28 +3545,16 @@
 s is not
-%0A%09 *        
  satisfi
@@ -3801,17 +3801,25 @@
 ition %7B%0A
-
 %09
+private 
 final bo

mark final field private