Commit 7d9316f3 authored by cdanger's avatar cdanger

Merge branch 'release/15.0.0'

parents 93d52fa1 bf708d6e
......@@ -2,6 +2,27 @@
All notable changes to this project are documented in this file following the [Keep a CHANGELOG](http://keepachangelog.com) conventions. This project adheres to [Semantic Versioning](http://semver.org).
## 15.0.0
### Added
- Classes from authzforce-ce-core-pdp-engine, which may be useful to PEP implementations (PEPs should not depend on authzforce-ce-core-pdp-engine except if using an embedded PDP):
- `StandardAttributeValueFactories` (for mapping standard Java types or XACML datatypes into AuthzForce data model)
- `ImmutableAttributeValueFactoryRegistry` (required by the previous one)
- `BasePdpExtensionRegistry` (required by the previous one).
- `AttributeValueFactoryRegistry#getCompatibleFactory(Class)` method: used in unit tests.
- `AttributeValueFactoryRegistry#newAttributeBag(Collection, AttributeSource)`: creates an AttributeBag with a custom AttributeSource
- `PrimitiveDatatype#getInstanceClass()` method: gives the Java class associated to the (XACML) datatype, in AuthzForce data model.
- `XacmlJaxbParsingUtils#parseXacmlJaxbResult(Result)` method: to convert XACML/XML Result into AuthzForce data model's DecisionResult
### Changed
- For more flexibility, genericity and code simplification (better adaptation to non-XML formats such as JSON in particular), AuthzForce data model classes (e.g. `AttributeValue`) no longer extend XACML-schema-derived (JAXB-annotated) classes (e.g. `AttributeValueType`).
- `DecisionCache.Factory#getInstance(...)`: new AttributeValueFactoryRegistry parameter for the decision cache system to be able to create/restore AttributeValues from deserialized data stored or produced by external - possibly remote - systems (e.g. cache storage database).
- `CloseableDesignatedAttributeProvider` (resp. `BaseDesignatedAttributeProvider`) class renamed to `CloseableNamedAttributeProvider` (resp. `BaseNamedAttributeProvider`) to reuse the official term "named attribute" from §7.3 of XACML 3.0 spec.
### Fixed
- IllegalArgumentException for empty XACML anyURI, i.e. `<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI" />`. XACML 3.0 spec's anyURI datatype (annex B.3) is defined by W3C XML schema specification (2004)'s anyURI datatype, itself defined by RFC 2396 and 2732 at IETF. An empty URI is valid according to RFC 2396 (section 4.2), therefore an empty AttributeValue with anyURI datatype must be parsed successfully into an empty value. (Fix to `SimpleValue` class.)
- AuthzForce `IntegerValue`s wrongly considered not equal if created from different Java integer types (for the same value), e.g. `1` (Integer) and `1L` (Long). (Fix to equals() implementations in `GenericInteger` subclasses.)
## 14.0.0
### Changed
- Interface method DecisionCache.Factory#getInstance(...): added EnvironmentProperties parameter to allow passing environment properties to DecisionCache implementations
......
......@@ -6,7 +6,7 @@
<version>7.2.0</version>
</parent>
<artifactId>authzforce-ce-core-pdp-api</artifactId>
<version>14.0.0</version>
<version>15.0.0</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>AuthzForce - Core PDP API</description>
<url>${project.url}</url>
......
......@@ -19,19 +19,21 @@ package org.ow2.authzforce.core.pdp.api;
import java.util.Objects;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
/**
* This class provides a skeletal implementation of the {@link DecisionResult} interface to minimize the effort required to implement this interface. Note that this class only overrides/implements
* {@link #equals(Object)}, {@link #hashCode()} and {@link #getStatus()}.
*/
public abstract class AbstractDecisionResult implements DecisionResult
public abstract class BaseDecisionResult implements DecisionResult
{
private final Status status;
private transient volatile int hashCode = 0;
protected AbstractDecisionResult(final Status status)
protected BaseDecisionResult(final Status status)
{
this.status = status;
}
......@@ -80,12 +82,9 @@ public abstract class AbstractDecisionResult implements DecisionResult
return false;
}
final PepActions otherPepActions = other.getPepActions();
final PepActions thisPepActions = other.getPepActions();
if (thisPepActions == null)
{
return otherPepActions == null || otherPepActions.isEmpty();
}
final ImmutableList<PepAction> otherPepActions = other.getPepActions();
assert otherPepActions != null;
final ImmutableList<PepAction> thisPepActions = this.getPepActions();
return thisPepActions.equals(otherPepActions);
}
......
......@@ -18,9 +18,9 @@
package org.ow2.authzforce.core.pdp.api;
/**
* This is a convenience class to help implement {@link CloseableDesignatedAttributeProvider}.
* This is a convenience class to help implement {@link CloseableNamedAttributeProvider}.
*/
public abstract class BaseDesignatedAttributeProvider implements CloseableDesignatedAttributeProvider
public abstract class BaseNamedAttributeProvider implements CloseableNamedAttributeProvider
{
private static final IllegalArgumentException UNDEF_INSTANCE_ID = new IllegalArgumentException("Undefined Attribute Provider's instance ID");
......@@ -39,7 +39,7 @@ public abstract class BaseDesignatedAttributeProvider implements CloseableDesign
* @throws IllegalArgumentException
* if instanceId null
*/
protected BaseDesignatedAttributeProvider(final String instanceID) throws IllegalArgumentException
protected BaseNamedAttributeProvider(final String instanceID) throws IllegalArgumentException
{
if (instanceID == null)
{
......@@ -75,12 +75,12 @@ public abstract class BaseDesignatedAttributeProvider implements CloseableDesign
return true;
}
if (!(obj instanceof BaseDesignatedAttributeProvider))
if (!(obj instanceof BaseNamedAttributeProvider))
{
return false;
}
final BaseDesignatedAttributeProvider other = (BaseDesignatedAttributeProvider) obj;
final BaseNamedAttributeProvider other = (BaseNamedAttributeProvider) obj;
return this.instanceID.equals(other.instanceID);
}
......
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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.ow2.authzforce.core.pdp.api;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
/**
* This is a base implementation of <code>PdpExtensionRegistry</code>. This should be used as basis to implement (in a final class) an immutable PDP extension registry of a specific type. If you need
* a generic immutable PDP extension registry, see {
*
* @param <T>
* type of extension in this registry
* @version $Id: $
*/
public abstract class BasePdpExtensionRegistry<T extends PdpExtension> implements PdpExtensionRegistry<T>
{
private final Class<? super T> extClass;
private final Map<String, T> extensionsById;
private final transient String toString;
/**
* Instantiates immutable registry from a map.
*
* @param extensionClass
* extension class
* @param extensionsById
* extensions input map; the registry actually creates and uses an immutable copy of this map internally to avoid external modifications on the internal map
*/
protected BasePdpExtensionRegistry(final Class<? super T> extensionClass, final Map<String, ? extends T> extensionsById)
{
assert extensionClass != null && extensionsById != null;
this.extClass = extensionClass;
this.extensionsById = HashCollections.newImmutableMap(extensionsById);
this.toString = this + "( extensionClass= " + extClass.getCanonicalName() + " )";
}
/** {@inheritDoc} */
@Override
public final T getExtension(final String identity)
{
return extensionsById.get(identity);
}
/** {@inheritDoc} */
@Override
public final Set<T> getExtensions()
{
return HashCollections.newImmutableSet(extensionsById.values());
}
private static final class ExtensionToIdFunction<E extends PdpExtension> implements Function<E, String>
{
@Override
public String apply(final E extension) throws NullPointerException
{
assert extension != null;
return Preconditions.checkNotNull(extension, "One of the input extensions is invalid (null)").getId();
}
}
private static final Function<? extends PdpExtension, String> EXTENSION_TO_ID_FUNCTION = new ExtensionToIdFunction<>();
@SuppressWarnings("unchecked")
private static <E extends PdpExtension> Map<String, E> newImmutableMap(final Set<E> extensions)
{
return Maps.uniqueIndex(extensions, (Function<E, String>) EXTENSION_TO_ID_FUNCTION);
}
/**
* Instantiates immutable registry from a set of extensions
*
* @param extensionClass
* extension class (required not null)
* @param extensions
* extensions (required not null)
*/
protected BasePdpExtensionRegistry(final Class<? super T> extensionClass, final Set<? extends T> extensions)
{
this(extensionClass, newImmutableMap(extensions));
}
@Override
public String toString()
{
return toString;
}
}
......@@ -20,24 +20,24 @@ package org.ow2.authzforce.core.pdp.api;
import java.io.Closeable;
import java.util.Set;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
import org.ow2.authzforce.core.pdp.api.value.AttributeValueFactoryRegistry;
import org.ow2.authzforce.xmlns.pdp.ext.AbstractAttributeProvider;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
/**
* {@link DesignatedAttributeProvider} that extends {@link Closeable} because it may may use resources external to the JVM such as a cache, a disk, a connection to a remote server, etc. for retrieving
* the attribute values. Therefore, these resources must be released by calling {@link #close()} when it is no longer needed.
* {@link NamedAttributeProvider} that extends {@link Closeable} because it may may use resources external to the JVM such as a cache, a disk, a connection to a remote server, etc. for retrieving the
* attribute values. Therefore, these resources must be released by calling {@link #close()} when it is no longer needed.
* <p>
* PDP extensions of this type (to support new ways of providing attributes) must implement the {@link FactoryBuilder} class.
*/
public interface CloseableDesignatedAttributeProvider extends DesignatedAttributeProvider, Closeable
public interface CloseableNamedAttributeProvider extends NamedAttributeProvider, Closeable
{
/**
* Intermediate dependency-aware {@link CloseableDesignatedAttributeProvider} factory that can create instances of Attribute Providers from a XML/JAXB configuration, and also provides the
* dependencies (required attributes) (based on this configuration), that any such instance (created by it) will need. Providing the dependencies helps to optimize the {@code depAttrProvider}
* argument to {@link #getInstance(AttributeValueFactoryRegistry, AttributeProvider)} and therefore optimize the created provider's job of finding its own supported attribute values based on other
* attributes in the evaluation context.
* Intermediate dependency-aware {@link CloseableNamedAttributeProvider} factory that can create instances of Attribute Providers from a XML/JAXB configuration, and also provides the dependencies
* (required attributes) (based on this configuration), that any such instance (created by it) will need. Providing the dependencies helps to optimize the {@code depAttrProvider} argument to
* {@link #getInstance(AttributeValueFactoryRegistry, AttributeProvider)} and therefore optimize the created provider's job of finding its own supported attribute values based on other attributes
* in the evaluation context.
*
*/
interface DependencyAwareFactory
......@@ -56,14 +56,14 @@ public interface CloseableDesignatedAttributeProvider extends DesignatedAttribut
/**
* Create Attribute Provider instance
*
* @param attributeValueFactoryRegistry
* registry of Attribute value factories for the Provider to be able to create attribute values
* @param depAttrProvider
* @param attributeValueFactories
* AttributeValue factories for the Provider to be able to create AttributeValues
* @param dependencyAttributeProvider
* Existing Attribute Provider supplying the possibly required attributes that new Providers instantiated here will depend on
*
* @return attribute value in internal model
*/
CloseableDesignatedAttributeProvider getInstance(AttributeValueFactoryRegistry attributeValueFactoryRegistry, AttributeProvider depAttrProvider);
CloseableNamedAttributeProvider getInstance(AttributeValueFactoryRegistry attributeValueFactories, AttributeProvider dependencyAttributeProvider);
}
/**
......@@ -84,13 +84,13 @@ public interface CloseableDesignatedAttributeProvider extends DesignatedAttribut
/**
* Creates an attribute-dependency-aware AttributeProvider factory by inferring attribute dependencies (required attributes) from {@code conf}.
*
* @param conf
* @param configuration
* configuration, that may define what attributes are required (dependency attributes)
* @param environmentProperties
* global PDP configuration environment properties
* @return a factory aware of dependencies (required attributes) possibly inferred from input {@code conf}
*/
public abstract DependencyAwareFactory getInstance(CONF_T conf, EnvironmentProperties environmentProperties);
public abstract DependencyAwareFactory getInstance(CONF_T configuration, EnvironmentProperties environmentProperties);
}
}
......@@ -21,6 +21,7 @@ import java.io.Closeable;
import java.util.List;
import java.util.Map;
import org.ow2.authzforce.core.pdp.api.value.AttributeValueFactoryRegistry;
import org.ow2.authzforce.xmlns.pdp.ext.AbstractDecisionCache;
/**
......@@ -48,10 +49,14 @@ public interface DecisionCache extends Closeable
*
* @param conf
* extension parameters
* @param envProps environment properties
* @param envProps
* environment properties
* @param attributeValueFactories
* AttributeValue factories for the decision cache system to be able to create/restore AttributeValues from deserialized data stored or produced by external - possibly remote -
* systems (e.g. cache storage database). Remember that such attribute values can be present in decision results, typically in AttributeAssignments of Obligations/Advice.
* @return instance of extension
*/
public abstract DecisionCache getInstance(CONF_T conf, EnvironmentProperties envProps);
public abstract DecisionCache getInstance(CONF_T conf, AttributeValueFactoryRegistry attributeValueFactories, EnvironmentProperties envProps);
}
/**
......@@ -71,7 +76,8 @@ public interface DecisionCache extends Closeable
* @param evalCtx
* evaluation context that can be used to save context about any partial/preliminary evaluation done by this decision cache when there is no cached result for {code request} yet. In
* this case, the PDP will call back {@link DecisionCache#put(DecisionRequest, DecisionResult, EvaluationContext)} with this same {@code evalCtx} after the PDP has computed the new
* result. Therefore, this allows the decision cache to reuse some context during an evaluation, and also to do some evaluation itself.
* result. Therefore, this allows the decision cache to reuse some context during an evaluation, and also to do some evaluation itself. This argument may be null if not required, i.e.
* {@link #isEvaluationContextRequired()} returns false.
* @return the corresponding decision result from cache; null if there is no such result in cache.
*/
DecisionResult get(DecisionRequest request, EvaluationContext evalCtx);
......@@ -97,7 +103,7 @@ public interface DecisionCache extends Closeable
* the corresponding decision result
* @param evalCtx
* evaluation context that can be used to retrieve context about any partial/preliminary evaluation done by this decision cache when {@link #get(DecisionRequest, EvaluationContext)} was
* called in the same request context.
* called in the same request context. This argument may be null if not required, i.e. {@link #isEvaluationContextRequired()} returns false.
*/
void put(DecisionRequest request, DecisionResult result, EvaluationContext evalCtx);
......
......@@ -25,18 +25,18 @@ import org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata;
import com.google.common.collect.ImmutableList;
/**
* Result of evaluation of {@link Decidable} (Policy, Rule...) with Obligations/Advice elements packaged together in a {@link PepActions} field.
* Result of evaluation of {@link Decidable} (Policy, Rule...) with PEP actions (Obligations/Advice).
*
*/
public interface DecisionResult extends ExtendedDecision
{
/**
* Get PEP actions (Obligations/Advices), may be null if the decision is neither Permit or Deny
* Get PEP actions (Obligations/Advices), may be empty - but <b>not null</b> - if the decision is neither Permit or Deny
*
* @return PEP actions
*/
ImmutablePepActions getPepActions();
ImmutableList<PepAction> getPepActions();
/**
* Get the list of the "applicable" policy elements (XACML Policy/PolicySet elements) that contributed to this decision.
......@@ -52,7 +52,7 @@ public interface DecisionResult extends ExtendedDecision
* More formally: {@code isApplicable(policy) iff evaluate(policy) != NotApplicable && (policy.parent == null || isApplicable(policy.parent)) }
*
* @return identifiers of policies found applicable for the decision request. Must be null if and only if the decision is NotApplicable. In particular, if the decision is different from
* NotApplicable but no applicable policy is returned (e.g. it was not requested to return such a list in the request), the returned list must be an empty list, not null.
* NotApplicable but no applicable policy is returned (e.g. it was not requested to return such a list in the request), the returned list must be an empty list, <b>not null</b>.
*/
ImmutableList<PrimaryPolicyMetadata> getApplicablePolicies();
......
......@@ -19,21 +19,21 @@ package org.ow2.authzforce.core.pdp.api;
import java.util.Optional;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
import org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
/**
* Factory for creating immutable {@link DecisionResult}s
*
*/
public final class DecisionResults
{
private static final class ImmutableNotApplicableResult extends AbstractDecisionResult
private static final class ImmutableNotApplicableResult extends BaseDecisionResult
{
private transient volatile String toString = null;
......@@ -49,21 +49,21 @@ public final class DecisionResults
{
if (toString == null)
{
toString = "Result( decision= NotApplicable, status=" + getStatus() + " )";
toString = "Result[ decision= NotApplicable, status=" + getStatus() + " ]";
}
return toString;
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return null;
return ImmutableList.of();
}
@Override
public ImmutableList<PrimaryPolicyMetadata> getApplicablePolicies()
{
return null;
return ImmutableList.of();
}
@Override
......@@ -85,7 +85,7 @@ public final class DecisionResults
}
}
private static abstract class ApplicableResult extends AbstractDecisionResult
private static abstract class ApplicableResult extends BaseDecisionResult
{
protected final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList;
......@@ -94,7 +94,7 @@ public final class DecisionResults
{
super(status);
this.applicablePolicyIdList = applicablePolicyIdList == null ? ImmutableList.<PrimaryPolicyMetadata> of() : applicablePolicyIdList;
this.applicablePolicyIdList = applicablePolicyIdList == null ? ImmutableList.<PrimaryPolicyMetadata>of() : applicablePolicyIdList;
}
@Override
......@@ -148,9 +148,9 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return null;
return ImmutableList.of();
}
@Override
......@@ -179,20 +179,20 @@ public final class DecisionResults
private final DecisionType decision;
private final ImmutablePepActions pepActions;
private final ImmutableList<PepAction> pepActions;
private transient volatile String toString = null;
/*
* For permit/deny result
*/
private ImmutableDPResult(final DecisionType decision, final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
private ImmutableDPResult(final DecisionType decision, final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
super(status, applicablePolicyIdList);
assert decision == DecisionType.PERMIT || decision == DecisionType.DENY;
this.decision = decision;
this.pepActions = pepActions == null ? ImmutablePepActions.EMPTY : pepActions;
this.pepActions = pepActions == null ? ImmutableList.of() : pepActions;
}
/** {@inheritDoc} */
......@@ -219,7 +219,7 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return this.pepActions;
}
......@@ -259,7 +259,7 @@ public final class DecisionResults
* list of identifiers of applicable policies that contributed to this result. If not null, the created instance uses only an immutable copy of this list.
* @return permit result, more particularly {@link #SIMPLE_PERMIT} iff {@code status == null && pepActions == null}.
*/
public static DecisionResult getPermit(final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
public static DecisionResult getPermit(final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
if (status == null && (pepActions == null || pepActions.isEmpty()) && (applicablePolicyIdList == null || applicablePolicyIdList.isEmpty()))
{
......@@ -282,7 +282,7 @@ public final class DecisionResults
* list of identifiers of applicable policies that contributed to this result. If not null, the created instance uses only an immutable copy of this list.
* @return deny result, more particularly {@link #SIMPLE_DENY} iff {@code status == null && pepActions == null}.
*/
public static DecisionResult getDeny(final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
public static DecisionResult getDeny(final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
if (status == null && (pepActions == null || pepActions.isEmpty()) && (applicablePolicyIdList == null || applicablePolicyIdList.isEmpty()))
{
......@@ -331,7 +331,7 @@ public final class DecisionResults
* if {@code cause == null}
*/
public static DecisionResult newIndeterminate(final DecisionType extendedIndeterminate, final IndeterminateEvaluationException cause,
final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList) throws IllegalArgumentException
final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList) throws IllegalArgumentException
{
Preconditions.checkNotNull(cause, "No cause defined for Indeterminate result");
return new ImmutableIndeterminateResult(extendedIndeterminate == null ? DecisionType.INDETERMINATE : extendedIndeterminate, cause, applicablePolicyIdList);
......@@ -351,8 +351,8 @@ public final class DecisionResults
* if
* {@code extendedDecision == null || extendedDecision.getDecision() ==null || (extendedDecision.getDecision() == INDETERMINATE && !extendedDecision.getCauseForIndeterminate().isPresent())}
*/
public static DecisionResult getInstance(final ExtendedDecision extendedDecision, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
throws IllegalArgumentException
public static DecisionResult getInstance(final ExtendedDecision extendedDecision, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
throws IllegalArgumentException
{
Preconditions.checkNotNull(extendedDecision, "Undefined extendedDecision");
final DecisionType decision = extendedDecision.getDecision();
......
......@@ -94,7 +94,7 @@ public interface EvaluationContext
/**
* Returns the value of a named attribute available in the request context. Used to evaluate {@link AttributeDesignatorExpression}, ContextSelectorId of {@link AttributeSelectorExpression}, or to
* get values of attributes on which {@link DesignatedAttributeProvider}s depends to resolve their own attributes (e.g. some module may need attribute X, such as a subject ID, as input to resolve
* get values of attributes on which {@link NamedAttributeProvider}s depends to resolve their own attributes (e.g. some module may need attribute X, such as a subject ID, as input to resolve
* attribute Y from an external source, such as subject role from a user database).
*
* @param attributeFQN
......@@ -264,12 +264,11 @@ public interface EvaluationContext
<L extends Listener> L putListener(Class<L> listenerType, L listener);
/**
* Returns the listener the specified class is mapped to, or null if no entry for this class is present. This will only return a value that was bound to this specific class, not a value that may
* have been bound to a subtype.
* Returns the listener the specified class is mapped to. This will only return a value that was bound to this specific class, not a value that may have been bound to a subtype.
*
* @param listenerType
* listener type, used as key to retrieve the listener registered with this type with {@link #putListener(Class, Listener)}
* @return the listener associated with this class
* @return the listener associated with this class, or null if no entry for this class is present
*/
<L extends Listener> L getListener(Class<L> listenerType);
......
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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.ow2.authzforce.core.pdp.api;
import java.util.Objects;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Advice;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Obligation;
import com.google.common.collect.ImmutableList;
/**
* Static immutable {@link PepActions}, e.g. empty actions, or static methods returning immutable {@link PepActions} or
*
*/
public final class ImmutablePepActions implements PepActions
{
// always non-null fields, immutable
private final ImmutableList<Obligation> obligationList;
private final ImmutableList<Advice> adviceList;
private transient volatile int hashCode;
private transient volatile String toString;
private ImmutablePepActions()
{
this.obligationList = ImmutableList.of();
this.adviceList = ImmutableList.of();
this.hashCode = 1;
this.toString = "( obligation_list= null, advice_list= null )";
}
/**
* Instantiates PEP action set from obligations/advice. Not used if there is neither any obligation and nor any advice, in which case the {@link ImmutablePepActions#EMPTY} must be used.
*
* @param obligationList
* obligation list; null if no obligation
* @param adviceList
* advice list; null if no advice
*/
public ImmutablePepActions(final ImmutableList<Obligation> obligationList, final ImmutableList<Advice> adviceList)
{
assert obligationList != null && !obligationList.isEmpty() || adviceList != null && !adviceList.isEmpty();
this.obligationList = obligationList == null ? ImmutableList.<Obligation> of() : obligationList;
this.adviceList = adviceList == null ? ImmutableList.<Advice> of() : adviceList;
this.hashCode = 0;
this.toString = null;
}
/**
* {@inheritDoc}
*
* Get the internal obligation list
*/
@Override
public ImmutableList<Obligation> getObligatory()
{
return obligationList;
}
/**
* {@inheritDoc}
*
* Get the internal advice list
*/
@Override
public ImmutableList<Advice> getAdvisory()
{
return adviceList;
}
/** {@inheritDoc} */
@Override
public int hashCode()
{
if (hashCode == 0)
{
hashCode = Objects.hash(this.obligationList, this.adviceList);
}
return hashCode;
}
/** {@inheritDoc} */
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof PepActions))
{
return false;
}
final PepActions other = (PepActions) obj;
return this.obligationList.equals(other.getObligatory()) && this.adviceList.equals(other.getAdvisory());
}
/** {@inheritDoc} */
@Override
public String toString()
{
if (toString == null)
{
toString = "[obligation_list=" + obligationList + ", advice_list=" + adviceList + "]";