aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.policy; aoqi@0: aoqi@0: import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion; aoqi@0: import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages; aoqi@0: import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; aoqi@0: import java.util.Arrays; aoqi@0: import java.util.Collection; aoqi@0: import java.util.Collections; aoqi@0: import java.util.Iterator; aoqi@0: import java.util.LinkedList; aoqi@0: import java.util.List; aoqi@0: import java.util.Set; aoqi@0: import java.util.TreeSet; aoqi@0: import javax.xml.namespace.QName; aoqi@0: aoqi@0: /** aoqi@0: * A policy represents normalized policy as a wrapper of available policy alternatives represented by aoqi@0: * child {@link AssertionSet AssertionSets}. aoqi@0: * aoqi@0: * @author Fabian Ritzmann, Marek Potociar aoqi@0: */ aoqi@0: public class Policy implements Iterable { aoqi@0: /** aoqi@0: * A string constant used in package private constructor to customize the object's toString() method output. aoqi@0: */ aoqi@0: private static final String POLICY_TOSTRING_NAME = "policy"; aoqi@0: aoqi@0: /** aoqi@0: * Constant represents empty list of assertion sets. This represents the content of a 'NULL' policy - a policy with aoqi@0: * no alternatives. The constant supports memory effective creation of 'NULL' policy objects. aoqi@0: */ aoqi@0: private static final List NULL_POLICY_ASSERTION_SETS = Collections.unmodifiableList(new LinkedList()); aoqi@0: aoqi@0: /** aoqi@0: * Constant represents list of assertion sets with single empty assertion set. This represents the content of aoqi@0: * an 'EMPTY' policy - a policy with a single empty alternative. The constant supports memory effective creation aoqi@0: * of 'EMPTY' policy objects. aoqi@0: */ aoqi@0: private static final List EMPTY_POLICY_ASSERTION_SETS = Collections.unmodifiableList(new LinkedList(Arrays.asList(new AssertionSet[] {AssertionSet.emptyAssertionSet()}))); aoqi@0: aoqi@0: /** aoqi@0: * Constant represents empty vocabulary of a 'NULL' or 'EMPTY' policies. The constant supports memory effective aoqi@0: * creation of 'NULL' and 'EMPTY' policy objects. aoqi@0: */ aoqi@0: private static final Set EMPTY_VOCABULARY = Collections.unmodifiableSet(new TreeSet(PolicyUtils.Comparison.QNAME_COMPARATOR)); aoqi@0: aoqi@0: /** aoqi@0: * Constant representation of all 'NULL' policies returned by createNullPolicy() factory method. This is to optimize aoqi@0: * the memory footprint. aoqi@0: */ aoqi@0: private static final Policy ANONYMOUS_NULL_POLICY = new Policy(null, null, NULL_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY); aoqi@0: aoqi@0: /** aoqi@0: * Constant representation of all 'EMPTY' policies returned by createEmptyPolicy() factory method. This constant is aoqi@0: * to optimize the memory footprint. aoqi@0: */ aoqi@0: private static final Policy ANONYMOUS_EMPTY_POLICY = new Policy(null, null, EMPTY_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY); aoqi@0: aoqi@0: /** aoqi@0: * Policy ID holder aoqi@0: */ aoqi@0: private String policyId; aoqi@0: aoqi@0: /** aoqi@0: * Policy name holder aoqi@0: */ aoqi@0: private String name; aoqi@0: aoqi@0: /** aoqi@0: * Namespace version holder aoqi@0: */ aoqi@0: private NamespaceVersion nsVersion; aoqi@0: aoqi@0: /** aoqi@0: * internal collection of policy alternatives aoqi@0: */ aoqi@0: private final List assertionSets; aoqi@0: aoqi@0: /** aoqi@0: * internal collection of policy vocabulary entries (qualified names of all assertion types present in the policy expression) aoqi@0: */ aoqi@0: private final Set vocabulary; aoqi@0: aoqi@0: /** aoqi@0: * immutable version of policy vocabulary that is made available to clients via getter method aoqi@0: */ aoqi@0: private final Collection immutableVocabulary; aoqi@0: aoqi@0: /** aoqi@0: * policy object name used in a toString() method. This ensures that Policy class children can customize aoqi@0: * (via package private Policy constructors) the toString() method without having to override it. aoqi@0: */ aoqi@0: private final String toStringName; aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a 'nothing allowed' aoqi@0: * policy expression. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @return policy instance which represents a 'nothing allowed' (no policy alternatives). aoqi@0: */ aoqi@0: public static Policy createNullPolicy() { aoqi@0: return ANONYMOUS_NULL_POLICY; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a 'anything allowed' aoqi@0: * policy expression. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @return policy instance which represents a 'anything allowed' (empty policy alternative with no plicy aoqi@0: * assertions prescribed). aoqi@0: */ aoqi@0: public static Policy createEmptyPolicy() { aoqi@0: return ANONYMOUS_EMPTY_POLICY; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a 'nothing allowed' aoqi@0: * policy expression. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @return policy instance which represents a 'nothing allowed' (no policy alternatives). aoqi@0: */ aoqi@0: public static Policy createNullPolicy(final String name, final String policyId) { aoqi@0: if (name == null && policyId == null) { aoqi@0: return ANONYMOUS_NULL_POLICY; aoqi@0: } else { aoqi@0: return new Policy(name, policyId, NULL_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a 'nothing allowed' aoqi@0: * policy expression. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param nsVersion Policy namespace version to be used when marshalling the policy expression aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @return policy instance which represents a 'nothing allowed' (no policy alternatives). aoqi@0: */ aoqi@0: public static Policy createNullPolicy(final NamespaceVersion nsVersion, final String name, final String policyId) { aoqi@0: if ((nsVersion == null || nsVersion == NamespaceVersion.getLatestVersion()) && name == null && policyId == null) { aoqi@0: return ANONYMOUS_NULL_POLICY; aoqi@0: } else { aoqi@0: return new Policy(nsVersion, name, policyId, NULL_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a 'anything allowed' aoqi@0: * policy expression. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * aoqi@0: * @return policy instance which represents a 'anything allowed' (empty policy alternative with no plicy aoqi@0: * assertions prescribed). aoqi@0: */ aoqi@0: public static Policy createEmptyPolicy(final String name, final String policyId) { aoqi@0: if (name == null && policyId == null) { aoqi@0: return ANONYMOUS_EMPTY_POLICY; aoqi@0: } else { aoqi@0: return new Policy(name, policyId, EMPTY_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a 'anything allowed' aoqi@0: * policy expression. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param nsVersion Policy namespace version to be used when marshalling the policy expression aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * aoqi@0: * @return policy instance which represents a 'anything allowed' (empty policy alternative with no plicy aoqi@0: * assertions prescribed). aoqi@0: */ aoqi@0: public static Policy createEmptyPolicy(final NamespaceVersion nsVersion, final String name, final String policyId) { aoqi@0: if ((nsVersion == null || nsVersion == NamespaceVersion.getLatestVersion()) && name == null && policyId == null) { aoqi@0: return ANONYMOUS_EMPTY_POLICY; aoqi@0: } else { aoqi@0: return new Policy(nsVersion, name, policyId, EMPTY_POLICY_ASSERTION_SETS, EMPTY_VOCABULARY); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a policy expression with aoqi@0: * alternatives specified by {@code sets} input parameter. If the collection of policy alternatives is null or empty aoqi@0: * an object representing a 'NULL' policy expression is returned. However, in such case it is better to use aoqi@0: * {@link #createNullPolicy()} factory method directly. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. aoqi@0: * aoqi@0: * @return policy instance which represents the policy with given alternatives. aoqi@0: */ aoqi@0: public static Policy createPolicy(final Collection sets) { aoqi@0: if (sets == null || sets.isEmpty()) { aoqi@0: return createNullPolicy(); aoqi@0: } else { aoqi@0: return new Policy(POLICY_TOSTRING_NAME, sets); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a policy expression with aoqi@0: * alternatives specified by {@code sets} input parameter. If the collection of policy alternatives is null or empty aoqi@0: * an object representing a 'NULL' policy expression is returned. However, in such case it is better to use aoqi@0: * {@link #createNullPolicy(String, String)} factory method directly. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. aoqi@0: * aoqi@0: * @return policy instance which represents the policy with given alternatives. aoqi@0: */ aoqi@0: public static Policy createPolicy(final String name, final String policyId, final Collection sets) { aoqi@0: if (sets == null || sets.isEmpty()) { aoqi@0: return createNullPolicy(name, policyId); aoqi@0: } else { aoqi@0: return new Policy(POLICY_TOSTRING_NAME, name, policyId, sets); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates an immutable policy instance which represents a policy expression with aoqi@0: * alternatives specified by {@code sets} input parameter. If the collection of policy alternatives is null or empty aoqi@0: * an object representing a 'NULL' policy expression is returned. However, in such case it is better to use aoqi@0: * {@link #createNullPolicy(String, String)} factory method directly. The policy is created using the latest namespace version supported. aoqi@0: * aoqi@0: * @param nsVersion Policy namespace version to be used when marshalling the policy expression aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. aoqi@0: * aoqi@0: * @return policy instance which represents the policy with given alternatives. aoqi@0: */ aoqi@0: public static Policy createPolicy(NamespaceVersion nsVersion, final String name, final String policyId, final Collection sets) { aoqi@0: if (sets == null || sets.isEmpty()) { aoqi@0: return createNullPolicy(nsVersion, name, policyId); aoqi@0: } else { aoqi@0: return new Policy(nsVersion, POLICY_TOSTRING_NAME, name, policyId, sets); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * A most flexible policy object constructor that allows private creation of policy objects and direct setting aoqi@0: * of all its attributes. aoqi@0: * aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @param assertionSets represents the collection of policy alternatives of the policy object created. The list is directly aoqi@0: * assigned to the policy object internal attribute. Subsequent manipulations on the collection must be handled with aoqi@0: * care. aoqi@0: * @param vocabulary represents the vocabulary of the policy object. Subsequent manipulations on the collection aoqi@0: * must be handled with care. aoqi@0: */ aoqi@0: private Policy(final String name, final String policyId, final List assertionSets, final Set vocabulary) { aoqi@0: this.nsVersion = NamespaceVersion.getLatestVersion(); aoqi@0: this.toStringName = POLICY_TOSTRING_NAME; aoqi@0: this.name = name; aoqi@0: this.policyId = policyId; aoqi@0: this.assertionSets = assertionSets; aoqi@0: this.vocabulary = vocabulary; aoqi@0: this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output aoqi@0: * customization. aoqi@0: * aoqi@0: * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the aoqi@0: * toString() method to identify the object. aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The aoqi@0: * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed. aoqi@0: */ aoqi@0: Policy(final String toStringName, final Collection sets) { aoqi@0: this.nsVersion = NamespaceVersion.getLatestVersion(); aoqi@0: this.toStringName = toStringName; aoqi@0: aoqi@0: if (sets == null || sets.isEmpty()) { aoqi@0: this.assertionSets = NULL_POLICY_ASSERTION_SETS; aoqi@0: this.vocabulary = EMPTY_VOCABULARY; aoqi@0: this.immutableVocabulary = EMPTY_VOCABULARY; aoqi@0: } else { aoqi@0: this.assertionSets = new LinkedList(); aoqi@0: this.vocabulary = new TreeSet(PolicyUtils.Comparison.QNAME_COMPARATOR); aoqi@0: this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary); aoqi@0: aoqi@0: addAll(sets); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output aoqi@0: * customization. aoqi@0: * aoqi@0: * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the aoqi@0: * toString() method to identify the object. aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The aoqi@0: * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed. aoqi@0: */ aoqi@0: Policy(final String toStringName, final String name, final String policyId, final Collection sets) { aoqi@0: this(toStringName, sets); aoqi@0: this.name = name; aoqi@0: this.policyId = policyId; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * A most flexible policy object constructor that allows private creation of policy objects and direct setting aoqi@0: * of all its attributes. aoqi@0: * aoqi@0: * @param nsVersion Policy namespace version to be used when marshalling the policy expression aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @param assertionSets represents the collection of policy alternatives of the policy object created. The list is directly aoqi@0: * assigned to the policy object internal attribute. Subsequent manipulations on the collection must be handled with aoqi@0: * care. aoqi@0: * @param vocabulary represents the vocabulary of the policy object. Subsequent manipulations on the collection aoqi@0: * must be handled with care. aoqi@0: */ aoqi@0: private Policy(final NamespaceVersion nsVersion, final String name, final String policyId, final List assertionSets, final Set vocabulary) { aoqi@0: this.nsVersion = nsVersion; aoqi@0: this.toStringName = POLICY_TOSTRING_NAME; aoqi@0: this.name = name; aoqi@0: this.policyId = policyId; aoqi@0: this.assertionSets = assertionSets; aoqi@0: this.vocabulary = vocabulary; aoqi@0: this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output aoqi@0: * customization. aoqi@0: * aoqi@0: * @param nsVersion Policy namespace version to be used when marshalling the policy expression aoqi@0: * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the aoqi@0: * toString() method to identify the object. aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The aoqi@0: * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed. aoqi@0: */ aoqi@0: Policy(final NamespaceVersion nsVersion, final String toStringName, final Collection sets) { aoqi@0: this.nsVersion = nsVersion; aoqi@0: this.toStringName = toStringName; aoqi@0: aoqi@0: if (sets == null || sets.isEmpty()) { aoqi@0: this.assertionSets = NULL_POLICY_ASSERTION_SETS; aoqi@0: this.vocabulary = EMPTY_VOCABULARY; aoqi@0: this.immutableVocabulary = EMPTY_VOCABULARY; aoqi@0: } else { aoqi@0: this.assertionSets = new LinkedList(); aoqi@0: this.vocabulary = new TreeSet(PolicyUtils.Comparison.QNAME_COMPARATOR); aoqi@0: this.immutableVocabulary = Collections.unmodifiableCollection(this.vocabulary); aoqi@0: aoqi@0: addAll(sets); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructor that should be overridden by child implementation. The constructor allows for easy toString() output aoqi@0: * customization. aoqi@0: * aoqi@0: * @param nsVersion Policy namespace version to be used when marshalling the policy expression aoqi@0: * @param toStringName a general name of the object (such as 'policy' or 'nested policy') that will be used in the aoqi@0: * toString() method to identify the object. aoqi@0: * @param name global URI of the policy. May be {@code null}. aoqi@0: * @param policyId local URI of the policy. May be {@code null}. aoqi@0: * @param sets represents the collection of policy alternatives of the policy object created. During the creation of aoqi@0: * the new policy object, the content of the alternatives collection is copied into an internal policy object structure, aoqi@0: * thus any subsequent operations on the collection will have no impact on the newly constructed policy object. The aoqi@0: * collection may be {@code null} or empty. In such case a 'NULL' policy object is constructed. aoqi@0: */ aoqi@0: Policy(final NamespaceVersion nsVersion, final String toStringName, final String name, final String policyId, final Collection sets) { aoqi@0: this(nsVersion, toStringName, sets); aoqi@0: this.name = name; aoqi@0: this.policyId = policyId; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Adds single alternative to the internal alternatives set of the policy object. aoqi@0: * aoqi@0: * @param set assertion set (policy alternative) object to be added. May be {@code null}; in such case the method aoqi@0: * returns false. aoqi@0: * aoqi@0: * @return {@code true} or {@code false} depending on whether the new alternative was added to the policy object or not. aoqi@0: */ aoqi@0: private boolean add(final AssertionSet set) { aoqi@0: if (set == null) { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: if (this.assertionSets.contains(set)) { aoqi@0: return false; aoqi@0: } else { aoqi@0: this.assertionSets.add(set); aoqi@0: this.vocabulary.addAll(set.getVocabulary()); aoqi@0: return true; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Adds all alternatives from the input collection of assertion sets to the policy object's internal set of alternatives. aoqi@0: * The policy object's vocabulary structure is updated as well. aoqi@0: * aoqi@0: * @param sets collection of new alternatives. Must NOT be {@code null} or empty. The check for null or empty input aoqi@0: * parameter is performed with help of {@code assert} keyword, thus during the testing and development of this class aoqi@0: * {@code -ea} switch should be turned on for this class. aoqi@0: * aoqi@0: * @return {@code true} if all elements in the input collection were added to internal structure, {@code false} otherwise. aoqi@0: */ aoqi@0: private boolean addAll(final Collection sets) { aoqi@0: assert (sets != null && !sets.isEmpty()) : LocalizationMessages.WSP_0036_PRIVATE_METHOD_DOES_NOT_ACCEPT_NULL_OR_EMPTY_COLLECTION(); aoqi@0: aoqi@0: boolean result = true; aoqi@0: for (AssertionSet set : sets) { aoqi@0: result &= add(set); // this is here to ensure that vocabulary is built correctly as well aoqi@0: } aoqi@0: Collections.sort(this.assertionSets); aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: Collection getContent() { aoqi@0: return assertionSets; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the policy identifier that serves as a local relative policy URI. aoqi@0: * aoqi@0: * @return policy identifier - a local relative policy URI. If no policy identifier is set, returns {@code null}. aoqi@0: */ aoqi@0: public String getId() { aoqi@0: return policyId; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the policy name that serves as a global policy URI. aoqi@0: * aoqi@0: * @return policy name - a global policy URI. If no policy name is set, returns {@code null}. aoqi@0: */ aoqi@0: public String getName() { aoqi@0: return name; aoqi@0: } aoqi@0: aoqi@0: public NamespaceVersion getNamespaceVersion() { aoqi@0: return nsVersion; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the policy ID or if that is null the policy name. May return null aoqi@0: * if both attributes are null. aoqi@0: * aoqi@0: * @see #getId() aoqi@0: * @see #getName() aoqi@0: * @return The policy ID if it was set, or the name or null if no attribute was set. aoqi@0: */ aoqi@0: public String getIdOrName() { aoqi@0: if (policyId != null) { aoqi@0: return policyId; aoqi@0: } aoqi@0: return name; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Method returns how many policy alternatives this policy instance contains. aoqi@0: * aoqi@0: * @return number of policy alternatives contained in this policy instance aoqi@0: */ aoqi@0: public int getNumberOfAssertionSets() { aoqi@0: return assertionSets.size(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * A policy usually contains one or more assertion sets. Each assertion set aoqi@0: * corresponds to a policy alternative as defined by WS-Policy. aoqi@0: * aoqi@0: * @return An iterator to iterate through all contained assertion sets aoqi@0: */ aoqi@0: public Iterator iterator() { aoqi@0: return assertionSets.iterator(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns {@code true} if the policy instance represents "nothing allowed" policy expression aoqi@0: * aoqi@0: * @return {@code true} if the policy instance represents "nothing allowed" policy expression, {@code false} otherwise. aoqi@0: */ aoqi@0: public boolean isNull() { aoqi@0: return assertionSets.size() == 0; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns {@code true} if the policy instance represents "anything allowed" policy expression aoqi@0: * aoqi@0: * @return {@code true} if the policy instance represents "anything allowed" policy expression, {@code false} otherwise. aoqi@0: */ aoqi@0: public boolean isEmpty() { aoqi@0: return assertionSets.size() == 1 && assertionSets.get(0).isEmpty(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns true if the policy contains the assertion names with specified namespace in its vocabulary aoqi@0: * aoqi@0: * @param namespaceUri the assertion namespace URI (identifying assertion domain) aoqi@0: * @return {@code true}, if an assertion with the given name could be found in the policy vocabulary {@code false} otherwise. aoqi@0: */ aoqi@0: public boolean contains(final String namespaceUri) { aoqi@0: for (QName entry : vocabulary) { aoqi@0: if (entry.getNamespaceURI().equals(namespaceUri)) { aoqi@0: return true; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Retrieves the vocabulary of this policy expression. The vocabulary is represented by an immutable collection of aoqi@0: * unique QName objects. Each of those objects represents single assertion type contained in the policy. aoqi@0: * aoqi@0: * @return immutable collection of assertion types contained in the policy (a policy vocabulary). aoqi@0: */ aoqi@0: public Collection getVocabulary() { aoqi@0: return immutableVocabulary; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Determines if the policy instance contains the assertion with the name specified in its vocabulary. aoqi@0: * aoqi@0: * @param assertionName the name of the assertion to be tested. aoqi@0: * aoqi@0: * @return {@code true} if the assertion with the specified name is part of the policy instance's vocabulary, aoqi@0: * {@code false} otherwise. aoqi@0: */ aoqi@0: public boolean contains(final QName assertionName) { aoqi@0: return vocabulary.contains(assertionName); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * An {@code Object.equals(Object obj)} method override. aoqi@0: */ aoqi@0: @Override aoqi@0: public boolean equals(final Object obj) { aoqi@0: if (this == obj) { aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: if (!(obj instanceof Policy)) { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: final Policy that = (Policy) obj; aoqi@0: aoqi@0: boolean result = true; aoqi@0: aoqi@0: result = result && this.vocabulary.equals(that.vocabulary); aoqi@0: result = result && this.assertionSets.size() == that.assertionSets.size() && this.assertionSets.containsAll(that.assertionSets); aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * An {@code Object.hashCode()} method override. aoqi@0: */ aoqi@0: @Override aoqi@0: public int hashCode() { aoqi@0: int result = 17; aoqi@0: aoqi@0: result = 37 * result + vocabulary.hashCode(); aoqi@0: result = 37 * result + assertionSets.hashCode(); aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * An {@code Object.toString()} method override. aoqi@0: */ aoqi@0: @Override aoqi@0: public String toString() { aoqi@0: return toString(0, new StringBuffer()).toString(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * A helper method that appends indented string representation of this instance to the input string buffer. aoqi@0: * aoqi@0: * @param indentLevel indentation level to be used. aoqi@0: * @param buffer buffer to be used for appending string representation of this instance aoqi@0: * @return modified buffer containing new string representation of the instance aoqi@0: */ aoqi@0: StringBuffer toString(final int indentLevel, final StringBuffer buffer) { aoqi@0: final String indent = PolicyUtils.Text.createIndent(indentLevel); aoqi@0: final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1); aoqi@0: final String innerDoubleIndent = PolicyUtils.Text.createIndent(indentLevel + 2); aoqi@0: aoqi@0: buffer.append(indent).append(toStringName).append(" {").append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("namespace version = '").append(nsVersion.name()).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("id = '").append(policyId).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("name = '").append(name).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: aoqi@0: buffer.append(innerIndent).append("vocabulary {").append(PolicyUtils.Text.NEW_LINE); aoqi@0: if (vocabulary.isEmpty()) { aoqi@0: buffer.append(innerDoubleIndent).append("no entries").append(PolicyUtils.Text.NEW_LINE); aoqi@0: } else { aoqi@0: int index = 1; aoqi@0: for (QName entry : vocabulary) { aoqi@0: buffer.append(innerDoubleIndent).append(index++).append(". entry = '").append(entry.getNamespaceURI()).append(':').append(entry.getLocalPart()).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: } aoqi@0: } aoqi@0: buffer.append(innerIndent).append('}').append(PolicyUtils.Text.NEW_LINE); aoqi@0: aoqi@0: if (assertionSets.isEmpty()) { aoqi@0: buffer.append(innerIndent).append("no assertion sets").append(PolicyUtils.Text.NEW_LINE); aoqi@0: } else { aoqi@0: for (AssertionSet set : assertionSets) { aoqi@0: set.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: buffer.append(indent).append('}'); aoqi@0: aoqi@0: return buffer; aoqi@0: } aoqi@0: }