feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,397 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.namespace.QName;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.util.LinkedList;
import java.util.List;
/**
* The AssertionSet is a set of assertions. It represents a single policy alternative.
*
* @author Fabian Ritzmann, Marek Potociar
*/
public final class AssertionSet implements Iterable<PolicyAssertion>, Comparable<AssertionSet> {
private static final AssertionSet EMPTY_ASSERTION_SET = new AssertionSet(Collections.unmodifiableList(new LinkedList<PolicyAssertion>()));
/**
* The comparator comapres policy assertions according to their publicly accessible attributes, in the following
* order of attributes:
*
* 1. namespace (not null String)
* 2. local name (not null String)
* 3. value (String): null < "" < "not empty"
* 4. has nested assertions (boolean): false < true
* 5. has nested policy (boolean): false < true
* 6. hashCode comparison
*/
private static final Comparator<PolicyAssertion> ASSERTION_COMPARATOR = new Comparator<PolicyAssertion>() {
public int compare(final PolicyAssertion pa1, final PolicyAssertion pa2) {
if (pa1.equals(pa2)) {
return 0;
}
int result;
result = PolicyUtils.Comparison.QNAME_COMPARATOR.compare(pa1.getName(), pa2.getName());
if (result != 0) {
return result;
}
result = PolicyUtils.Comparison.compareNullableStrings(pa1.getValue(), pa2.getValue());
if (result != 0) {
return result;
}
result = PolicyUtils.Comparison.compareBoolean(pa1.hasNestedAssertions(), pa2.hasNestedAssertions());
if (result != 0) {
return result;
}
result = PolicyUtils.Comparison.compareBoolean(pa1.hasNestedPolicy(), pa2.hasNestedPolicy());
if (result != 0) {
return result;
}
return Math.round(Math.signum(pa1.hashCode() - pa2.hashCode()));
}
};
private final List<PolicyAssertion> assertions;
private final Set<QName> vocabulary = new TreeSet<QName>(PolicyUtils.Comparison.QNAME_COMPARATOR);
private final Collection<QName> immutableVocabulary = Collections.unmodifiableCollection(vocabulary);
private AssertionSet(List<PolicyAssertion> list) {
assert (list != null) : LocalizationMessages.WSP_0037_PRIVATE_CONSTRUCTOR_DOES_NOT_TAKE_NULL();
this.assertions = list;
}
private AssertionSet(final Collection<AssertionSet> alternatives) {
this.assertions = new LinkedList<PolicyAssertion>();
for (AssertionSet alternative : alternatives) {
addAll(alternative.assertions);
}
}
private boolean add(final PolicyAssertion assertion) {
if (assertion == null) {
return false;
}
if (this.assertions.contains(assertion)) {
return false;
} else {
this.assertions.add(assertion);
this.vocabulary.add(assertion.getName());
return true;
}
}
private boolean addAll(final Collection<? extends PolicyAssertion> assertions) {
boolean result = true;
if (assertions != null) {
for (PolicyAssertion assertion : assertions) {
result &= add(assertion); // this is here to ensure that vocabulary is built correctly as well
}
}
return result;
}
/**
* Return all assertions contained in this assertion set.
*
* @return All assertions contained in this assertion set
*/
Collection<PolicyAssertion> getAssertions() {
return assertions;
}
/**
* Retrieves the vocabulary of this policy expression. The vocabulary is represented by an immutable collection of
* unique QName objects. Each of those objects represents single assertion type contained in the assertion set.
*
* @return immutable collection of assertion types contained in the assertion set (a policy vocabulary).
*/
Collection<QName> getVocabulary() {
return immutableVocabulary;
}
/**
* Checks whether this policy alternative is compatible with the provided policy alternative.
*
* @param alternative policy alternative used for compatibility test
* @param mode compatibility mode to be used
* @return {@code true} if the two policy alternatives are compatible, {@code false} otherwise
*/
boolean isCompatibleWith(final AssertionSet alternative, PolicyIntersector.CompatibilityMode mode) {
boolean result = (mode == PolicyIntersector.CompatibilityMode.LAX) || this.vocabulary.equals(alternative.vocabulary);
result = result && this.areAssertionsCompatible(alternative, mode);
result = result && alternative.areAssertionsCompatible(this, mode);
return result;
}
private boolean areAssertionsCompatible(final AssertionSet alternative, PolicyIntersector.CompatibilityMode mode) {
nextAssertion: for (PolicyAssertion thisAssertion : this.assertions) {
if ((mode == PolicyIntersector.CompatibilityMode.STRICT) || !thisAssertion.isIgnorable()) {
for (PolicyAssertion thatAssertion : alternative.assertions) {
if (thisAssertion.isCompatibleWith(thatAssertion, mode)) {
continue nextAssertion;
}
}
return false;
}
}
return true;
}
/**
* Creates and returns new assertion set holding content of all provided policy assertion sets.
* <p/>
* This method should not be used to perform a merge of general Policy instances. A client should be aware of the
* method's result meaning and the difference between merge of Policy instances and merge of AssertionSet instances.
*
*
* @param alternatives collection of provided policy assertion sets which content is to be stored in the assertion set.
* May be {@code null} - empty assertion set is returned in such case.
* @return new instance of assertion set holding the content of all provided policy assertion sets.
*/
public static AssertionSet createMergedAssertionSet(final Collection<AssertionSet> alternatives) {
if (alternatives == null || alternatives.isEmpty()) {
return EMPTY_ASSERTION_SET;
}
final AssertionSet result = new AssertionSet(alternatives);
Collections.sort(result.assertions, ASSERTION_COMPARATOR);
return result;
}
/**
* Creates and returns new assertion set holding a set of provided policy assertions.
*
* @param assertions collection of provided policy assertions to be stored in the assertion set. May be {@code null}.
* @return new instance of assertion set holding the provided policy assertions
*/
public static AssertionSet createAssertionSet(final Collection<? extends PolicyAssertion> assertions) {
if (assertions == null || assertions.isEmpty()) {
return EMPTY_ASSERTION_SET;
}
final AssertionSet result = new AssertionSet(new LinkedList<PolicyAssertion>());
result.addAll(assertions);
Collections.sort(result.assertions, ASSERTION_COMPARATOR);
return result;
}
public static AssertionSet emptyAssertionSet() {
return EMPTY_ASSERTION_SET;
}
/**
* Returns an iterator over a set of child policy assertion objects.
*
* @return policy assertion Iterator.
*/
public Iterator<PolicyAssertion> iterator() {
return this.assertions.iterator();
}
/**
* Searches for assertions with given name. Only assertions that are contained as immediate children of the assertion set are
* searched, i.e. nested policies are not searched.
*
* @param name The fully qualified name of searched assertion
* @return List of all assertions matching the requested name. If no assertions are found, the returned list is empty
* (i.e. {@code null} value is never returned).
*/
public Collection<PolicyAssertion> get(final QName name) {
final List<PolicyAssertion> matched = new LinkedList<PolicyAssertion>();
if (vocabulary.contains(name)) {
// we iterate the assertion set only if we are sure we contain such assertion name in our vocabulary
for (PolicyAssertion assertion : assertions) {
if (assertion.getName().equals(name)) {
matched.add(assertion);
}
}
}
return matched;
}
/**
* Returns {@code true} if this assertion set contains no assertions.
*
* @return {@code true} if this assertion set contains no assertions.
*/
public boolean isEmpty() {
return assertions.isEmpty();
}
/**
* Returns true if the assertion set contains the assertion name specified in its vocabulary
*
* @param assertionName the fully qualified name of the assertion
* @return {@code true}, if an assertion with the given name could be found in the assertion set vocabulary {@code false} otherwise.
*/
public boolean contains(final QName assertionName) {
return vocabulary.contains(assertionName);
}
/**
* An {@code Comparable<T>.compareTo(T o)} interface method implementation.
* @param that other alternative to compare with
*/
public int compareTo(final AssertionSet that) {
if (this.equals(that)) {
return 0;
}
// comparing vocabularies
final Iterator<QName> vIterator1 = this.getVocabulary().iterator();
final Iterator<QName> vIterator2 = that.getVocabulary().iterator();
while (vIterator1.hasNext()) {
final QName entry1 = vIterator1.next();
if (vIterator2.hasNext()) {
final QName entry2 = vIterator2.next();
final int result = PolicyUtils.Comparison.QNAME_COMPARATOR.compare(entry1, entry2);
if (result != 0) {
return result;
}
} else {
return 1; // we have more entries in this vocabulary
}
}
if (vIterator2.hasNext()) {
return -1; // we have more entries in that vocabulary
}
// vocabularies are equal => comparing assertions
final Iterator<PolicyAssertion> pIterator1 = this.getAssertions().iterator();
final Iterator<PolicyAssertion> pIterator2 = that.getAssertions().iterator();
while (pIterator1.hasNext()) {
final PolicyAssertion pa1 = pIterator1.next();
if (pIterator2.hasNext()) {
final PolicyAssertion pa2 = pIterator2.next();
final int result = ASSERTION_COMPARATOR.compare(pa1, pa2);
if (result != 0) {
return result;
}
} else {
return 1; // we have more entries in this assertion set
}
}
if (pIterator2.hasNext()) {
return -1; // we have more entries in that assertion set
}
// seems like objects are very simmilar although not equal => we must not return 0 otherwise the TreeSet
// holding this element would discard the newly added element. Thus we return that the first argument is
// greater than second (just because it is first...)
return 1;
}
/**
* An {@code Object.equals(Object obj)} method override.
*/
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof AssertionSet)) {
return false;
}
final AssertionSet that = (AssertionSet) obj;
boolean result = true;
result = result && this.vocabulary.equals(that.vocabulary);
result = result && this.assertions.size() == that.assertions.size() && this.assertions.containsAll(that.assertions);
return result;
}
/**
* An {@code Object.hashCode()} method override.
*/
public int hashCode() {
int result = 17;
result = 37 * result + vocabulary.hashCode();
result = 37 * result + assertions.hashCode();
return result;
}
/**
* An {@code Object.toString()} method override.
*/
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
buffer.append(indent).append("assertion set {").append(PolicyUtils.Text.NEW_LINE);
if (assertions.isEmpty()) {
buffer.append(innerIndent).append("no assertions").append(PolicyUtils.Text.NEW_LINE);
} else {
for (PolicyAssertion assertion : assertions) {
assertion.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE);
}
}
buffer.append(indent).append('}');
return buffer;
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionValidator;
import static com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages.WSP_0076_NO_SERVICE_PROVIDERS_FOUND;
import java.util.Collection;
import java.util.LinkedList;
/**
* Provides methods for assertion validation.
*
* @author Marek Potociar (marek.potociar at sun.com)
* @author Fabian Ritzmann
*/
public class AssertionValidationProcessor {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(AssertionValidationProcessor.class);
private final Collection<PolicyAssertionValidator> validators = new LinkedList<PolicyAssertionValidator>();
/**
* This constructor instantiates the object with a set of dynamically
* discovered PolicyAssertionValidators.
*
* @throws PolicyException Thrown if the set of dynamically discovered
* PolicyAssertionValidators is empty.
*/
private AssertionValidationProcessor() throws PolicyException {
this(null);
}
/**
* This constructor adds the given set of policy validators to the dynamically
* discovered PolicyAssertionValidators.
*
* This constructor is intended to be used by the JAX-WS com.sun.xml.internal.ws.policy.api.ValidationProcessor.
*
* @param policyValidators A set of PolicyAssertionValidators. May be null
* @throws PolicyException Thrown if the set of given PolicyAssertionValidators
* and dynamically discovered PolicyAssertionValidators is empty.
*/
protected AssertionValidationProcessor(final Collection<PolicyAssertionValidator> policyValidators)
throws PolicyException {
for(PolicyAssertionValidator validator : PolicyUtils.ServiceProvider.load(PolicyAssertionValidator.class)) {
validators.add(validator);
}
if (policyValidators != null) {
for (PolicyAssertionValidator validator : policyValidators) {
validators.add(validator);
}
}
if (validators.size() == 0) {
throw LOGGER.logSevereException(new PolicyException(WSP_0076_NO_SERVICE_PROVIDERS_FOUND(PolicyAssertionValidator.class.getName())));
}
}
/**
* Factory method that returns singleton instance of the class.
*
* This method is only intended to be used by code that has no dependencies on
* JAX-WS. Otherwise use com.sun.xml.internal.ws.api.policy.ValidationProcessor.
*
* @return singleton An instance of the class.
* @throws PolicyException If instantiation failed.
*/
public static AssertionValidationProcessor getInstance() throws PolicyException {
return new AssertionValidationProcessor();
}
/**
* Validates fitness of the {@code assertion} on the client side.
*
* return client side {@code assertion} fitness
* @param assertion The assertion to be validated.
* @return The fitness of the assertion on the client side.
* @throws PolicyException If validation failed.
*/
public PolicyAssertionValidator.Fitness validateClientSide(final PolicyAssertion assertion) throws PolicyException {
PolicyAssertionValidator.Fitness assertionFitness = PolicyAssertionValidator.Fitness.UNKNOWN;
for ( PolicyAssertionValidator validator : validators ) {
assertionFitness = assertionFitness.combine(validator.validateClientSide(assertion));
if (assertionFitness == PolicyAssertionValidator.Fitness.SUPPORTED) {
break;
}
}
return assertionFitness;
}
/**
* Validates fitness of the {@code assertion} on the server side.
*
* return server side {@code assertion} fitness
* @param assertion The assertion to be validated.
* @return The fitness of the assertion on the server side.
* @throws PolicyException If validation failed.
*/
public PolicyAssertionValidator.Fitness validateServerSide(final PolicyAssertion assertion) throws PolicyException {
PolicyAssertionValidator.Fitness assertionFitness = PolicyAssertionValidator.Fitness.UNKNOWN;
for (PolicyAssertionValidator validator : validators) {
assertionFitness = assertionFitness.combine(validator.validateServerSide(assertion));
if (assertionFitness == PolicyAssertionValidator.Fitness.SUPPORTED) {
break;
}
}
return assertionFitness;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
import java.util.Collection;
/**
* Complex assertion is an abstract class that serves as a base class for any assertion
* that <b>MAY</b> contain nested policies.
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public abstract class ComplexAssertion extends PolicyAssertion {
private final NestedPolicy nestedPolicy;
protected ComplexAssertion() {
super();
this.nestedPolicy = NestedPolicy.createNestedPolicy(AssertionSet.emptyAssertionSet());
}
protected ComplexAssertion(final AssertionData data, final Collection<? extends PolicyAssertion> assertionParameters, final AssertionSet nestedAlternative) {
super(data, assertionParameters);
AssertionSet nestedSet = (nestedAlternative != null) ? nestedAlternative : AssertionSet.emptyAssertionSet();
this.nestedPolicy = NestedPolicy.createNestedPolicy(nestedSet);
}
@Override
public final boolean hasNestedPolicy() {
return true;
}
@Override
public final NestedPolicy getNestedPolicy() {
return nestedPolicy;
}
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionValidator.Fitness;
import java.util.Collection;
import java.util.LinkedList;
/**
* Contains static methods for policy alternative selection. Given policy map is changed so that
* each effective policy contains at most one policy alternative. Uses domain
* specific @see com.sun.xml.internal.ws.policy.spi.PolicySelector
* to find out whether particular policy assertion is actually supported.
*
* If you are using JAX-WS, use the com.sun.xml.internal.ws.api.policy.AlternativeSelector
* instead of this class.
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
* @author Fabian Ritzmann
*/
public class EffectiveAlternativeSelector {
private enum AlternativeFitness {
UNEVALUATED {
AlternativeFitness combine(final Fitness assertionFitness) {
switch (assertionFitness) {
case UNKNOWN:
return UNKNOWN;
case UNSUPPORTED:
return UNSUPPORTED;
case SUPPORTED:
return SUPPORTED;
case INVALID:
return INVALID;
default:
return UNEVALUATED;
}
}
},
INVALID {
AlternativeFitness combine(final Fitness assertionFitness) {
return INVALID;
}
},
UNKNOWN {
AlternativeFitness combine(final Fitness assertionFitness) {
switch (assertionFitness) {
case UNKNOWN:
return UNKNOWN;
case UNSUPPORTED:
return UNSUPPORTED;
case SUPPORTED:
return PARTIALLY_SUPPORTED;
case INVALID:
return INVALID;
default:
return UNEVALUATED;
}
}
},
UNSUPPORTED {
AlternativeFitness combine(final Fitness assertionFitness) {
switch (assertionFitness) {
case UNKNOWN:
case UNSUPPORTED:
return UNSUPPORTED;
case SUPPORTED:
return PARTIALLY_SUPPORTED;
case INVALID:
return INVALID;
default:
return UNEVALUATED;
}
}
},
PARTIALLY_SUPPORTED {
AlternativeFitness combine(final Fitness assertionFitness) {
switch (assertionFitness) {
case UNKNOWN:
case UNSUPPORTED:
case SUPPORTED:
return PARTIALLY_SUPPORTED;
case INVALID:
return INVALID;
default:
return UNEVALUATED;
}
}
},
SUPPORTED_EMPTY {
AlternativeFitness combine(final Fitness assertionFitness) {
// will not localize - this exception may not occur if there is no programatic error in this class
throw new UnsupportedOperationException("Combine operation was called unexpectedly on 'SUPPORTED_EMPTY' alternative fitness enumeration state.");
}
},
SUPPORTED {
AlternativeFitness combine(final Fitness assertionFitness) {
switch (assertionFitness) {
case UNKNOWN:
case UNSUPPORTED:
return PARTIALLY_SUPPORTED;
case SUPPORTED:
return SUPPORTED;
case INVALID:
return INVALID;
default:
return UNEVALUATED;
}
}
};
abstract AlternativeFitness combine(Fitness assertionFitness);
}
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(EffectiveAlternativeSelector.class);
/**
* Does the selection for policy map bound to given modifier.
*
* If you are using JAX-WS, use the com.sun.xml.internal.ws.api.policy.AlternativeSelector
* instead of this class.
*
* @param modifier Holds the policy map
* @throws PolicyException Most likely an internal error if a policy could not be read or set on the policy map
* @see EffectivePolicyModifier which the map is bound to
*/
public static void doSelection(final EffectivePolicyModifier modifier) throws PolicyException {
final AssertionValidationProcessor validationProcessor = AssertionValidationProcessor.getInstance();
selectAlternatives(modifier, validationProcessor);
}
/**
* This method is intended to be called by extension classes that need to
* override the behavior of {@link #doSelection}.
*
* @param modifier
* @param validationProcessor
* @throws PolicyException
*/
protected static void selectAlternatives(final EffectivePolicyModifier modifier,
final AssertionValidationProcessor validationProcessor)
throws PolicyException {
final PolicyMap map = modifier.getMap();
for (PolicyMapKey mapKey : map.getAllServiceScopeKeys()) {
final Policy oldPolicy = map.getServiceEffectivePolicy(mapKey);
modifier.setNewEffectivePolicyForServiceScope(mapKey, selectBestAlternative(oldPolicy, validationProcessor));
}
for (PolicyMapKey mapKey : map.getAllEndpointScopeKeys()) {
final Policy oldPolicy = map.getEndpointEffectivePolicy(mapKey);
modifier.setNewEffectivePolicyForEndpointScope(mapKey, selectBestAlternative(oldPolicy, validationProcessor));
}
for (PolicyMapKey mapKey : map.getAllOperationScopeKeys()) {
final Policy oldPolicy = map.getOperationEffectivePolicy(mapKey);
modifier.setNewEffectivePolicyForOperationScope(mapKey, selectBestAlternative(oldPolicy, validationProcessor));
}
for (PolicyMapKey mapKey : map.getAllInputMessageScopeKeys()) {
final Policy oldPolicy = map.getInputMessageEffectivePolicy(mapKey);
modifier.setNewEffectivePolicyForInputMessageScope(mapKey, selectBestAlternative(oldPolicy, validationProcessor));
}
for (PolicyMapKey mapKey : map.getAllOutputMessageScopeKeys()) {
final Policy oldPolicy = map.getOutputMessageEffectivePolicy(mapKey);
modifier.setNewEffectivePolicyForOutputMessageScope(mapKey, selectBestAlternative(oldPolicy, validationProcessor));
}
for (PolicyMapKey mapKey : map.getAllFaultMessageScopeKeys()) {
final Policy oldPolicy = map.getFaultMessageEffectivePolicy(mapKey);
modifier.setNewEffectivePolicyForFaultMessageScope(mapKey, selectBestAlternative(oldPolicy, validationProcessor));
}
}
private static Policy selectBestAlternative(final Policy policy, final AssertionValidationProcessor validationProcessor) throws PolicyException {
AssertionSet bestAlternative = null;
AlternativeFitness bestAlternativeFitness = AlternativeFitness.UNEVALUATED;
for (AssertionSet alternative : policy) {
AlternativeFitness alternativeFitness = (alternative.isEmpty()) ? AlternativeFitness.SUPPORTED_EMPTY : AlternativeFitness.UNEVALUATED;
for ( PolicyAssertion assertion : alternative ) {
final Fitness assertionFitness = validationProcessor.validateClientSide(assertion);
switch(assertionFitness) {
case UNKNOWN:
case UNSUPPORTED:
case INVALID:
LOGGER.warning(LocalizationMessages.WSP_0075_PROBLEMATIC_ASSERTION_STATE(assertion.getName(), assertionFitness));
break;
default:
break;
}
alternativeFitness = alternativeFitness.combine(assertionFitness);
}
if (bestAlternativeFitness.compareTo(alternativeFitness) < 0) {
// better alternative found
bestAlternative = alternative;
bestAlternativeFitness = alternativeFitness;
}
if (bestAlternativeFitness == AlternativeFitness.SUPPORTED) {
// all assertions supported by at least one selector
break;
}
}
switch (bestAlternativeFitness) {
case INVALID:
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0053_INVALID_CLIENT_SIDE_ALTERNATIVE()));
case UNKNOWN:
case UNSUPPORTED:
case PARTIALLY_SUPPORTED:
LOGGER.warning(LocalizationMessages.WSP_0019_SUBOPTIMAL_ALTERNATIVE_SELECTED(bestAlternativeFitness));
break;
default:
break;
}
Collection<AssertionSet> alternativeSet = null;
if (bestAlternative != null) {
// return a policy containing just the picked alternative
alternativeSet = new LinkedList<AssertionSet>();
alternativeSet.add(bestAlternative);
}
return Policy.createPolicy(policy.getNamespaceVersion(), policy.getName(), policy.getId(), alternativeSet);
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
/**
* The class serves as a policy map mutator that allows for replacement of current effective policies
* stored in the policy map with new effective policy provided by the mutator user.
*
* @author Marek Potociar (marek.potociar@sun.com)
*/
public final class EffectivePolicyModifier extends PolicyMapMutator {
public static EffectivePolicyModifier createEffectivePolicyModifier() {
return new EffectivePolicyModifier();
}
/**
* Ensures that direct instantiation is not possible from outside of the class
*/
private EffectivePolicyModifier() {
// no initialization required
}
/**
* Replaces current effective policy on the service scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter. If no policy was defined for the presented key, the new policy is simply
* stored with the key.
*
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the input parameters is {@code null}
*/
public void setNewEffectivePolicyForServiceScope(
final PolicyMapKey key, final Policy newEffectivePolicy) {
getMap().setNewEffectivePolicyForScope(PolicyMap.ScopeType.SERVICE, key, newEffectivePolicy);
}
/**
* Replaces current effective policy on the endpoint scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter.
*
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the input parameters is {@code null}
*/
public void setNewEffectivePolicyForEndpointScope(
final PolicyMapKey key, final Policy newEffectivePolicy) {
getMap().setNewEffectivePolicyForScope(PolicyMap.ScopeType.ENDPOINT, key, newEffectivePolicy);
}
/**
* Replaces current effective policy on the operation scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter. If no policy was defined for the presented key, the new policy is simply
* stored with the key.
*
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the input parameters is {@code null}
*/
public void setNewEffectivePolicyForOperationScope(
final PolicyMapKey key, final Policy newEffectivePolicy) {
getMap().setNewEffectivePolicyForScope(PolicyMap.ScopeType.OPERATION, key, newEffectivePolicy);
}
/**
* Replaces current effective policy on the input message scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter. If no policy was defined for the presented key, the new policy is simply
* stored with the key.
*
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the input parameters is {@code null}
*/
public void setNewEffectivePolicyForInputMessageScope(
final PolicyMapKey key, final Policy newEffectivePolicy) {
getMap().setNewEffectivePolicyForScope(PolicyMap.ScopeType.INPUT_MESSAGE, key, newEffectivePolicy);
}
/**
* Replaces current effective policy on the output message scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter. If no policy was defined for the presented key, the new policy is simply
* stored with the key.
*
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the input parameters is {@code null}
*/
public void setNewEffectivePolicyForOutputMessageScope(
final PolicyMapKey key, final Policy newEffectivePolicy) {
getMap().setNewEffectivePolicyForScope(PolicyMap.ScopeType.OUTPUT_MESSAGE, key, newEffectivePolicy);
}
/**
* Replaces current effective policy on the fault message scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter. If no policy was defined for the presented key, the new policy is simply
* stored with the key.
*
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the input parameters is {@code null}
*/
public void setNewEffectivePolicyForFaultMessageScope(
final PolicyMapKey key, final Policy newEffectivePolicy) {
getMap().setNewEffectivePolicyForScope(PolicyMap.ScopeType.FAULT_MESSAGE, key, newEffectivePolicy);
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import java.util.Arrays;
import java.util.Iterator;
/**
* A special policy implementation that assures that only no or single policy alternative is possible within this type of policy.
*
* @author Marek Potociar
*/
public final class NestedPolicy extends Policy {
private static final String NESTED_POLICY_TOSTRING_NAME = "nested policy";
private NestedPolicy(final AssertionSet set) {
super(NESTED_POLICY_TOSTRING_NAME, Arrays.asList(new AssertionSet[] { set }));
}
private NestedPolicy(final String name, final String policyId, final AssertionSet set) {
super(NESTED_POLICY_TOSTRING_NAME, name, policyId, Arrays.asList(new AssertionSet[] { set }));
}
static NestedPolicy createNestedPolicy(final AssertionSet set) {
return new NestedPolicy(set);
}
static NestedPolicy createNestedPolicy(final String name, final String policyId, final AssertionSet set) {
return new NestedPolicy(name, policyId, set);
}
/**
* Returns the AssertionSet instance representing a single policy alterantive held wihtin this nested policy object.
* If the nested policy represents a policy with no alternatives (i.e. nothing is allowed) the method returns {@code null}.
*
* @return nested policy alternative represented by AssertionSet object. May return {@code null} in case the nested policy
* represents 'nothing allowed' policy.
*/
public AssertionSet getAssertionSet() {
final Iterator<AssertionSet> iterator = iterator();
if (iterator.hasNext()) {
return iterator.next();
} else {
return null;
}
}
/**
* An {@code Object.equals(Object obj)} method override.
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof NestedPolicy)) {
return false;
}
final NestedPolicy that = (NestedPolicy) obj;
return super.equals(that);
}
@Override
public int hashCode() {
return super.hashCode();
}
/**
* An {@code Object.toString()} method override.
*/
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
@Override
StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
return super.toString(indentLevel, buffer);
}
}

View File

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

View File

@@ -0,0 +1,366 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
import com.sun.xml.internal.ws.policy.sourcemodel.ModelNode;
/**
* Base class for any policy assertion implementations. It defines the common
* interface and provides some default implentation for common policy assertion
* functionality.
* <p/>
* NOTE: Assertion implementers should not extend this class directly. {@link SimpleAssertion}
* or {@link ComplexAssertion} should be used as a base class instead.
*
* @author Marek Potociar (marek.potociar at sun.com)
* @author Fabian Ritzmann
*/
public abstract class PolicyAssertion {
private final AssertionData data;
private AssertionSet parameters;
private NestedPolicy nestedPolicy; // TODO: remove
protected PolicyAssertion() {
this.data = AssertionData.createAssertionData(null);
this.parameters = AssertionSet.createAssertionSet(null);
}
/**
* Creates generic assertionand stores the data specified in input parameters
*
* @param assertionData assertion creation data specifying the details of newly created assertion. May be {@code null}.
* @param assertionParameters collection of assertions parameters of this policy assertion. May be {@code null}.
* @param nestedAlternative assertion set specifying nested policy alternative. May be {@code null}.
*
* @deprecated Non-abstract assertion types should derive from {@link SimpleAssertion}
* or {@link ComplexAssertion} instead. {@link Policy} class will not provide support for
* nested policy alternatives in the future. This responsibility is delegated to
* {@link ComplexAssertion} class instead.
*/
@Deprecated
protected PolicyAssertion(final AssertionData assertionData, final Collection<? extends PolicyAssertion> assertionParameters, final AssertionSet nestedAlternative) {
this.data = assertionData;
if (nestedAlternative != null) {
this.nestedPolicy = NestedPolicy.createNestedPolicy(nestedAlternative);
}
this.parameters = AssertionSet.createAssertionSet(assertionParameters);
}
/**
* Creates generic assertionand stores the data specified in input parameters
*
* @param assertionData assertion creation data specifying the details of newly created assertion
* @param assertionParameters collection of assertions parameters of this policy assertion. May be {@code null}.
*/
protected PolicyAssertion(final AssertionData assertionData, final Collection<? extends PolicyAssertion> assertionParameters) {
if (assertionData == null) {
this.data = AssertionData.createAssertionData(null);
} else {
this.data = assertionData;
}
this.parameters = AssertionSet.createAssertionSet(assertionParameters);
}
/**
* Returns the fully qualified name of the assertion.
*
* @return assertion's fully qualified name.
*/
public final QName getName() {
return data.getName();
}
/**
* Returns the value of the assertion - the character data content contained in the assertion element representation.
*
* @return assertion's value. May return {@code null} if there is no value set for the assertion.
*/
public final String getValue() {
return data.getValue();
}
/**
* Method specifies whether the assertion is otpional or not.
* <p/>
* This is a default implementation that may be overriden. The method returns {@code true} if the {@code wsp:optional} attribute
* is present on the assertion and its value is {@code 'true'}. Otherwise the method returns {@code false}.
*
* @return {@code 'true'} if the assertion is optional. Returns {@code false} otherwise.
*/
public boolean isOptional() {
return data.isOptionalAttributeSet();
}
/**
* Method specifies whether the assertion is ignorable or not.
* <p/>
* This is a default implementation that may be overriden. The method returns {@code true} if the {@code wsp:Ignorable} attribute
* is present on the assertion and its value is {@code 'true'}. Otherwise the method returns {@code false}.
*
* @return {@code 'true'} if the assertion is ignorable. Returns {@code false} otherwise.
*/
public boolean isIgnorable() {
return data.isIgnorableAttributeSet();
}
/**
* Method specifies whether the assertion is private or not. This is specified by our proprietary visibility element.
*
* @return {@code 'true'} if the assertion is marked as private (i.e. should not be marshalled int generated WSDL documents). Returns {@code false} otherwise.
*/
public final boolean isPrivate() {
return data.isPrivateAttributeSet();
}
/**
* Returns the disconnected set of attributes attached to the assertion. Each attribute is represented as a single
* {@code Map.Entry<attributeName, attributeValue>} element.
* <p/>
* 'Disconnected' means, that the result of this method will not be synchronized with any consequent assertion's attribute modification. It is
* also important to notice that a manipulation with returned set of attributes will not have any effect on the actual assertion's
* attributes.
*
* @return disconected set of attributes attached to the assertion.
*/
public final Set<Map.Entry<QName, String>> getAttributesSet() {
return data.getAttributesSet();
}
/**
* Returns the disconnected map of attributes attached to the assertion.
* <p/>
* 'Disconnected' means, that the result of this method will not be synchronized with any consequent assertion's attribute modification. It is
* also important to notice that a manipulation with returned set of attributes will not have any effect on the actual assertion's
* attributes.
*
* @return disconnected map of attributes attached to the assertion.
*/
public final Map<QName, String> getAttributes() {
return data.getAttributes();
}
/**
* Returns the value of an attribute. Returns null if an attribute with the given name does not exist.
*
* @param name The fully qualified name of the attribute
* @return The value of the attribute. Returns {@code null} if there is no such attribute or if it's value is null.
*/
public final String getAttributeValue(final QName name) {
return data.getAttributeValue(name);
}
/**
* Returns the boolean information whether this assertion contains any parameters.
*
* @return {@code true} if the assertion contains parameters. Returns {@code false} otherwise.
*
* @deprecated Use hasParameters() instead
*/
@Deprecated
public final boolean hasNestedAssertions() {
// TODO: remove
return !parameters.isEmpty();
}
/**
* Returns the boolean information whether this assertion contains any parameters.
*
* @return {@code true} if the assertion contains parameters. Returns {@code false} otherwise.
*/
public final boolean hasParameters() {
return !parameters.isEmpty();
}
/**
* Returns the assertion's parameter collection iterator.
*
* @return the assertion's parameter collection iterator.
*
* @deprecated Use getNestedParametersIterator() instead
*/
@Deprecated
public final Iterator<PolicyAssertion> getNestedAssertionsIterator() {
// TODO: remove
return parameters.iterator();
}
/**
* Returns the assertion's parameter collection iterator.
*
* @return the assertion's parameter collection iterator.
*/
public final Iterator<PolicyAssertion> getParametersIterator() {
return parameters.iterator();
}
boolean isParameter() {
return data.getNodeType() == ModelNode.Type.ASSERTION_PARAMETER_NODE;
}
/**
* Returns the boolean information whether this assertion contains nested policy.
*
* @return {@code true} if the assertion contains child (nested) policy. Returns {@code false} otherwise.
*/
public boolean hasNestedPolicy() {
// TODO: make abstract
return getNestedPolicy() != null;
}
/**
* Returns the nested policy if any.
*
* @return the nested policy if the assertion contains a nested policy. Returns {@code null} otherwise.
*/
public NestedPolicy getNestedPolicy() {
// TODO: make abstract
return nestedPolicy;
}
/**
* Casts the assertion to the implementation type. Returns null if that is not
* possible.
*
* @param <T> The implementation type of the assertion.
* @param type The implementation type of the assertion. May not be null.
* @return The instance of the implementation type. Null otherwise.
*/
public <T extends PolicyAssertion> T getImplementation(Class<T> type) {
if (type.isAssignableFrom(this.getClass())) {
return type.cast(this);
}
else {
return null;
}
}
/**
* An {@code Object.toString()} method override.
*/
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
protected StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
buffer.append(indent).append("Assertion[").append(this.getClass().getName()).append("] {").append(PolicyUtils.Text.NEW_LINE);
data.toString(indentLevel + 1, buffer);
buffer.append(PolicyUtils.Text.NEW_LINE);
if (hasParameters()) {
buffer.append(innerIndent).append("parameters {").append(PolicyUtils.Text.NEW_LINE);
for (PolicyAssertion parameter : parameters) {
parameter.toString(indentLevel + 2, buffer).append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(innerIndent).append('}').append(PolicyUtils.Text.NEW_LINE);
} else {
buffer.append(innerIndent).append("no parameters").append(PolicyUtils.Text.NEW_LINE);
}
if (hasNestedPolicy()) {
getNestedPolicy().toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE);
} else {
buffer.append(innerIndent).append("no nested policy").append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(indent).append('}');
return buffer;
}
/**
* Checks whether this policy alternative is compatible with the provided policy alternative.
*
* @param assertion policy alternative used for compatibility test
* @param mode compatibility mode to be used
* @return {@code true} if the two policy alternatives are compatible, {@code false} otherwise
*/
boolean isCompatibleWith(final PolicyAssertion assertion, PolicyIntersector.CompatibilityMode mode) {
boolean result = this.data.getName().equals(assertion.data.getName()) && (this.hasNestedPolicy() == assertion.hasNestedPolicy());
if (result && this.hasNestedPolicy()) {
result = this.getNestedPolicy().getAssertionSet().isCompatibleWith(assertion.getNestedPolicy().getAssertionSet(), mode);
}
return result;
}
/**
* An {@code Object.equals(Object obj)} method override.
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof PolicyAssertion)) {
return false;
}
final PolicyAssertion that = (PolicyAssertion) obj;
boolean result = true;
result = result && this.data.equals(that.data);
result = result && this.parameters.equals(that.parameters);
result = result && ((this.getNestedPolicy() == null) ? ((that.getNestedPolicy() == null) ? true : false) : this.getNestedPolicy().equals(that.getNestedPolicy()));
return result;
}
/**
* An {@code Object.hashCode()} method override.
*/
@Override
public int hashCode() {
int result = 17;
result = 37 * result + data.hashCode();
result = 37 * result + ((hasParameters()) ? 17 : 0);
result = 37 * result + ((hasNestedPolicy()) ? 17 : 0);
return result;
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import javax.xml.namespace.QName;
/**
* Commonly used constants by the policy implementations
*/
public final class PolicyConstants {
/**
* Sun proprietary policy namespace URI
*/
public static final String SUN_POLICY_NAMESPACE_URI = "http://java.sun.com/xml/ns/wsit/policy";
/**
* Sun proprietary policy namespace prefix
*/
public static final String SUN_POLICY_NAMESPACE_PREFIX = "sunwsp";
/**
* Fully qualified name of the SUN's proprietary policy assertion visibility attribute
*/
public static final QName VISIBILITY_ATTRIBUTE = new QName(SUN_POLICY_NAMESPACE_URI, "visibility");
/**
* Recognized value of the SUN's proprietary policy assertion visibility attribute
*/
public static final String VISIBILITY_VALUE_PRIVATE = "private";
/**
* Standard WS-Security Utility namespace URI, used in Policy Id
*/
public static final String WSU_NAMESPACE_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
/**
* Standard WS-Security Utility namespace prefix, used in Policy Id
*/
public static final String WSU_NAMESPACE_PREFIX = "wsu";
/**
* Fully qualified name of the Policy wsu:Id XML attribute
*/
public static final QName WSU_ID = new QName(WSU_NAMESPACE_URI, "Id");
/**
* Standard XML namespace URI
*/
public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
/**
* Fully qualified name of the xml:id policy attribute
*/
public static final QName XML_ID = new QName(XML_NAMESPACE_URI, "id");
/**
* Identifier of the client-side configuration file
*/
public static final String CLIENT_CONFIGURATION_IDENTIFIER = "client";
/**
* XML namespace for management policy assertions
*/
public static final String SUN_MANAGEMENT_NAMESPACE = "http://java.sun.com/xml/ns/metro/management";
/**
* Prevent instantiation of this class.
*/
private PolicyConstants() {
// nothing to initialize
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
/**
* This is a base exception class and thrown when there is an error in the policy processing
*/
public class PolicyException extends Exception {
public PolicyException(String message) {
super(message);
}
public PolicyException(String message, Throwable cause) {
super(message, cause);
}
public PolicyException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import java.util.ArrayList;
/**
* The instance of this class is intended to provide policy intersection mechanism.
*
* @author Marek Potociar (marek.potociar@sun.com)
*/
public final class PolicyIntersector {
static enum CompatibilityMode {
STRICT,
LAX
}
private static final PolicyIntersector STRICT_INTERSECTOR = new PolicyIntersector(CompatibilityMode.STRICT);
private static final PolicyIntersector LAX_INTERSECTOR = new PolicyIntersector(CompatibilityMode.LAX);
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyIntersector.class);
private CompatibilityMode mode;
/**
* Prevents direct instantiation of this class from outside
* @param intersectionMode intersection mode
*/
private PolicyIntersector(CompatibilityMode intersectionMode) {
this.mode = intersectionMode;
}
/**
* Returns a strict policy intersector that can be used to intersect group of policies.
*
* @return policy intersector instance.
*/
public static PolicyIntersector createStrictPolicyIntersector() {
return PolicyIntersector.STRICT_INTERSECTOR;
}
/**
* Returns a strict policy intersector that can be used to intersect group of policies.
*
* @return policy intersector instance.
*/
public static PolicyIntersector createLaxPolicyIntersector() {
return PolicyIntersector.LAX_INTERSECTOR;
}
/**
* Performs intersection on the input collection of policies and returns the resulting (intersected) policy. If input policy
* collection contains only a single policy instance, no intersection is performed and the instance is directly returned
* as a method call result.
*
* @param policies collection of policies to be intersected. Must not be {@code null} nor empty, otherwise exception is thrown.
* @return intersected policy as a result of perfromed policy intersection. A {@code null} value is never returned.
*
* @throws IllegalArgumentException in case {@code policies} argument is either {@code null} or empty collection.
*/
public Policy intersect(final Policy... policies) {
if (policies == null || policies.length == 0) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0056_NEITHER_NULL_NOR_EMPTY_POLICY_COLLECTION_EXPECTED()));
} else if (policies.length == 1) {
return policies[0];
}
// check for "null" and "empty" policy: if such policy is found return "null" policy,
// or if all policies are "empty", return "empty" policy
boolean found = false;
boolean allPoliciesEmpty = true;
NamespaceVersion latestVersion = null;
for (Policy tested : policies) {
if (tested.isEmpty()) {
found = true;
} else {
if (tested.isNull()) {
found = true;
}
allPoliciesEmpty = false;
}
if (latestVersion == null) {
latestVersion = tested.getNamespaceVersion();
} else if (latestVersion.compareTo(tested.getNamespaceVersion()) < 0) {
latestVersion = tested.getNamespaceVersion();
}
if (found && !allPoliciesEmpty) {
return Policy.createNullPolicy(latestVersion, null, null);
}
}
latestVersion = (latestVersion != null) ? latestVersion : NamespaceVersion.getLatestVersion();
if (allPoliciesEmpty) {
return Policy.createEmptyPolicy(latestVersion, null, null);
}
// simple tests didn't lead to final answer => let's performe some intersecting ;)
final List<AssertionSet> finalAlternatives = new LinkedList<AssertionSet>(policies[0].getContent());
final Queue<AssertionSet> testedAlternatives = new LinkedList<AssertionSet>();
final List<AssertionSet> alternativesToMerge = new ArrayList<AssertionSet>(2);
for (int i = 1; i < policies.length; i++) {
final Collection<AssertionSet> currentAlternatives = policies[i].getContent();
testedAlternatives.clear();
testedAlternatives.addAll(finalAlternatives);
finalAlternatives.clear();
AssertionSet testedAlternative;
while ((testedAlternative = testedAlternatives.poll()) != null) {
for (AssertionSet currentAlternative : currentAlternatives) {
if (testedAlternative.isCompatibleWith(currentAlternative, this.mode)) {
alternativesToMerge.add(testedAlternative);
alternativesToMerge.add(currentAlternative);
finalAlternatives.add(AssertionSet.createMergedAssertionSet(alternativesToMerge));
alternativesToMerge.clear();
}
}
}
}
return Policy.createPolicy(latestVersion, null, null, finalAlternatives);
}
}

View File

@@ -0,0 +1,671 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.xml.namespace.QName;
/**
* A PolicyMap holds all policies for a scope.
*
* This map is modeled around WSDL 1.1 policy scopes according to WS-PolicyAttachment. The map holds an information about
* every scope for service, endpoint, operation, and input/output/fault message. It also provide accessibility methods for
* computing and obtaining effective policy on each scope.
*
* TODO: rename createWsdlMessageScopeKey to createWsdlInputOutputMessageScopeKey
*
* @author Fabian Ritzmann
*/
public final class PolicyMap implements Iterable<Policy> {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyMap.class);
private static final PolicyMapKeyHandler serviceKeyHandler = new PolicyMapKeyHandler() {
public boolean areEqual(final PolicyMapKey key1, final PolicyMapKey key2) {
return key1.getService().equals(key2.getService());
}
public int generateHashCode(final PolicyMapKey key) {
int result = 17;
result = 37 * result + key.getService().hashCode();
return result;
}
};
private static final PolicyMapKeyHandler endpointKeyHandler = new PolicyMapKeyHandler() {
public boolean areEqual(final PolicyMapKey key1, final PolicyMapKey key2) {
boolean retVal = true;
retVal = retVal && key1.getService().equals(key2.getService());
retVal = retVal && ((key1.getPort() == null) ? key2.getPort() == null : key1.getPort().equals(key2.getPort()));
return retVal;
}
public int generateHashCode(final PolicyMapKey key) {
int result = 17;
result = 37 * result + key.getService().hashCode();
result = 37 * result + ((key.getPort() == null) ? 0 : key.getPort().hashCode());
return result;
}
};
private static final PolicyMapKeyHandler operationAndInputOutputMessageKeyHandler = new PolicyMapKeyHandler() {
// we use the same algorithm to handle operation and input/output message keys
public boolean areEqual(final PolicyMapKey key1, final PolicyMapKey key2) {
boolean retVal = true;
retVal = retVal && key1.getService().equals(key2.getService());
retVal = retVal && ((key1.getPort() == null) ? key2.getPort() == null : key1.getPort().equals(key2.getPort()));
retVal = retVal && ((key1.getOperation() == null) ? key2.getOperation() == null : key1.getOperation().equals(key2.getOperation()));
return retVal;
}
public int generateHashCode(final PolicyMapKey key) {
int result = 17;
result = 37 * result + key.getService().hashCode();
result = 37 * result + ((key.getPort() == null) ? 0 : key.getPort().hashCode());
result = 37 * result + ((key.getOperation() == null) ? 0 : key.getOperation().hashCode());
return result;
}
};
private static final PolicyMapKeyHandler faultMessageHandler = new PolicyMapKeyHandler() {
public boolean areEqual(final PolicyMapKey key1, final PolicyMapKey key2) {
boolean retVal = true;
retVal = retVal && key1.getService().equals(key2.getService());
retVal = retVal && ((key1.getPort() == null) ? key2.getPort() == null : key1.getPort().equals(key2.getPort()));
retVal = retVal && ((key1.getOperation() == null) ? key2.getOperation() == null : key1.getOperation().equals(key2.getOperation()));
retVal = retVal && ((key1.getFaultMessage() == null) ? key2.getFaultMessage() == null : key1.getFaultMessage().equals(key2.getFaultMessage()));
return retVal;
}
public int generateHashCode(final PolicyMapKey key) {
int result = 17;
result = 37 * result + key.getService().hashCode();
result = 37 * result + ((key.getPort() == null) ? 0 : key.getPort().hashCode());
result = 37 * result + ((key.getOperation() == null) ? 0 : key.getOperation().hashCode());
result = 37 * result + ((key.getFaultMessage() == null) ? 0 : key.getFaultMessage().hashCode());
return result;
}
};
static enum ScopeType {
SERVICE,
ENDPOINT,
OPERATION,
INPUT_MESSAGE,
OUTPUT_MESSAGE,
FAULT_MESSAGE
}
private static final class ScopeMap implements Iterable<Policy> {
private final Map<PolicyMapKey, PolicyScope> internalMap = new HashMap<PolicyMapKey, PolicyScope>();
private final PolicyMapKeyHandler scopeKeyHandler;
private final PolicyMerger merger;
ScopeMap(final PolicyMerger merger, final PolicyMapKeyHandler scopeKeyHandler) {
this.merger = merger;
this.scopeKeyHandler = scopeKeyHandler;
}
Policy getEffectivePolicy(final PolicyMapKey key) throws PolicyException {
final PolicyScope scope = internalMap.get(createLocalCopy(key));
return (scope == null) ? null : scope.getEffectivePolicy(merger);
}
void putSubject(final PolicyMapKey key, final PolicySubject subject) {
final PolicyMapKey localKey = createLocalCopy(key);
final PolicyScope scope = internalMap.get(localKey);
if (scope == null) {
final List<PolicySubject> list = new LinkedList<PolicySubject>();
list.add(subject);
internalMap.put(localKey, new PolicyScope(list));
} else {
scope.attach(subject);
}
}
void setNewEffectivePolicy(final PolicyMapKey key, final Policy newEffectivePolicy) {
// we add this policy map as a subject, because there is nothing reasonable we could add there, since
// this is an artificial policy subject
final PolicySubject subject = new PolicySubject(key, newEffectivePolicy);
final PolicyMapKey localKey = createLocalCopy(key);
final PolicyScope scope = internalMap.get(localKey);
if (scope == null) {
final List<PolicySubject> list = new LinkedList<PolicySubject>();
list.add(subject);
internalMap.put(localKey, new PolicyScope(list));
} else {
scope.dettachAllSubjects();
scope.attach(subject);
}
}
Collection<PolicyScope> getStoredScopes() {
return internalMap.values();
}
Set<PolicyMapKey> getAllKeys() {
return internalMap.keySet();
}
private PolicyMapKey createLocalCopy(final PolicyMapKey key) {
if (key == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0045_POLICY_MAP_KEY_MUST_NOT_BE_NULL()));
}
final PolicyMapKey localKeyCopy = new PolicyMapKey(key);
localKeyCopy.setHandler(scopeKeyHandler);
return localKeyCopy;
}
public Iterator<Policy> iterator() {
return new Iterator<Policy> () {
private final Iterator<PolicyMapKey> keysIterator = internalMap.keySet().iterator();
public boolean hasNext() {
return keysIterator.hasNext();
}
public Policy next() {
final PolicyMapKey key = keysIterator.next();
try {
return getEffectivePolicy(key);
} catch (PolicyException e) {
throw LOGGER.logSevereException(new IllegalStateException(LocalizationMessages.WSP_0069_EXCEPTION_WHILE_RETRIEVING_EFFECTIVE_POLICY_FOR_KEY(key), e));
}
}
public void remove() {
throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0034_REMOVE_OPERATION_NOT_SUPPORTED()));
}
};
}
public boolean isEmpty() {
return internalMap.isEmpty();
}
@Override
public String toString() {
return internalMap.toString();
}
}
private static final PolicyMerger merger = PolicyMerger.getMerger();
private final ScopeMap serviceMap = new ScopeMap(merger, serviceKeyHandler);
private final ScopeMap endpointMap = new ScopeMap(merger, endpointKeyHandler);
private final ScopeMap operationMap = new ScopeMap(merger, operationAndInputOutputMessageKeyHandler);
private final ScopeMap inputMessageMap = new ScopeMap(merger, operationAndInputOutputMessageKeyHandler);
private final ScopeMap outputMessageMap = new ScopeMap(merger, operationAndInputOutputMessageKeyHandler);
private final ScopeMap faultMessageMap = new ScopeMap(merger, faultMessageHandler);
/**
* This constructor is private to prevent direct instantiation from outside of the class
*/
private PolicyMap() {
// nothing to initialize
}
/**
* Creates new policy map instance and connects provided collection of policy map mutators to the created policy map.
*
* @param mutators collection of mutators that should be connected to the newly created map.
* @return new policy map instance (mutable via provided collection of mutators).
*/
public static PolicyMap createPolicyMap(final Collection<? extends PolicyMapMutator> mutators) {
final PolicyMap result = new PolicyMap();
if (mutators != null && !mutators.isEmpty()) {
for (PolicyMapMutator mutator : mutators) {
mutator.connect(result);
}
}
return result;
}
public Policy getServiceEffectivePolicy(final PolicyMapKey key) throws PolicyException {
return serviceMap.getEffectivePolicy(key);
}
public Policy getEndpointEffectivePolicy(final PolicyMapKey key) throws PolicyException {
return endpointMap.getEffectivePolicy(key);
}
public Policy getOperationEffectivePolicy(final PolicyMapKey key) throws PolicyException {
return operationMap.getEffectivePolicy(key);
}
public Policy getInputMessageEffectivePolicy(final PolicyMapKey key) throws PolicyException {
return inputMessageMap.getEffectivePolicy(key);
}
public Policy getOutputMessageEffectivePolicy(final PolicyMapKey key) throws PolicyException {
return outputMessageMap.getEffectivePolicy(key);
}
public Policy getFaultMessageEffectivePolicy(final PolicyMapKey key) throws PolicyException {
return faultMessageMap.getEffectivePolicy(key);
}
/**
* Returns all service scope keys stored in this policy map
*
* @return collection of service scope policy map keys stored in the map.
*/
public Collection<PolicyMapKey> getAllServiceScopeKeys() {
return serviceMap.getAllKeys();
}
/**
* Returns all endpoint scope keys stored in this policy map
*
* @return collection of endpoint scope policy map keys stored in the map.
*/
public Collection<PolicyMapKey> getAllEndpointScopeKeys() {
return endpointMap.getAllKeys();
}
/**
* Returns all operation scope keys stored in this policy map
*
* @return collection of operation scope policy map keys stored in the map.
*/
public Collection<PolicyMapKey> getAllOperationScopeKeys() {
return operationMap.getAllKeys();
}
/**
* Returns all input message scope keys stored in this policy map
*
* @return collection of input message scope policy map keys stored in the map.
*/
public Collection<PolicyMapKey> getAllInputMessageScopeKeys() {
return inputMessageMap.getAllKeys();
}
/**
* Returns all output message scope keys stored in this policy map
*
* @return collection of output message scope policy map keys stored in the map.
*/
public Collection<PolicyMapKey> getAllOutputMessageScopeKeys() {
return outputMessageMap.getAllKeys();
}
/**
* Returns all fault message scope keys stored in this policy map
*
* @return collection of input message scope policy map keys stored in the map.
*/
public Collection<PolicyMapKey> getAllFaultMessageScopeKeys() {
return faultMessageMap.getAllKeys();
}
/**
* Places new subject into policy map under the scope identified by it's type and policy map key.
*
* @param scopeType the type of the scope the subject belongs to
* @param key a policy map key to be used to store the subject
* @param subject actual policy subject to be stored in the policy map
*
* @throw IllegalArgumentException in case the scope type is not recognized.
*/
void putSubject(final ScopeType scopeType, final PolicyMapKey key, final PolicySubject subject) {
switch (scopeType) {
case SERVICE:
serviceMap.putSubject(key, subject);
break;
case ENDPOINT:
endpointMap.putSubject(key, subject);
break;
case OPERATION:
operationMap.putSubject(key, subject);
break;
case INPUT_MESSAGE:
inputMessageMap.putSubject(key, subject);
break;
case OUTPUT_MESSAGE:
outputMessageMap.putSubject(key, subject);
break;
case FAULT_MESSAGE:
faultMessageMap.putSubject(key, subject);
break;
default:
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0002_UNRECOGNIZED_SCOPE_TYPE(scopeType)));
}
}
/**
* Replaces current effective policy on given scope (identified by a {@code key} parameter) with the new efective
* policy provided as a second input parameter. If no policy was defined for the presented key, the new policy is simply
* stored with the key.
*
* @param scopeType the type of the scope the subject belongs to. Must not be {@code null}.
* @param key identifier of the scope the effective policy should be replaced with the new one. Must not be {@code null}.
* @param newEffectivePolicy the new policy to replace the old effective policy of the scope. Must not be {@code null}.
*
* @throw IllegalArgumentException in case any of the input parameters is {@code null}
* or in case the scope type is not recognized.
*/
void setNewEffectivePolicyForScope(final ScopeType scopeType, final PolicyMapKey key, final Policy newEffectivePolicy) throws IllegalArgumentException {
if (scopeType == null || key == null || newEffectivePolicy == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0062_INPUT_PARAMS_MUST_NOT_BE_NULL()));
}
switch (scopeType) {
case SERVICE :
serviceMap.setNewEffectivePolicy(key, newEffectivePolicy);
break;
case ENDPOINT :
endpointMap.setNewEffectivePolicy(key, newEffectivePolicy);
break;
case OPERATION :
operationMap.setNewEffectivePolicy(key, newEffectivePolicy);
break;
case INPUT_MESSAGE :
inputMessageMap.setNewEffectivePolicy(key, newEffectivePolicy);
break;
case OUTPUT_MESSAGE :
outputMessageMap.setNewEffectivePolicy(key, newEffectivePolicy);
break;
case FAULT_MESSAGE :
faultMessageMap.setNewEffectivePolicy(key, newEffectivePolicy);
break;
default:
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0002_UNRECOGNIZED_SCOPE_TYPE(scopeType)));
}
}
/**
* Returns all policy subjects contained by this map.
*
* @return All policy subjects contained by this map
*/
public Collection<PolicySubject> getPolicySubjects() {
final List<PolicySubject> subjects = new LinkedList<PolicySubject>();
addSubjects(subjects, serviceMap);
addSubjects(subjects, endpointMap);
addSubjects(subjects, operationMap);
addSubjects(subjects, inputMessageMap);
addSubjects(subjects, outputMessageMap);
addSubjects(subjects, faultMessageMap);
return subjects;
}
/*
* TODO: reconsider this QUICK HACK
*/
public boolean isInputMessageSubject(final PolicySubject subject) {
for (PolicyScope scope : inputMessageMap.getStoredScopes()) {
if (scope.getPolicySubjects().contains(subject)) {
return true;
}
}
return false;
}
/*
* TODO: reconsider this QUICK HACK
*/
public boolean isOutputMessageSubject(final PolicySubject subject) {
for (PolicyScope scope : outputMessageMap.getStoredScopes()) {
if (scope.getPolicySubjects().contains(subject)) {
return true;
}
}
return false;
}
/*
* TODO: reconsider this QUICK HACK
*/
public boolean isFaultMessageSubject(final PolicySubject subject) {
for (PolicyScope scope : faultMessageMap.getStoredScopes()) {
if (scope.getPolicySubjects().contains(subject)) {
return true;
}
}
return false;
}
/**
* Returns true if this map contains no key - policy pairs
*
* A null object key or policy constitutes a non-empty map.
*
* @return true if this map contains no key - policy pairs
*/
public boolean isEmpty() {
return serviceMap.isEmpty() && endpointMap.isEmpty() &&
operationMap.isEmpty() && inputMessageMap.isEmpty() &&
outputMessageMap.isEmpty() && faultMessageMap.isEmpty();
}
/**
* Add all subjects in the given map to the collection
*
* @param subjects A collection that should hold subjects. The new subjects are added to the collection. Must not be {@code null}.
* @param scopeMap A scope map that holds policy scopes. The subjects are retrieved from the scope objects.
*/
private void addSubjects(final Collection<PolicySubject> subjects, final ScopeMap scopeMap) {
for (PolicyScope scope : scopeMap.getStoredScopes()) {
final Collection<PolicySubject> scopedSubjects = scope.getPolicySubjects();
subjects.addAll(scopedSubjects);
}
}
/**
* Creates a service policy scope <emph>locator</emph> object, that serves as a access key into
* a {@code PolicyMap} where actual service policy scope for given service can be retrieved.
*
* @param service qualified name of the service. Must not be {@code null}.
* @throws IllegalArgumentException in case service, port or operation parameter is {@code null}.
*/
public static PolicyMapKey createWsdlServiceScopeKey(final QName service) throws IllegalArgumentException {
if (service == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0031_SERVICE_PARAM_MUST_NOT_BE_NULL()));
}
return new PolicyMapKey(service, null, null, serviceKeyHandler);
}
/**
* Creates an endpoint policy scope <emph>locator</emph> object, that serves as a access key into
* a {@code PolicyMap} where actual endpoint policy scope for given endpoint can be retrieved.
*
* @param service qualified name of the service. Must not be {@code null}.
* @param port qualified name of the endpoint. Must not be {@code null}.
* @throws IllegalArgumentException in case service, port or operation parameter is {@code null}.
*/
public static PolicyMapKey createWsdlEndpointScopeKey(final QName service, final QName port) throws IllegalArgumentException {
if (service == null || port == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0033_SERVICE_AND_PORT_PARAM_MUST_NOT_BE_NULL(service, port)));
}
return new PolicyMapKey(service, port, null, endpointKeyHandler);
}
/**
* Creates an operation policy scope <emph>locator</emph> object, that serves as a access key into
* a {@code PolicyMap} where actual operation policy scope for given bound operation can be retrieved.
*
* @param service qualified name of the service. Must not be {@code null}.
* @param port qualified name of the endpoint. Must not be {@code null}.
* @param operation qualified name of the operation. Must not be {@code null}.
* @throws IllegalArgumentException in case service, port or operation parameter is {@code null}.
*/
public static PolicyMapKey createWsdlOperationScopeKey(final QName service, final QName port, final QName operation) throws IllegalArgumentException {
return createOperationOrInputOutputMessageKey(service, port, operation);
}
/**
* Creates an input/output message policy scope <emph>locator</emph> object identified by a bound operation, that serves as a
* access key into {@code PolicyMap} where actual input/output message policy scope for given input message of a bound operation
* can be retrieved.
* <p/>
* The method returns a key that is compliant with <emph>WSDL 1.1 Basic Profile Specification</emph>, according to which there
* should be no two operations with the same name in a single port type definition.
*
* @param service qualified name of the service. Must not be {@code null}.
* @param port qualified name of the endpoint. Must not be {@code null}.
* @param operation qualified name of the operation. Must not be {@code null}.
* @throws IllegalArgumentException in case service, port or operation parameter is {@code null}.
*
*/
public static PolicyMapKey createWsdlMessageScopeKey(final QName service, final QName port, final QName operation) throws IllegalArgumentException {
return createOperationOrInputOutputMessageKey(service, port, operation);
}
/**
* Creates a fault message policy scope <emph>locator</emph> object identified by a bound operation, that serves as a
* access key into {@code PolicyMap} where the actual fault message policy scope for one of the faults of a bound operation
* can be retrieved.
* <p/>
* The method returns a key that is compliant with the <emph>WSDL 1.1 Basic Profile Specification</emph>, according to which there
* should be no two operations with the same name in a single port type definition.
*
* @param service qualified name of the service. Must not be {@code null}.
* @param port qualified name of the endpoint. Must not be {@code null}.
* @param operation qualified name of the operation. Must not be {@code null}.
* @param fault qualified name of the fault. Do not confuse this with the name of the actual message. This parameter
* takes the wsdl:binding/wsdl:operation/wsdl:fault name and not the wsdl:message name. Must not be {@code null}.
* @throws IllegalArgumentException in case service, port or operation parameter is {@code null}.
*
*/
public static PolicyMapKey createWsdlFaultMessageScopeKey(final QName service, final QName port, final QName operation, final QName fault) throws IllegalArgumentException {
if (service == null || port == null || operation == null || fault == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0030_SERVICE_PORT_OPERATION_FAULT_MSG_PARAM_MUST_NOT_BE_NULL(service, port, operation, fault)));
}
return new PolicyMapKey(service, port, operation, fault, faultMessageHandler);
}
private static PolicyMapKey createOperationOrInputOutputMessageKey(final QName service, final QName port, final QName operation) {
if (service == null || port == null || operation == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0029_SERVICE_PORT_OPERATION_PARAM_MUST_NOT_BE_NULL(service, port, operation)));
}
return new PolicyMapKey(service, port, operation, operationAndInputOutputMessageKeyHandler);
}
@Override
public String toString(){
// TODO
final StringBuffer result = new StringBuffer();
if(null!=this.serviceMap) {
result.append("\nServiceMap=").append(this.serviceMap);
}
if(null!=this.endpointMap) {
result.append("\nEndpointMap=").append(this.endpointMap);
}
if(null!=this.operationMap) {
result.append("\nOperationMap=").append(this.operationMap);
}
if(null!=this.inputMessageMap) {
result.append("\nInputMessageMap=").append(this.inputMessageMap);
}
if(null!=this.outputMessageMap) {
result.append("\nOutputMessageMap=").append(this.outputMessageMap);
}
if(null!=this.faultMessageMap) {
result.append("\nFaultMessageMap=").append(this.faultMessageMap);
}
return result.toString();
}
public Iterator<Policy> iterator() {
return new Iterator<Policy> () {
private final Iterator<Iterator<Policy>> mainIterator;
private Iterator<Policy> currentScopeIterator;
{ // instance initialization
final Collection<Iterator<Policy>> scopeIterators = new ArrayList<Iterator<Policy>>(6);
scopeIterators.add(serviceMap.iterator());
scopeIterators.add(endpointMap.iterator());
scopeIterators.add(operationMap.iterator());
scopeIterators.add(inputMessageMap.iterator());
scopeIterators.add(outputMessageMap.iterator());
scopeIterators.add(faultMessageMap.iterator());
mainIterator = scopeIterators.iterator();
currentScopeIterator = mainIterator.next();
}
public boolean hasNext() {
while (!currentScopeIterator.hasNext()) {
if (mainIterator.hasNext()) {
currentScopeIterator = mainIterator.next();
} else {
return false;
}
}
return true;
}
public Policy next() {
if (hasNext()) {
return currentScopeIterator.next();
}
throw LOGGER.logSevereException(new NoSuchElementException(LocalizationMessages.WSP_0054_NO_MORE_ELEMS_IN_POLICY_MAP()));
}
public void remove() {
throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0034_REMOVE_OPERATION_NOT_SUPPORTED()));
}
};
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
/**
* The class provides methods to extend policy map content with new policies
*
* @author Marek Potociar (marek.potociar@sun.com)
*/
public final class PolicyMapExtender extends PolicyMapMutator {
/**
* This constructor is private to prevent direct instantiation from outside of the class
*/
private PolicyMapExtender() {
// nothing to initialize
}
public static PolicyMapExtender createPolicyMapExtender() {
return new PolicyMapExtender();
}
public void putServiceSubject(final PolicyMapKey key, final PolicySubject subject) {
getMap().putSubject(PolicyMap.ScopeType.SERVICE, key, subject);
}
public void putEndpointSubject(final PolicyMapKey key, final PolicySubject subject) {
getMap().putSubject(PolicyMap.ScopeType.ENDPOINT, key, subject);
}
public void putOperationSubject(final PolicyMapKey key, final PolicySubject subject) {
getMap().putSubject(PolicyMap.ScopeType.OPERATION, key, subject);
}
public void putInputMessageSubject(final PolicyMapKey key, final PolicySubject subject) {
getMap().putSubject(PolicyMap.ScopeType.INPUT_MESSAGE, key, subject);
}
public void putOutputMessageSubject(final PolicyMapKey key, final PolicySubject subject) {
getMap().putSubject(PolicyMap.ScopeType.OUTPUT_MESSAGE, key, subject);
}
public void putFaultMessageSubject(final PolicyMapKey key, final PolicySubject subject) {
getMap().putSubject(PolicyMap.ScopeType.FAULT_MESSAGE, key, subject);
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import javax.xml.namespace.QName;
/**
* This class provides implementation of PolicyMapKey interface to be used in connection with {@link PolicyMap}.
* Instances of the class are created by a call to one of {@link PolicyMap} <code>createWsdl<emph>XXX</emph>PolicyMapKey(...)</code>
* methods.
* <p/>
* The class wraps scope information and adds a package setter method to allow injection of actual equality comparator/tester. This injection
* is made within a <code>get...</code> call on {@link PolicyMap}, before the actual scope map search is performed.
*
*
* @author Marek Potociar (marek.potociar at sun.com)
* @author Fabian Ritzmann
*/
final public class PolicyMapKey {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyMapKey.class);
private final QName service;
private final QName port;
private final QName operation;
private final QName faultMessage;
private PolicyMapKeyHandler handler;
PolicyMapKey(final QName service, final QName port, final QName operation, final PolicyMapKeyHandler handler) {
this(service, port, operation, null, handler);
}
PolicyMapKey(final QName service, final QName port, final QName operation, final QName faultMessage, final PolicyMapKeyHandler handler) {
if (handler == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0046_POLICY_MAP_KEY_HANDLER_NOT_SET()));
}
this.service = service;
this.port = port;
this.operation = operation;
this.faultMessage = faultMessage;
this.handler = handler;
}
PolicyMapKey(final PolicyMapKey that) {
this.service = that.service;
this.port = that.port;
this.operation = that.operation;
this.faultMessage = that.faultMessage;
this.handler = that.handler;
}
public QName getOperation() {
return operation;
}
public QName getPort() {
return port;
}
public QName getService() {
return service;
}
void setHandler(PolicyMapKeyHandler handler) {
if (handler == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0046_POLICY_MAP_KEY_HANDLER_NOT_SET()));
}
this.handler = handler;
}
public QName getFaultMessage() {
return faultMessage;
}
@Override
public boolean equals(final Object that) {
if (this == that) {
return true; // we are lucky here => no special handling is required
}
if (that == null) {
return false;
}
if (that instanceof PolicyMapKey) {
return handler.areEqual(this, (PolicyMapKey) that);
} else {
return false;
}
}
@Override
public int hashCode() {
return handler.generateHashCode(this);
}
@Override
public String toString() {
final StringBuffer result = new StringBuffer("PolicyMapKey(");
result.append(this.service).append(", ").append(port).append(", ").append(operation).append(", ").append(faultMessage);
return result.append(")").toString();
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
/**
* This interface defines method that is used to handle actual equality comparison and hash code generation for PolicyMapKey object.
* <p/>
* The different implementations of this interface may allow different strategies to be applied for operations mentioned above. This feature
* is used within {@link WSPolicyMap} to restrict set of fields to be compared when searching different policy scope maps.
*
*
*
* @author Marek Potociar
*/
interface PolicyMapKeyHandler {
boolean areEqual(PolicyMapKey locator1, PolicyMapKey locator2);
int generateHashCode(PolicyMapKey locator);
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
/**
* The class serves as a base for specific policy map mutator implementations. It provides common methods that allow
* concrete mutator implementations to connect and disconnect to/from a policy map instance.
*
* @author Marek Potociar (marek.potociar@sun.com)
*/
public abstract class PolicyMapMutator {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyMapMutator.class);
private PolicyMap map = null;
/**
* Creates a new instance of PolicyMapMutator. This class cannot be extended from outside of this package.
*/
PolicyMapMutator() {
// nothing to instantiate
}
/**
* The method is used to connect the policy map mutator instance to the map it should mutate.
*
* @param map the policy map instance that will be mutable by this mutator.
* @throws IllegalStateException in case this mutator object is already connected to a policy map.
*/
public void connect(final PolicyMap map) {
if (isConnected()) {
throw LOGGER.logSevereException(new IllegalStateException(LocalizationMessages.WSP_0044_POLICY_MAP_MUTATOR_ALREADY_CONNECTED()));
}
this.map = map;
}
/**
* Can be used to retrieve the policy map currently connected to this mutator. Will return {@code null} if not connected.
*
* @return policy map currently connected to this mutator. May return {@code null} if the mutator is not connected.
*
* @see #isConnected()
* @see #disconnect()
*/
public PolicyMap getMap() {
return this.map;
}
/**
* Disconnects the mutator from the policy map object it is connected to. Method must be called prior to connecting this
* mutator instance to another policy map.
* <p/>
* This operation is irreversible: you cannot connect the mutator to the same policy map instance once you disconnect from it.
* Multiple consequent calls of this method will have no effect.
*/
public void disconnect() {
this.map = null;
}
/**
* This method provides connection status information of the policy map mutator instance.
*
* @return {@code true} if the mutator instance is connected to a policy map, otherwise returns {@code false}.
*/
public boolean isConnected() {
return this.map != null;
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.PolicyMap.ScopeType;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.subject.PolicyMapKeyConverter;
import com.sun.xml.internal.ws.policy.subject.WsdlBindingSubject;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import javax.xml.namespace.QName;
/**
* Utility methods that operate on a PolicyMap.
*
* @author Fabian Ritzmann
*/
public class PolicyMapUtil {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyMapUtil.class);
private static final PolicyMerger MERGER = PolicyMerger.getMerger();
/**
* Prevent instantiation.
*/
private PolicyMapUtil() {
}
/**
* Throw an exception if the policy map contains any policy with at least two
* policy alternatives.
*
* Optional assertions are not considered (unless they have been normalized into
* two policy alternatives).
*
* @param map policy map to be processed
* @throws PolicyException Thrown if the policy map contains at least one policy
* with more than one policy alternative
*/
public static void rejectAlternatives(final PolicyMap map) throws PolicyException {
for (Policy policy : map) {
if (policy.getNumberOfAssertionSets() > 1) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0035_RECONFIGURE_ALTERNATIVES(policy.getIdOrName())));
}
}
}
/**
* Inserts all PolicySubjects of type WsdlBindingSubject into the given policy map.
*
* @param policyMap The policy map
* @param policySubjects The policy subjects. The actual subject must have the
* type WsdlBindingSubject, otherwise it will not be processed.
* @param serviceName The name of the current WSDL service
* @param portName The name of the current WSDL port
* @throws PolicyException Thrown if the effective policy of a policy subject
* could not be computed
*/
public static void insertPolicies(final PolicyMap policyMap, final Collection<PolicySubject> policySubjects, QName serviceName, QName portName)
throws PolicyException {
LOGGER.entering(policyMap, policySubjects, serviceName, portName);
final HashMap<WsdlBindingSubject, Collection<Policy>> subjectToPolicies = new HashMap<WsdlBindingSubject, Collection<Policy>>();
for (PolicySubject subject: policySubjects) {
final Object actualSubject = subject.getSubject();
if (actualSubject instanceof WsdlBindingSubject) {
final WsdlBindingSubject wsdlSubject = (WsdlBindingSubject) actualSubject;
final Collection<Policy> subjectPolicies = new LinkedList<Policy>();
subjectPolicies.add(subject.getEffectivePolicy(MERGER));
final Collection<Policy> existingPolicies = subjectToPolicies.put(wsdlSubject, subjectPolicies);
if (existingPolicies != null) {
subjectPolicies.addAll(existingPolicies);
}
}
}
final PolicyMapKeyConverter converter = new PolicyMapKeyConverter(serviceName, portName);
for (WsdlBindingSubject wsdlSubject : subjectToPolicies.keySet()) {
final PolicySubject newSubject = new PolicySubject(wsdlSubject, subjectToPolicies.get(wsdlSubject));
PolicyMapKey mapKey = converter.getPolicyMapKey(wsdlSubject);
if (wsdlSubject.isBindingSubject()) {
policyMap.putSubject(ScopeType.ENDPOINT, mapKey, newSubject);
}
else if (wsdlSubject.isBindingOperationSubject()) {
policyMap.putSubject(ScopeType.OPERATION, mapKey, newSubject);
}
else if (wsdlSubject.isBindingMessageSubject()) {
switch (wsdlSubject.getMessageType()) {
case INPUT:
policyMap.putSubject(ScopeType.INPUT_MESSAGE, mapKey, newSubject);
break;
case OUTPUT:
policyMap.putSubject(ScopeType.OUTPUT_MESSAGE, mapKey, newSubject);
break;
case FAULT:
policyMap.putSubject(ScopeType.FAULT_MESSAGE, mapKey, newSubject);
break;
}
}
}
LOGGER.exiting();
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
/**
* Merge policies and return the effective policy.
*
* WS-PolicyAttachment defines a merge algorithm for WSDL 1.1 policy attachments.
*/
public final class PolicyMerger {
private static final PolicyMerger merger = new PolicyMerger();
/**
* This private constructor is to avoid direct class instantiation from outsied of the package
*/
private PolicyMerger() {
// nothing to instantiate
}
/**
* Factory method for obtaining thread-safe policy merger instance.
*
* @return policy merger instance.
*/
public static PolicyMerger getMerger() {
return merger;
}
/**
* Takes collection of policies and merges them into a single policy using algorithm described in
* WS-PolicyAttachment specification. None of the original policies in the collection are modified in
* any way.
*
* The newly created policy has an ID that is a concatentation of all merged policy IDs.
*
* @param policies collection of policies to be merged. The collection must not contain '{@code null}' elements!
* @return merged policy containing combination of policy alternatives stored in all input policies.
* If provided collection of policies is {@code null} or empty, returns {@code null}. If provided
* collection of policies contains only single policy, the policy is returned.
*/
public Policy merge(final Collection<Policy> policies) {
if (policies == null || policies.isEmpty()) {
return null;
} else if (policies.size() == 1) {
return policies.iterator().next();
}
final Collection<Collection<AssertionSet>> alternativeSets = new LinkedList<Collection<AssertionSet>>();
final StringBuilder id = new StringBuilder();
NamespaceVersion mergedVersion = policies.iterator().next().getNamespaceVersion();
for (Policy policy : policies) {
alternativeSets.add(policy.getContent());
if (mergedVersion.compareTo(policy.getNamespaceVersion()) < 0) {
mergedVersion = policy.getNamespaceVersion();
}
final String policyId = policy.getId();
if (policyId != null) {
if (id.length() > 0) {
id.append('-');
}
id.append(policyId);
}
}
final Collection<Collection<AssertionSet>> combinedAlternatives = PolicyUtils.Collections.combine(null, alternativeSets, false);
if (combinedAlternatives == null || combinedAlternatives.isEmpty()) {
return Policy.createNullPolicy(mergedVersion, null, id.length() == 0 ? null : id.toString());
} else {
final Collection<AssertionSet> mergedSetList = new ArrayList<AssertionSet>(combinedAlternatives.size());
for (Collection<AssertionSet> toBeMerged : combinedAlternatives) {
mergedSetList.add(AssertionSet.createMergedAssertionSet(toBeMerged));
}
return Policy.createPolicy(mergedVersion, null, id.length() == 0 ? null : id.toString(), mergedSetList);
}
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* A policy scope is a collection of equally ranked elements or subjects that
* hold policies
*
* @author Fabian Ritzmann
*/
final class PolicyScope {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyScope.class);
private final List<PolicySubject> subjects = new LinkedList<PolicySubject>();
PolicyScope(final List<PolicySubject> initialSubjects) {
if (initialSubjects != null && !initialSubjects.isEmpty()) {
this.subjects.addAll(initialSubjects);
}
}
void attach(final PolicySubject subject) {
if (subject == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0020_SUBJECT_PARAM_MUST_NOT_BE_NULL()));
}
subjects.add(subject);
}
void dettachAllSubjects() {
subjects.clear();
}
/**
* Returns all policies of the scope merged into one policy
*
* @return effective policy of the scope
*/
Policy getEffectivePolicy(final PolicyMerger merger) throws PolicyException {
final LinkedList<Policy> policies = new LinkedList<Policy>();
for (PolicySubject subject : subjects) {
policies.add(subject.getEffectivePolicy(merger));
}
return merger.merge(policies);
}
/**
* Returns all subjects contained by this scope
*
* @return The subjects contained by this scope
*/
Collection<PolicySubject> getPolicySubjects() {
return this.subjects;
}
/**
* An {@code Object.toString()} method override.
*/
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
buffer.append(indent).append("policy scope {").append(PolicyUtils.Text.NEW_LINE);
for (PolicySubject policySubject : subjects) {
policySubject.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(indent).append('}');
return buffer;
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* A PolicySubject is an entity (e.g., a port, operation, binding,
* service) with which a policy can be associated.
*
* @author Fabian Ritzmann
*/
public final class PolicySubject {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicySubject.class);
private final List<Policy> policies = new LinkedList<Policy>();
private final Object subject;
/**
* Constructs a policy subject instance.
*
* @param subject object to which the policies are attached. Must not be {@code null}.
* @param policy first policy attached to the subject. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the arguments is {@code null}.
*/
public PolicySubject(Object subject, Policy policy) throws IllegalArgumentException {
if (subject == null || policy == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0021_SUBJECT_AND_POLICY_PARAM_MUST_NOT_BE_NULL(subject, policy)));
}
this.subject = subject;
this.attach(policy);
}
/**
* Constructs a policy subject instance.
*
* @param subject object to which the policies are attached. Must not be {@code null}.
* @param policies first policy attached to the subject. Must not be {@code null}.
*
* @throws IllegalArgumentException in case any of the arguments is {@code null} or
* in case {@code policies} argument represents empty collection.
*/
public PolicySubject(Object subject, Collection<Policy> policies) throws IllegalArgumentException {
if (subject == null || policies == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0062_INPUT_PARAMS_MUST_NOT_BE_NULL()));
}
if (policies.isEmpty()) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0064_INITIAL_POLICY_COLLECTION_MUST_NOT_BE_EMPTY()));
}
this.subject = subject;
this.policies.addAll(policies);
}
/**
* Attaches another Policy instance to the policy subject.
*
* @param policy new policy instance to be attached to this subject
*
* @throws IllegalArgumentException in case {@code policy} argument is {@code null}.
*/
public void attach(final Policy policy) {
if (policy == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0038_POLICY_TO_ATTACH_MUST_NOT_BE_NULL()));
}
this.policies.add(policy);
}
/**
* Returns the effective policy of the subject, i.e. all policies of the subject
* merged together.
*
* @return effective policy of the subject
*/
public Policy getEffectivePolicy(final PolicyMerger merger) throws PolicyException {
return merger.merge(policies);
}
/**
* A unique identifier of the subject
*
* Subjects may not always be uniquely identifiable. Also, once the subject is
* assigned to a scope, its identity may not matter anymore. Therefore this
* may be null.
*/
public Object getSubject() {
return this.subject;
}
/**
* An {@code Object.toString()} method override.
*/
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
buffer.append(indent).append("policy subject {").append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("subject = '").append(subject).append('\'').append(PolicyUtils.Text.NEW_LINE);
for (Policy policy : policies) {
policy.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(indent).append('}');
return buffer;
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy;
import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
import java.util.Collection;
/**
* Simple assertion is an abstract class that serves as a base class for any assertion
* that <b>MAY NOT</b> contain nested policies.
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public abstract class SimpleAssertion extends PolicyAssertion {
protected SimpleAssertion() {
super();
}
protected SimpleAssertion(AssertionData data, Collection<? extends PolicyAssertion> assertionParameters) {
super(data, assertionParameters);
}
@Override
public final boolean hasNestedPolicy() { // TODO: make abstract
return false;
}
@Override
public final NestedPolicy getNestedPolicy() { // TODO: make abstract
return null;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.api.policy.ModelTranslator;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicySubject;
import com.sun.xml.internal.ws.resources.PolicyMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
/**
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
*/
abstract class BuilderHandler{
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(BuilderHandler.class);
Map<String,PolicySourceModel> policyStore;
Collection<String> policyURIs;
Object policySubject;
/**
* Creates a new instance of BuilderHandler
*/
BuilderHandler(Collection<String> policyURIs, Map<String,PolicySourceModel> policyStore, Object policySubject) {
this.policyStore = policyStore;
this.policyURIs = policyURIs;
this.policySubject = policySubject;
}
final void populate(final PolicyMapExtender policyMapExtender) throws PolicyException {
if (null == policyMapExtender) {
throw LOGGER.logSevereException(new PolicyException(PolicyMessages.WSP_1006_POLICY_MAP_EXTENDER_CAN_NOT_BE_NULL()));
}
doPopulate(policyMapExtender);
}
protected abstract void doPopulate(final PolicyMapExtender policyMapExtender) throws PolicyException;
final Collection<Policy> getPolicies() throws PolicyException {
if (null == policyURIs) {
throw LOGGER.logSevereException(new PolicyException(PolicyMessages.WSP_1004_POLICY_URIS_CAN_NOT_BE_NULL()));
}
if (null == policyStore) {
throw LOGGER.logSevereException(new PolicyException(PolicyMessages.WSP_1010_NO_POLICIES_DEFINED()));
}
final Collection<Policy> result = new ArrayList<Policy>(policyURIs.size());
for (String policyURI : policyURIs) {
final PolicySourceModel sourceModel = policyStore.get(policyURI);
if (sourceModel == null) {
throw LOGGER.logSevereException(new PolicyException(PolicyMessages.WSP_1005_POLICY_REFERENCE_DOES_NOT_EXIST(policyURI)));
} else {
result.add(ModelTranslator.getTranslator().translate(sourceModel));
}
}
return result;
}
final Collection<PolicySubject> getPolicySubjects() throws PolicyException {
final Collection<Policy> policies = getPolicies();
final Collection<PolicySubject> result = new ArrayList<PolicySubject>(policies.size());
for (Policy policy : policies) {
result.add(new PolicySubject(policySubject, policy));
}
return result;
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import com.sun.xml.internal.ws.policy.PolicySubject;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import java.util.Collection;
import java.util.Map;
import javax.xml.namespace.QName;
/**
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
*/
final class BuilderHandlerEndpointScope extends BuilderHandler{
private final QName service;
private final QName port;
/** Creates a new instance of WSDLServiceScopeBuilderHandler */
BuilderHandlerEndpointScope(Collection<String> policyURIs, Map<String,PolicySourceModel> policyStore, Object policySubject, QName service, QName port) {
super(policyURIs, policyStore, policySubject);
this.service = service;
this.port = port;
}
protected void doPopulate(final PolicyMapExtender policyMapExtender) throws PolicyException {
final PolicyMapKey mapKey = PolicyMap.createWsdlEndpointScopeKey(service, port);
for (PolicySubject subject : getPolicySubjects()) {
policyMapExtender.putEndpointSubject(mapKey, subject);
}
}
@Override
public String toString() {
return (new StringBuffer(service.toString())).append(":").append(port.toString()).toString();
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import com.sun.xml.internal.ws.policy.PolicySubject;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import java.util.Collection;
import java.util.Map;
import javax.xml.namespace.QName;
/**
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
*/
final class BuilderHandlerMessageScope extends BuilderHandler{
private final QName service;
private final QName port;
private final QName operation;
private final QName message;
private final Scope scope;
enum Scope{
InputMessageScope,
OutputMessageScope,
FaultMessageScope,
};
/** Creates a new instance of WSDLServiceScopeBuilderHandler */
BuilderHandlerMessageScope(
Collection<String> policyURIs
, Map<String,PolicySourceModel> policyStore
, Object policySubject
, Scope scope
, QName service, QName port, QName operation, QName message) {
super(policyURIs, policyStore, policySubject);
this.service = service;
this.port = port;
this.operation = operation;
this.scope = scope;
this.message = message;
}
/**
* Multiple bound operations may refer to the same fault messages. This would result
* in multiple builder handlers referring to the same policies. This method allows
* to sort out these duplicate handlers.
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof BuilderHandlerMessageScope)) {
return false;
}
final BuilderHandlerMessageScope that = (BuilderHandlerMessageScope) obj;
boolean result = true;
result = result && ((this.policySubject == null) ? ((that.policySubject == null) ? true : false) :this.policySubject.equals(that.policySubject));
result = result && ((this.scope == null) ? ((that.scope == null) ? true : false) :this.scope.equals(that.scope));
result = result && ((this.message == null) ? ((that.message == null) ? true : false) :this.message.equals(that.message));
if (this.scope != Scope.FaultMessageScope) {
result = result && ((this.service == null) ? ((that.service == null) ? true : false) :this.service.equals(that.service));
result = result && ((this.port == null) ? ((that.port == null) ? true : false) :this.port.equals(that.port));
result = result && ((this.operation == null) ? ((that.operation == null) ? true : false) :this.operation.equals(that.operation));
}
return result;
}
@Override
public int hashCode() {
int hashCode = 19;
hashCode = 31 * hashCode + (policySubject == null ? 0 : policySubject.hashCode());
hashCode = 31 * hashCode + (message == null ? 0 : message.hashCode());
hashCode = 31 * hashCode + (scope == null ? 0 : scope.hashCode());
if (scope != Scope.FaultMessageScope) {
hashCode = 31 * hashCode + (service == null ? 0 : service.hashCode());
hashCode = 31 * hashCode + (port == null ? 0 : port.hashCode());
hashCode = 31 * hashCode + (operation == null ? 0 : operation.hashCode());
}
return hashCode;
}
protected void doPopulate(final PolicyMapExtender policyMapExtender) throws PolicyException{
PolicyMapKey mapKey;
if (Scope.FaultMessageScope == scope) {
mapKey = PolicyMap.createWsdlFaultMessageScopeKey(service, port, operation, message);
} else { // in|out msg scope
mapKey = PolicyMap.createWsdlMessageScopeKey(service, port, operation);
}
if (Scope.InputMessageScope == scope) {
for (PolicySubject subject:getPolicySubjects()) {
policyMapExtender.putInputMessageSubject(mapKey, subject);
}
} else if (Scope.OutputMessageScope == scope) {
for (PolicySubject subject:getPolicySubjects()) {
policyMapExtender.putOutputMessageSubject(mapKey, subject);
}
} else if (Scope.FaultMessageScope == scope) {
for (PolicySubject subject : getPolicySubjects()) {
policyMapExtender.putFaultMessageSubject(mapKey, subject);
}
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import com.sun.xml.internal.ws.policy.PolicySubject;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import java.util.Collection;
import java.util.Map;
import javax.xml.namespace.QName;
/**
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
*/
final class BuilderHandlerOperationScope extends BuilderHandler{
private final QName service;
private final QName port;
private final QName operation;
/** Creates a new instance of WSDLServiceScopeBuilderHandler */
BuilderHandlerOperationScope(
Collection<String> policyURIs
, Map<String,PolicySourceModel> policyStore
, Object policySubject
, QName service, QName port, QName operation) {
super(policyURIs, policyStore, policySubject);
this.service = service;
this.port = port;
this.operation = operation;
}
protected void doPopulate(final PolicyMapExtender policyMapExtender) throws PolicyException{
final PolicyMapKey mapKey = PolicyMap.createWsdlOperationScopeKey(service, port, operation);
for (PolicySubject subject : getPolicySubjects()) {
policyMapExtender.putOperationSubject(mapKey, subject);
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import com.sun.xml.internal.ws.policy.PolicySubject;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import java.util.Collection;
import java.util.Map;
import javax.xml.namespace.QName;
/**
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
*/
final class BuilderHandlerServiceScope extends BuilderHandler{
private final QName service;
/**
* Creates a new instance of BuilderHandlerServiceScope
*/
BuilderHandlerServiceScope(
Collection<String> policyURIs, Map<String,PolicySourceModel> policyStore, Object policySubject, QName service) {
super(policyURIs, policyStore, policySubject);
this.service = service;
}
protected void doPopulate(final PolicyMapExtender policyMapExtender) throws PolicyException{
final PolicyMapKey mapKey = PolicyMap.createWsdlServiceScopeKey(service);
for (PolicySubject subject : getPolicySubjects()) {
policyMapExtender.putServiceSubject(mapKey, subject);
}
}
@Override
public String toString() {
return service.toString();
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.api.policy.AlternativeSelector;
import com.sun.xml.internal.ws.api.policy.PolicyResolver;
import com.sun.xml.internal.ws.api.policy.ValidationProcessor;
import com.sun.xml.internal.ws.policy.AssertionSet;
import com.sun.xml.internal.ws.policy.EffectivePolicyModifier;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionValidator.Fitness;
import com.sun.xml.internal.ws.resources.PolicyMessages;
import javax.xml.ws.WebServiceException;
/**
* This default implementation runs the policy validators on the server side and
* selects a policy alternative on the client side.
*
* @author Rama Pulavarthi
* @author Fabian Ritzmann
*/
public class DefaultPolicyResolver implements PolicyResolver {
public PolicyMap resolve(ServerContext context) {
PolicyMap map = context.getPolicyMap();
if(map != null)
validateServerPolicyMap(map);
return map;
}
public PolicyMap resolve(ClientContext context) {
PolicyMap map = context.getPolicyMap();
if(map != null)
map = doAlternativeSelection(map);
return map;
}
/**
* Checks if the PolicyMap has only single alternative in the scope.
*
* @param policyMap
* PolicyMap that needs to be validated.
*/
private void validateServerPolicyMap(PolicyMap policyMap) {
try {
final ValidationProcessor validationProcessor = ValidationProcessor.getInstance();
for (Policy policy : policyMap) {
// TODO: here is a good place to check if the actual policy has only one alternative...
for (AssertionSet assertionSet : policy) {
for (PolicyAssertion assertion : assertionSet) {
Fitness validationResult = validationProcessor.validateServerSide(assertion);
if (validationResult != Fitness.SUPPORTED) {
throw new PolicyException(PolicyMessages.WSP_1015_SERVER_SIDE_ASSERTION_VALIDATION_FAILED(
assertion.getName(),
validationResult));
}
}
}
}
} catch (PolicyException e) {
throw new WebServiceException(e);
}
}
/**
* Selects a best alternative if there are multiple policy alternatives.
*
* @param policyMap
* @return
*/
private PolicyMap doAlternativeSelection(PolicyMap policyMap) {
final EffectivePolicyModifier modifier = EffectivePolicyModifier.createEffectivePolicyModifier();
modifier.connect(policyMap);
try {
AlternativeSelector.doSelection(modifier);
} catch (PolicyException e) {
throw new WebServiceException(e);
}
return policyMap;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicyMapMutator;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
/**
* Used for populating changes into PolicyMap. Once a PolicyMap is created
* PolicyMapBuilder notifies all the registered WSPolicyBuilderHandler to populate
* changes to the PolicyMap.
*
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
*/
class PolicyMapBuilder {
/**
* policyBuilders should contain list of registered PolicyBuilders
*/
private List<BuilderHandler> policyBuilders = new LinkedList<BuilderHandler>();
/**
* Creates a new instance of PolicyMapBuilder
*/
PolicyMapBuilder() {
// nothing to initialize
}
/**
* Registers another builder, which has to be notified after a new
* PolicyMap is created in order to populate it's changes.
*
*/
void registerHandler(final BuilderHandler builder){
if (null != builder) {
policyBuilders.add(builder);
}
}
/**
* Iterates all the registered PolicyBuilders and lets them populate
* their changes into PolicyMap. Registers mutators given as a parameter
* with the newly created map.
*/
PolicyMap getPolicyMap(final PolicyMapMutator... externalMutators) throws PolicyException{
return getNewPolicyMap(externalMutators);
}
/**
* Iterates all the registered PolicyBuilders and lets them populate
* their changes into PolicyMap. Registers mutators from collection given as a parameter
* with the newly created map.
*/
private PolicyMap getNewPolicyMap(final PolicyMapMutator... externalMutators) throws PolicyException{
final HashSet<PolicyMapMutator> mutators = new HashSet<PolicyMapMutator>();
final PolicyMapExtender myExtender = PolicyMapExtender.createPolicyMapExtender();
mutators.add(myExtender);
if (null != externalMutators) {
mutators.addAll(Arrays.asList(externalMutators));
}
final PolicyMap policyMap = PolicyMap.createPolicyMap(mutators);
for(BuilderHandler builder : policyBuilders){
builder.populate(myExtender);
}
return policyMap;
}
void unregisterAll() {
this.policyBuilders = null;
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.addressing.policy.AddressingFeatureConfigurator;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLService;
import com.sun.xml.internal.ws.encoding.policy.FastInfosetFeatureConfigurator;
import com.sun.xml.internal.ws.encoding.policy.MtomFeatureConfigurator;
import com.sun.xml.internal.ws.encoding.policy.SelectOptimalEncodingFeatureConfigurator;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import com.sun.xml.internal.ws.policy.jaxws.spi.PolicyFeatureConfigurator;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.util.ServiceFinder;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.WebServiceException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
/**
* @author Rama Pulavarthi
* @author Fabian Ritzmann
*/
public class PolicyUtil {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtil.class);
private static final Collection<PolicyFeatureConfigurator> CONFIGURATORS =
new LinkedList<PolicyFeatureConfigurator>();
static {
// Add feature configurators that are already built into JAX-WS
CONFIGURATORS.add(new AddressingFeatureConfigurator());
CONFIGURATORS.add(new MtomFeatureConfigurator());
CONFIGURATORS.add(new FastInfosetFeatureConfigurator());
CONFIGURATORS.add(new SelectOptimalEncodingFeatureConfigurator());
// Dynamically discover remaining feature configurators
addServiceProviders(CONFIGURATORS, PolicyFeatureConfigurator.class);
}
/**
* Adds the dynamically discovered implementations for the given service class
* to the given collection.
*
* @param <T> The type of the service class.
* @param providers The discovered implementations are added to this collection.
* @param service The service interface.
*/
public static <T> void addServiceProviders(Collection<T> providers, Class<T> service) {
final Iterator<T> foundProviders = ServiceFinder.find(service).iterator();
while (foundProviders.hasNext()) {
providers.add(foundProviders.next());
}
}
/**
* Iterates through the ports in the WSDL model, for each policy in the policy
* map that is attached at endpoint scope computes a list of corresponding
* WebServiceFeatures and sets them on the port.
*
* @param model The WSDL model
* @param policyMap The policy map
* @throws PolicyException If the list of WebServiceFeatures could not be computed
*/
public static void configureModel(final WSDLModel model, PolicyMap policyMap) throws PolicyException {
LOGGER.entering(model, policyMap);
for (WSDLService service : model.getServices().values()) {
for (WSDLPort port : service.getPorts()) {
final Collection<WebServiceFeature> features = getPortScopedFeatures(policyMap, service.getName(), port.getName());
for (WebServiceFeature feature : features) {
port.addFeature(feature);
port.getBinding().addFeature(feature);
}
}
}
LOGGER.exiting();
}
/**
* Returns the list of features that correspond to the policies in the policy
* map for a give port
*
* @param policyMap The service policies
* @param serviceName The service name
* @param portName The service port name
* @return List of features for the given port corresponding to the policies in the map
*/
public static Collection<WebServiceFeature> getPortScopedFeatures(PolicyMap policyMap, QName serviceName, QName portName) {
LOGGER.entering(policyMap, serviceName, portName);
Collection<WebServiceFeature> features = new ArrayList<WebServiceFeature>();
try {
final PolicyMapKey key = PolicyMap.createWsdlEndpointScopeKey(serviceName, portName);
for (PolicyFeatureConfigurator configurator : CONFIGURATORS) {
Collection<WebServiceFeature> additionalFeatures = configurator.getFeatures(key, policyMap);
if (additionalFeatures != null) {
features.addAll(additionalFeatures);
}
}
} catch (PolicyException e) {
throw new WebServiceException(e);
}
LOGGER.exiting(features);
return features;
}
}

View File

@@ -0,0 +1,466 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.txw2.TypedXmlWriter;
import com.sun.xml.internal.ws.addressing.policy.AddressingPolicyMapConfigurator;
import com.sun.xml.internal.ws.api.WSBinding;
import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory;
import com.sun.xml.internal.ws.api.policy.PolicyResolver;
import com.sun.xml.internal.ws.api.model.CheckedException;
import com.sun.xml.internal.ws.api.model.JavaMethod;
import com.sun.xml.internal.ws.api.model.SEIModel;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundFault;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundPortType;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLFault;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLInput;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLMessage;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOperation;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPortType;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLService;
import com.sun.xml.internal.ws.api.policy.ModelGenerator;
import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension;
import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGenExtnContext;
import com.sun.xml.internal.ws.encoding.policy.MtomPolicyMapConfigurator;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyConstants;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapExtender;
import com.sun.xml.internal.ws.policy.PolicyMapUtil;
import com.sun.xml.internal.ws.policy.PolicyMerger;
import com.sun.xml.internal.ws.policy.PolicySubject;
import com.sun.xml.internal.ws.policy.jaxws.spi.PolicyMapConfigurator;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicyModelGenerator;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicyModelMarshaller;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import com.sun.xml.internal.ws.policy.subject.WsdlBindingSubject;
import com.sun.xml.internal.ws.resources.PolicyMessages;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceException;
/**
* Marshals the contents of a policy map to WSDL.
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
* @author Fabian Ritzmann
*/
public class PolicyWSDLGeneratorExtension extends WSDLGeneratorExtension {
static enum ScopeType {
SERVICE,
ENDPOINT,
OPERATION,
INPUT_MESSAGE,
OUTPUT_MESSAGE,
FAULT_MESSAGE
}
private final static PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyWSDLGeneratorExtension.class);
private PolicyMap policyMap;
private SEIModel seiModel;
private final Collection<PolicySubject> subjects = new LinkedList<PolicySubject>();
private final PolicyModelMarshaller marshaller = PolicyModelMarshaller.getXmlMarshaller(true);
private final PolicyMerger merger = PolicyMerger.getMerger();
@Override
public void start(final WSDLGenExtnContext context) {
LOGGER.entering();
try {
this.seiModel = context.getModel();
final PolicyMapConfigurator[] policyMapConfigurators = loadConfigurators();
final PolicyMapExtender[] extenders = new PolicyMapExtender[policyMapConfigurators.length];
for (int i = 0; i < policyMapConfigurators.length; i++) {
extenders[i] = PolicyMapExtender.createPolicyMapExtender();
}
// Read policy config file
policyMap = PolicyResolverFactory.create().resolve(
new PolicyResolver.ServerContext(policyMap, context.getContainer(), context.getEndpointClass(), false, extenders));
if (policyMap == null) {
LOGGER.fine(PolicyMessages.WSP_1019_CREATE_EMPTY_POLICY_MAP());
policyMap = PolicyMap.createPolicyMap(Arrays.asList(extenders));
}
final WSBinding binding = context.getBinding();
try {
final Collection<PolicySubject> policySubjects = new LinkedList<PolicySubject>();
for (int i = 0; i < policyMapConfigurators.length; i++) {
policySubjects.addAll(policyMapConfigurators[i].update(policyMap, seiModel, binding));
extenders[i].disconnect();
}
PolicyMapUtil.insertPolicies(policyMap, policySubjects, this.seiModel.getServiceQName(), this.seiModel.getPortName());
} catch (PolicyException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1017_MAP_UPDATE_FAILED(), e));
}
final TypedXmlWriter root = context.getRoot();
root._namespace(NamespaceVersion.v1_2.toString(), NamespaceVersion.v1_2.getDefaultNamespacePrefix());
root._namespace(NamespaceVersion.v1_5.toString(), NamespaceVersion.v1_5.getDefaultNamespacePrefix());
root._namespace(PolicyConstants.WSU_NAMESPACE_URI, PolicyConstants.WSU_NAMESPACE_PREFIX);
} finally {
LOGGER.exiting();
}
}
@Override
public void addDefinitionsExtension(final TypedXmlWriter definitions) {
try {
LOGGER.entering();
if (policyMap == null) {
LOGGER.fine(PolicyMessages.WSP_1009_NOT_MARSHALLING_ANY_POLICIES_POLICY_MAP_IS_NULL());
} else {
subjects.addAll(policyMap.getPolicySubjects());
final PolicyModelGenerator generator = ModelGenerator.getGenerator();
Set<String> policyIDsOrNamesWritten = new HashSet<String>();
for (PolicySubject subject : subjects) {
if (subject.getSubject() == null) {
LOGGER.fine(PolicyMessages.WSP_1008_NOT_MARSHALLING_WSDL_SUBJ_NULL(subject));
} else {
final Policy policy;
try {
policy = subject.getEffectivePolicy(merger);
} catch (PolicyException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1011_FAILED_TO_RETRIEVE_EFFECTIVE_POLICY_FOR_SUBJECT(subject.toString()), e));
}
if ((null == policy.getIdOrName()) || (policyIDsOrNamesWritten.contains(policy.getIdOrName()))) {
LOGGER.fine(PolicyMessages.WSP_1016_POLICY_ID_NULL_OR_DUPLICATE(policy));
} else {
try {
final PolicySourceModel policyInfoset = generator.translate(policy);
marshaller.marshal(policyInfoset, definitions);
} catch (PolicyException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1018_FAILED_TO_MARSHALL_POLICY(policy.getIdOrName()), e));
}
policyIDsOrNamesWritten.add(policy.getIdOrName());
}
}
}
}
} finally {
LOGGER.exiting();
}
}
@Override
public void addServiceExtension(final TypedXmlWriter service) {
LOGGER.entering();
final String serviceName = (null == seiModel) ? null : seiModel.getServiceQName().getLocalPart();
selectAndProcessSubject(service, WSDLService.class, ScopeType.SERVICE, serviceName);
LOGGER.exiting();
}
@Override
public void addPortExtension(final TypedXmlWriter port) {
LOGGER.entering();
final String portName = (null == seiModel) ? null : seiModel.getPortName().getLocalPart();
selectAndProcessSubject(port, WSDLPort.class, ScopeType.ENDPOINT, portName);
LOGGER.exiting();
}
@Override
public void addPortTypeExtension(final TypedXmlWriter portType) {
LOGGER.entering();
final String portTypeName = (null == seiModel) ? null : seiModel.getPortTypeName().getLocalPart();
selectAndProcessSubject(portType, WSDLPortType.class, ScopeType.ENDPOINT, portTypeName);
LOGGER.exiting();
}
@Override
public void addBindingExtension(final TypedXmlWriter binding) {
LOGGER.entering();
final QName bindingName = (null == seiModel) ? null : seiModel.getBoundPortTypeName();
selectAndProcessBindingSubject(binding, WSDLBoundPortType.class, ScopeType.ENDPOINT, bindingName);
LOGGER.exiting();
}
@Override
public void addOperationExtension(final TypedXmlWriter operation, final JavaMethod method) {
LOGGER.entering();
selectAndProcessSubject(operation, WSDLOperation.class, ScopeType.OPERATION, (String)null);
LOGGER.exiting();
}
@Override
public void addBindingOperationExtension(final TypedXmlWriter operation, final JavaMethod method) {
LOGGER.entering();
final QName operationName = (method == null) ? null : new QName(method.getOwner().getTargetNamespace(), method.getOperationName());
selectAndProcessBindingSubject(operation, WSDLBoundOperation.class, ScopeType.OPERATION, operationName);
LOGGER.exiting();
}
@Override
public void addInputMessageExtension(final TypedXmlWriter message, final JavaMethod method) {
LOGGER.entering();
final String messageName = (null == method) ? null : method.getRequestMessageName();
selectAndProcessSubject(message, WSDLMessage.class, ScopeType.INPUT_MESSAGE, messageName);
LOGGER.exiting();
}
@Override
public void addOutputMessageExtension(final TypedXmlWriter message, final JavaMethod method) {
LOGGER.entering();
final String messageName = (null == method) ? null : method.getResponseMessageName();
selectAndProcessSubject(message, WSDLMessage.class, ScopeType.OUTPUT_MESSAGE, messageName);
LOGGER.exiting();
}
@Override
public void addFaultMessageExtension(final TypedXmlWriter message, final JavaMethod method, final CheckedException exception) {
LOGGER.entering();
final String messageName = (null == exception) ? null : exception.getMessageName();
selectAndProcessSubject(message, WSDLMessage.class, ScopeType.FAULT_MESSAGE, messageName);
LOGGER.exiting();
}
@Override
public void addOperationInputExtension(final TypedXmlWriter input, final JavaMethod method) {
LOGGER.entering();
final String messageName = (null == method) ? null : method.getRequestMessageName();
selectAndProcessSubject(input, WSDLInput.class, ScopeType.INPUT_MESSAGE, messageName);
LOGGER.exiting();
}
@Override
public void addOperationOutputExtension(final TypedXmlWriter output, final JavaMethod method) {
LOGGER.entering();
final String messageName = (null == method) ? null : method.getResponseMessageName();
selectAndProcessSubject(output, WSDLOutput.class, ScopeType.OUTPUT_MESSAGE, messageName);
LOGGER.exiting();
}
@Override
public void addOperationFaultExtension(final TypedXmlWriter fault, final JavaMethod method, final CheckedException exception) {
LOGGER.entering();
final String messageName = (null == exception) ? null : exception.getMessageName();
selectAndProcessSubject(fault, WSDLFault.class, ScopeType.FAULT_MESSAGE, messageName);
LOGGER.exiting();
}
@Override
public void addBindingOperationInputExtension(final TypedXmlWriter input, final JavaMethod method) {
LOGGER.entering();
final QName operationName = new QName(method.getOwner().getTargetNamespace(), method.getOperationName());
selectAndProcessBindingSubject(input, WSDLBoundOperation.class, ScopeType.INPUT_MESSAGE, operationName);
LOGGER.exiting();
}
@Override
public void addBindingOperationOutputExtension(final TypedXmlWriter output, final JavaMethod method) {
LOGGER.entering();
final QName operationName = new QName(method.getOwner().getTargetNamespace(), method.getOperationName());
selectAndProcessBindingSubject(output, WSDLBoundOperation.class, ScopeType.OUTPUT_MESSAGE, operationName);
LOGGER.exiting();
}
@Override
public void addBindingOperationFaultExtension(final TypedXmlWriter writer, final JavaMethod method, final CheckedException exception) {
LOGGER.entering(writer, method, exception);
if (subjects != null) {
for (PolicySubject subject : subjects) { // iterate over all subjects in policy map
if (this.policyMap.isFaultMessageSubject(subject)) {
final Object concreteSubject = subject.getSubject();
if (concreteSubject != null) {
final String exceptionName = exception == null ? null : exception.getMessageName();
if (exceptionName == null) { // no name provided to check
writePolicyOrReferenceIt(subject, writer);
}
if (WSDLBoundFaultContainer.class.isInstance(concreteSubject)) { // is it our class?
WSDLBoundFaultContainer faultContainer = (WSDLBoundFaultContainer) concreteSubject;
WSDLBoundFault fault = faultContainer.getBoundFault();
WSDLBoundOperation operation = faultContainer.getBoundOperation();
if (exceptionName.equals(fault.getName()) &&
operation.getName().getLocalPart().equals(method.getOperationName())) {
writePolicyOrReferenceIt(subject, writer);
}
}
else if (WsdlBindingSubject.class.isInstance(concreteSubject)) {
WsdlBindingSubject wsdlSubject = (WsdlBindingSubject) concreteSubject;
if ((wsdlSubject.getMessageType() == WsdlBindingSubject.WsdlMessageType.FAULT) &&
exception.getOwner().getTargetNamespace().equals(wsdlSubject.getName().getNamespaceURI()) &&
exceptionName.equals(wsdlSubject.getName().getLocalPart())) {
writePolicyOrReferenceIt(subject, writer);
}
}
}
}
}
}
LOGGER.exiting();
}
/**
* This method should only be invoked by interface methods that deal with WSDL binding because they
* may use the QName of the WSDL binding element as PolicySubject instead of a WSDL object.
*
* @param xmlWriter A TypedXmlWriter.
* @param clazz The policy subject.
* @param scopeType The WSDL scope.
* @param bindingName The WSDL binding name.
*/
private void selectAndProcessSubject(final TypedXmlWriter xmlWriter, final Class clazz, final ScopeType scopeType, final QName bindingName) {
LOGGER.entering(xmlWriter, clazz, scopeType, bindingName);
if (bindingName == null) {
selectAndProcessSubject(xmlWriter, clazz, scopeType, (String) null);
} else {
if (subjects != null) {
for (PolicySubject subject : subjects) {
if (bindingName.equals(subject.getSubject())) {
writePolicyOrReferenceIt(subject, xmlWriter);
}
}
}
selectAndProcessSubject(xmlWriter, clazz, scopeType, bindingName.getLocalPart());
}
LOGGER.exiting();
}
private void selectAndProcessBindingSubject(final TypedXmlWriter xmlWriter, final Class clazz, final ScopeType scopeType, final QName bindingName) {
LOGGER.entering(xmlWriter, clazz, scopeType, bindingName);
if ((subjects != null) && (bindingName != null)) {
for (PolicySubject subject : subjects) {
if (subject.getSubject() instanceof WsdlBindingSubject) {
final WsdlBindingSubject wsdlSubject = (WsdlBindingSubject) subject.getSubject();
if (bindingName.equals(wsdlSubject.getName())) {
writePolicyOrReferenceIt(subject, xmlWriter);
}
}
}
}
selectAndProcessSubject(xmlWriter, clazz, scopeType, bindingName);
LOGGER.exiting();
}
private void selectAndProcessSubject(final TypedXmlWriter xmlWriter, final Class clazz, final ScopeType scopeType, final String wsdlName) {
LOGGER.entering(xmlWriter, clazz, scopeType, wsdlName);
if (subjects != null) {
for (PolicySubject subject : subjects) { // iterate over all subjects in policy map
if (isCorrectType(policyMap, subject, scopeType)) {
final Object concreteSubject = subject.getSubject();
if (concreteSubject != null && clazz.isInstance(concreteSubject)) { // is it our class?
if (null == wsdlName) { // no name provided to check
writePolicyOrReferenceIt(subject, xmlWriter);
} else {
try {
final Method getNameMethod = clazz.getDeclaredMethod("getName");
if (stringEqualsToStringOrQName(wsdlName, getNameMethod.invoke(concreteSubject))) {
writePolicyOrReferenceIt(subject, xmlWriter);
}
} catch (NoSuchMethodException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1003_UNABLE_TO_CHECK_ELEMENT_NAME(clazz.getName(), wsdlName), e));
} catch (IllegalAccessException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1003_UNABLE_TO_CHECK_ELEMENT_NAME(clazz.getName(), wsdlName), e));
} catch (InvocationTargetException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1003_UNABLE_TO_CHECK_ELEMENT_NAME(clazz.getName(), wsdlName), e));
}
}
}
}
}
}
LOGGER.exiting();
}
private static boolean isCorrectType(final PolicyMap map, final PolicySubject subject, final ScopeType type) {
switch (type) {
case OPERATION:
return !(map.isInputMessageSubject(subject) || map.isOutputMessageSubject(subject) || map.isFaultMessageSubject(subject));
case INPUT_MESSAGE:
return map.isInputMessageSubject(subject);
case OUTPUT_MESSAGE:
return map.isOutputMessageSubject(subject);
case FAULT_MESSAGE:
return map.isFaultMessageSubject(subject);
default:
return true;
}
}
private boolean stringEqualsToStringOrQName(final String first, final Object second) {
return (second instanceof QName) ? first.equals(((QName) second).getLocalPart()) : first.equals(second);
}
/**
* Adds a PolicyReference element that points to the policy of the element,
* if the policy does not have any id or name. Writes policy inside the element otherwise.
*
* @param subject
* PolicySubject to be referenced or marshalled
* @param writer
* A TXW on to which we shall add the PolicyReference
*/
private void writePolicyOrReferenceIt(final PolicySubject subject, final TypedXmlWriter writer) {
final Policy policy;
try {
policy = subject.getEffectivePolicy(merger);
} catch (PolicyException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1011_FAILED_TO_RETRIEVE_EFFECTIVE_POLICY_FOR_SUBJECT(subject.toString()), e));
}
if (policy != null) {
if (null == policy.getIdOrName()) {
final PolicyModelGenerator generator = ModelGenerator.getGenerator();
try {
final PolicySourceModel policyInfoset = generator.translate(policy);
marshaller.marshal(policyInfoset, writer);
} catch (PolicyException pe) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1002_UNABLE_TO_MARSHALL_POLICY_OR_POLICY_REFERENCE(), pe));
}
} else {
final TypedXmlWriter policyReference = writer._element(policy.getNamespaceVersion().asQName(XmlToken.PolicyReference), TypedXmlWriter.class);
policyReference._attribute(XmlToken.Uri.toString(), '#' + policy.getIdOrName());
}
}
}
private PolicyMapConfigurator[] loadConfigurators() {
final Collection<PolicyMapConfigurator> configurators = new LinkedList<PolicyMapConfigurator>();
// Add map configurators that are already built into JAX-WS
configurators.add(new AddressingPolicyMapConfigurator());
configurators.add(new MtomPolicyMapConfigurator());
// Dynamically discover remaining map configurators
PolicyUtil.addServiceProviders(configurators, PolicyMapConfigurator.class);
return configurators.toArray(new PolicyMapConfigurator[configurators.size()]);
}
}

View File

@@ -0,0 +1,990 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLObject;
import com.sun.xml.internal.ws.api.model.wsdl.editable.*;
import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension;
import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtensionContext;
import com.sun.xml.internal.ws.api.policy.PolicyResolver;
import com.sun.xml.internal.ws.resources.PolicyMessages;
import com.sun.xml.internal.ws.policy.jaxws.SafePolicyReader.PolicyRecord;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModelContext;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.util.xml.XmlUtil;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.ws.WebServiceException;
/**
* This class parses the Policy Attachments in the WSDL and creates a PolicyMap thaty captures the policies configured on
* different PolicySubjects in the wsdl.
*
* After, it is finished it sets the PolicyMap on the WSDLModel.
*
* @author Jakub Podlesak (jakub.podlesak at sun.com)
* @author Fabian Ritzmann
* @author Rama Pulavarthi
*/
final public class PolicyWSDLParserExtension extends WSDLParserExtension {
enum HandlerType {
PolicyUri, AnonymousPolicyId
}
final static class PolicyRecordHandler {
String handler;
HandlerType type;
PolicyRecordHandler(HandlerType type, String handler) {
this.type = type;
this.handler = handler;
}
HandlerType getType() {
return type;
}
String getHandler() {
return handler;
}
}
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyWSDLParserExtension.class);
//anonymous policy id prefix
private static final StringBuffer AnonymnousPolicyIdPrefix = new StringBuffer("#__anonymousPolicy__ID");
// anonymous policies count
private int anonymousPoliciesCount;
private final SafePolicyReader policyReader = new SafePolicyReader();
// policy queue -- needed for evaluating the right order policy of policy models expansion
private PolicyRecord expandQueueHead = null;
// storage for policy models with an id passed by
private Map<String,PolicyRecord> policyRecordsPassedBy = null;
// storage for anonymous policies defined within given WSDL
private Map<String,PolicySourceModel> anonymousPolicyModels = null;
// container for URIs of policies referenced
private List<String> unresolvedUris = null;
// structures for policies really needed to build a map
private final LinkedList<String> urisNeeded = new LinkedList<String>();
private final Map<String, PolicySourceModel> modelsNeeded = new HashMap<String, PolicySourceModel>();
// lookup tables for Policy attachments found
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4ServiceMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4PortMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4PortTypeMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4BindingMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4BoundOperationMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4OperationMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4MessageMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4InputMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4OutputMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4FaultMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4BindingInputOpMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4BindingOutputOpMap = null;
private Map<WSDLObject, Collection<PolicyRecordHandler>> handlers4BindingFaultOpMap = null;
private PolicyMapBuilder policyBuilder = new PolicyMapBuilder();
private boolean isPolicyProcessed(final String policyUri) {
return modelsNeeded.containsKey(policyUri);
}
private void addNewPolicyNeeded(final String policyUri, final PolicySourceModel policyModel) {
if (!modelsNeeded.containsKey(policyUri)) {
modelsNeeded.put(policyUri, policyModel);
urisNeeded.addFirst(policyUri);
}
}
private Map<String, PolicySourceModel> getPolicyModels() {
return modelsNeeded;
}
private Map<String,PolicyRecord> getPolicyRecordsPassedBy() {
if (null==policyRecordsPassedBy) {
policyRecordsPassedBy = new HashMap<String,PolicyRecord>();
}
return policyRecordsPassedBy;
}
private Map<String,PolicySourceModel> getAnonymousPolicyModels() {
if (null==anonymousPolicyModels) {
anonymousPolicyModels = new HashMap<String,PolicySourceModel>();
}
return anonymousPolicyModels;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4ServiceMap() {
if (null==handlers4ServiceMap) {
handlers4ServiceMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4ServiceMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4PortMap() {
if (null==handlers4PortMap) {
handlers4PortMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4PortMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4PortTypeMap() {
if (null==handlers4PortTypeMap) {
handlers4PortTypeMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4PortTypeMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4BindingMap() {
if (null==handlers4BindingMap) {
handlers4BindingMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4BindingMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4OperationMap() {
if (null==handlers4OperationMap) {
handlers4OperationMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4OperationMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4BoundOperationMap() {
if (null==handlers4BoundOperationMap) {
handlers4BoundOperationMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4BoundOperationMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4MessageMap() {
if (null==handlers4MessageMap) {
handlers4MessageMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4MessageMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4InputMap() {
if (null==handlers4InputMap) {
handlers4InputMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4InputMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4OutputMap() {
if (null==handlers4OutputMap) {
handlers4OutputMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4OutputMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4FaultMap() {
if (null==handlers4FaultMap) {
handlers4FaultMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4FaultMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4BindingInputOpMap() {
if (null==handlers4BindingInputOpMap) {
handlers4BindingInputOpMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4BindingInputOpMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4BindingOutputOpMap() {
if (null==handlers4BindingOutputOpMap) {
handlers4BindingOutputOpMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4BindingOutputOpMap;
}
private Map<WSDLObject, Collection<PolicyRecordHandler>> getHandlers4BindingFaultOpMap() {
if (null==handlers4BindingFaultOpMap) {
handlers4BindingFaultOpMap = new HashMap<WSDLObject,Collection<PolicyRecordHandler>>();
}
return handlers4BindingFaultOpMap;
}
private List<String> getUnresolvedUris(final boolean emptyListNeeded) {
if ((null == unresolvedUris) || emptyListNeeded) {
unresolvedUris = new LinkedList<String>();
}
return unresolvedUris;
}
private void policyRecToExpandQueue(final PolicyRecord policyRec) {
if (null==expandQueueHead) {
expandQueueHead = policyRec;
} else {
expandQueueHead = expandQueueHead.insert(policyRec);
}
}
/**
* Creates a new instance of PolicyWSDLParserExtension
*/
public PolicyWSDLParserExtension() {
}
private PolicyRecordHandler readSinglePolicy(final PolicyRecord policyRec, final boolean inner) {
PolicyRecordHandler handler = null;
String policyId = policyRec.policyModel.getPolicyId();
if (policyId == null) {
policyId = policyRec.policyModel.getPolicyName();
}
if (policyId != null) { // policy id defined, keep the policy
handler = new PolicyRecordHandler(HandlerType.PolicyUri, policyRec.getUri());
getPolicyRecordsPassedBy().put(policyRec.getUri(), policyRec);
policyRecToExpandQueue(policyRec);
} else if (inner) { // no id given to the policy --> keep as an annonymous policy model
final String anonymousId = AnonymnousPolicyIdPrefix.append(anonymousPoliciesCount++).toString();
handler = new PolicyRecordHandler(HandlerType.AnonymousPolicyId,anonymousId);
getAnonymousPolicyModels().put(anonymousId, policyRec.policyModel);
if (null != policyRec.unresolvedURIs) {
getUnresolvedUris(false).addAll(policyRec.unresolvedURIs);
}
}
return handler;
}
private void addHandlerToMap(
final Map<WSDLObject, Collection<PolicyRecordHandler>> map, final WSDLObject key, final PolicyRecordHandler handler) {
if (map.containsKey(key)) {
map.get(key).add(handler);
} else {
final Collection<PolicyRecordHandler> newSet = new LinkedList<PolicyRecordHandler>();
newSet.add(handler);
map.put(key,newSet);
}
}
private String getBaseUrl(final String policyUri) {
if (null == policyUri) {
return null;
}
// TODO: encoded urls (escaped characters) might be a problem ?
final int fragmentIdx = policyUri.indexOf('#');
return (fragmentIdx == -1) ? policyUri : policyUri.substring(0, fragmentIdx);
}
// adding current url even to locally referenced policies
// in order to distinguish imported policies
private void processReferenceUri(
final String policyUri,
final WSDLObject element,
final XMLStreamReader reader,
final Map<WSDLObject, Collection<PolicyRecordHandler>> map) {
if (null == policyUri || policyUri.length() == 0) {
return;
}
if ('#' != policyUri.charAt(0)) { // external uri (already)
getUnresolvedUris(false).add(policyUri);
}
addHandlerToMap(map, element,
new PolicyRecordHandler(
HandlerType.PolicyUri,
SafePolicyReader.relativeToAbsoluteUrl(policyUri, reader.getLocation().getSystemId())));
}
private boolean processSubelement(
final WSDLObject element, final XMLStreamReader reader, final Map<WSDLObject, Collection<PolicyRecordHandler>> map) {
if (NamespaceVersion.resolveAsToken(reader.getName()) == XmlToken.PolicyReference) { // "PolicyReference" element interests us
processReferenceUri(policyReader.readPolicyReferenceElement(reader), element, reader, map);
return true;
} else if (NamespaceVersion.resolveAsToken(reader.getName()) == XmlToken.Policy) { // policy could be defined here
final PolicyRecordHandler handler =
readSinglePolicy(
policyReader.readPolicyElement(
reader,
(null == reader.getLocation().getSystemId()) ? // baseUrl
"" : reader.getLocation().getSystemId()),
true);
if (null != handler) { // only policies with an Id can work for us
addHandlerToMap(map, element, handler);
} // endif null != handler
return true; // element consumed
}//end if Policy element found
return false;
}
private void processAttributes(final WSDLObject element, final XMLStreamReader reader, final Map<WSDLObject, Collection<PolicyRecordHandler>> map) {
final String[] uriArray = getPolicyURIsFromAttr(reader);
if (null != uriArray) {
for (String policyUri : uriArray) {
processReferenceUri(policyUri, element, reader, map);
}
}
}
@Override
public boolean portElements(final EditableWSDLPort port, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(port, reader, getHandlers4PortMap());
LOGGER.exiting();
return result;
}
@Override
public void portAttributes(final EditableWSDLPort port, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(port, reader, getHandlers4PortMap());
LOGGER.exiting();
}
@Override
public boolean serviceElements(final EditableWSDLService service, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(service, reader, getHandlers4ServiceMap());
LOGGER.exiting();
return result;
}
@Override
public void serviceAttributes(final EditableWSDLService service, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(service, reader, getHandlers4ServiceMap());
LOGGER.exiting();
}
@Override
public boolean definitionsElements(final XMLStreamReader reader){
LOGGER.entering();
if (NamespaceVersion.resolveAsToken(reader.getName()) == XmlToken.Policy) { // Only "Policy" element interests me
readSinglePolicy(
policyReader.readPolicyElement(
reader,
(null == reader.getLocation().getSystemId()) ? // baseUrl
"" : reader.getLocation().getSystemId()),
false);
LOGGER.exiting();
return true;
}
LOGGER.exiting();
return false;
}
@Override
public boolean bindingElements(final EditableWSDLBoundPortType binding, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(binding, reader, getHandlers4BindingMap());
LOGGER.exiting();
return result;
}
@Override
public void bindingAttributes(final EditableWSDLBoundPortType binding, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(binding, reader, getHandlers4BindingMap());
LOGGER.exiting();
}
@Override
public boolean portTypeElements(final EditableWSDLPortType portType, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(portType, reader, getHandlers4PortTypeMap());
LOGGER.exiting();
return result;
}
@Override
public void portTypeAttributes(final EditableWSDLPortType portType, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(portType, reader, getHandlers4PortTypeMap());
LOGGER.exiting();
}
@Override
public boolean portTypeOperationElements(final EditableWSDLOperation operation, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(operation, reader, getHandlers4OperationMap());
LOGGER.exiting();
return result;
}
@Override
public void portTypeOperationAttributes(final EditableWSDLOperation operation, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(operation, reader, getHandlers4OperationMap());
LOGGER.exiting();
}
@Override
public boolean bindingOperationElements(final EditableWSDLBoundOperation boundOperation, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(boundOperation, reader, getHandlers4BoundOperationMap());
LOGGER.exiting();
return result;
}
@Override
public void bindingOperationAttributes(final EditableWSDLBoundOperation boundOperation, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(boundOperation, reader, getHandlers4BoundOperationMap());
LOGGER.exiting();
}
@Override
public boolean messageElements(final EditableWSDLMessage msg, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(msg, reader, getHandlers4MessageMap());
LOGGER.exiting();
return result;
}
@Override
public void messageAttributes(final EditableWSDLMessage msg, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(msg, reader, getHandlers4MessageMap());
LOGGER.exiting();
}
@Override
public boolean portTypeOperationInputElements(final EditableWSDLInput input, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(input, reader, getHandlers4InputMap());
LOGGER.exiting();
return result;
}
@Override
public void portTypeOperationInputAttributes(final EditableWSDLInput input, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(input, reader, getHandlers4InputMap());
LOGGER.exiting();
}
@Override
public boolean portTypeOperationOutputElements(final EditableWSDLOutput output, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(output, reader, getHandlers4OutputMap());
LOGGER.exiting();
return result;
}
@Override
public void portTypeOperationOutputAttributes(final EditableWSDLOutput output, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(output, reader, getHandlers4OutputMap());
LOGGER.exiting();
}
@Override
public boolean portTypeOperationFaultElements(final EditableWSDLFault fault, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(fault, reader, getHandlers4FaultMap());
LOGGER.exiting();
return result;
}
@Override
public void portTypeOperationFaultAttributes(final EditableWSDLFault fault, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(fault, reader, getHandlers4FaultMap());
LOGGER.exiting();
}
@Override
public boolean bindingOperationInputElements(final EditableWSDLBoundOperation operation, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(operation, reader, getHandlers4BindingInputOpMap());
LOGGER.exiting();
return result;
}
@Override
public void bindingOperationInputAttributes(final EditableWSDLBoundOperation operation, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(operation, reader, getHandlers4BindingInputOpMap());
LOGGER.exiting();
}
@Override
public boolean bindingOperationOutputElements(final EditableWSDLBoundOperation operation, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(operation, reader, getHandlers4BindingOutputOpMap());
LOGGER.exiting();
return result;
}
@Override
public void bindingOperationOutputAttributes(final EditableWSDLBoundOperation operation, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(operation, reader, getHandlers4BindingOutputOpMap());
LOGGER.exiting();
}
@Override
public boolean bindingOperationFaultElements(final EditableWSDLBoundFault fault, final XMLStreamReader reader) {
LOGGER.entering();
final boolean result = processSubelement(fault, reader, getHandlers4BindingFaultOpMap());
LOGGER.exiting(result);
return result;
}
@Override
public void bindingOperationFaultAttributes(final EditableWSDLBoundFault fault, final XMLStreamReader reader) {
LOGGER.entering();
processAttributes(fault, reader, getHandlers4BindingFaultOpMap());
LOGGER.exiting();
}
private PolicyMapBuilder getPolicyMapBuilder() {
if (null == policyBuilder) {
policyBuilder = new PolicyMapBuilder();
}
return policyBuilder;
}
private Collection<String> getPolicyURIs(
final Collection<PolicyRecordHandler> handlers, final PolicySourceModelContext modelContext) throws PolicyException{
final Collection<String> result = new ArrayList<String>(handlers.size());
String policyUri;
for (PolicyRecordHandler handler : handlers) {
policyUri = handler.handler;
if (HandlerType.AnonymousPolicyId == handler.type) {
final PolicySourceModel policyModel = getAnonymousPolicyModels().get(policyUri);
policyModel.expand(modelContext);
while (getPolicyModels().containsKey(policyUri)) {
policyUri = AnonymnousPolicyIdPrefix.append(anonymousPoliciesCount++).toString();
}
getPolicyModels().put(policyUri,policyModel);
}
result.add(policyUri);
}
return result;
}
private boolean readExternalFile(final String fileUrl) {
InputStream ios = null;
XMLStreamReader reader = null;
try {
final URL xmlURL = new URL(fileUrl);
ios = xmlURL.openStream();
reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(ios);
while (reader.hasNext()) {
if (reader.isStartElement() && NamespaceVersion.resolveAsToken(reader.getName()) == XmlToken.Policy) {
readSinglePolicy(policyReader.readPolicyElement(reader, fileUrl), false);
}
reader.next();
}
return true;
} catch (IOException ioe) {
return false;
} catch (XMLStreamException xmlse) {
return false;
} finally {
PolicyUtils.IO.closeResource(reader);
PolicyUtils.IO.closeResource(ios);
}
}
@Override
public void finished(final WSDLParserExtensionContext context) {
LOGGER.entering(context);
// need to make sure proper beginning order of internal policies within unresolvedUris list
if (null != expandQueueHead) { // any policies found
final List<String> externalUris = getUnresolvedUris(false); // protect list of possible external policies
getUnresolvedUris(true); // cleaning up the list only
final LinkedList<String> baseUnresolvedUris = new LinkedList<String>();
for (PolicyRecord currentRec = expandQueueHead ; null != currentRec ; currentRec = currentRec.next) {
baseUnresolvedUris.addFirst(currentRec.getUri());
}
getUnresolvedUris(false).addAll(baseUnresolvedUris);
expandQueueHead = null; // cut the queue off
getUnresolvedUris(false).addAll(externalUris);
}
while (!getUnresolvedUris(false).isEmpty()) {
final List<String> urisToBeSolvedList = getUnresolvedUris(false);
getUnresolvedUris(true); // just cleaning up the list
for (String currentUri : urisToBeSolvedList) {
if (!isPolicyProcessed(currentUri)) {
final PolicyRecord prefetchedRecord = getPolicyRecordsPassedBy().get(currentUri);
if (null == prefetchedRecord) {
if (policyReader.getUrlsRead().contains(getBaseUrl(currentUri))) { // --> unresolvable policy
LOGGER.logSevereException(new PolicyException(PolicyMessages.WSP_1014_CAN_NOT_FIND_POLICY(currentUri)));
} else {
if (readExternalFile(getBaseUrl(currentUri))) {
getUnresolvedUris(false).add(currentUri);
}
}
} else { // policy has not been yet passed by
if (null != prefetchedRecord.unresolvedURIs) {
getUnresolvedUris(false).addAll(prefetchedRecord.unresolvedURIs);
} // end-if null != prefetchedRecord.unresolvedURIs
addNewPolicyNeeded(currentUri, prefetchedRecord.policyModel);
}
} // end-if policy already processed
} // end-foreach unresolved uris
}
final PolicySourceModelContext modelContext = PolicySourceModelContext.createContext();
for (String policyUri : urisNeeded) {
final PolicySourceModel sourceModel = modelsNeeded.get(policyUri);
try {
sourceModel.expand(modelContext);
modelContext.addModel(new URI(policyUri), sourceModel);
} catch (URISyntaxException e) {
LOGGER.logSevereException(e);
} catch (PolicyException e) {
LOGGER.logSevereException(e);
}
}
// Start-preparation of policy map builder
// iterating over all services and binding all the policies read before
try {
// messageSet holds the handlers for all wsdl:message elements. There
// may otherwise be multiple entries for policies that are contained
// by fault messages.
HashSet<BuilderHandlerMessageScope> messageSet = new HashSet<BuilderHandlerMessageScope>();
for (EditableWSDLService service : context.getWSDLModel().getServices().values()) {
if (getHandlers4ServiceMap().containsKey(service)) {
getPolicyMapBuilder().registerHandler(new BuilderHandlerServiceScope(
getPolicyURIs(getHandlers4ServiceMap().get(service),modelContext)
,getPolicyModels()
,service
,service.getName()));
}
// end service scope
for (EditableWSDLPort port : service.getPorts()) {
if (getHandlers4PortMap().containsKey(port)) {
getPolicyMapBuilder().registerHandler(
new BuilderHandlerEndpointScope(
getPolicyURIs(getHandlers4PortMap().get(port),modelContext)
,getPolicyModels()
,port
,port.getOwner().getName()
,port.getName()));
}
if ( // port.getBinding may not be null, but in case ...
null != port.getBinding()) {
if ( // handler for binding
getHandlers4BindingMap().containsKey(port.getBinding())) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerEndpointScope(
getPolicyURIs(getHandlers4BindingMap().get(port.getBinding()),modelContext)
,getPolicyModels()
,port.getBinding()
,service.getName()
,port.getName()));
} // endif handler for binding
if ( // handler for port type
getHandlers4PortTypeMap().containsKey(port.getBinding().getPortType())) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerEndpointScope(
getPolicyURIs(getHandlers4PortTypeMap().get(port.getBinding().getPortType()),modelContext)
,getPolicyModels()
,port.getBinding().getPortType()
,service.getName()
,port.getName()));
} // endif handler for port type
// end endpoint scope
for (EditableWSDLBoundOperation boundOperation : port.getBinding().getBindingOperations()) {
final EditableWSDLOperation operation = boundOperation.getOperation();
final QName operationName = new QName(boundOperation.getBoundPortType().getName().getNamespaceURI(), boundOperation.getName().getLocalPart());
// We store the message and portType/operation under the same namespace as the binding/operation so that we can match them up later
if ( // handler for operation scope -- by boundOperation
getHandlers4BoundOperationMap().containsKey(boundOperation)) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerOperationScope(
getPolicyURIs(getHandlers4BoundOperationMap().get(boundOperation),modelContext)
,getPolicyModels()
,boundOperation
,service.getName()
,port.getName()
,operationName));
} // endif handler for binding:operation scope
if ( // handler for operation scope -- by operation map
getHandlers4OperationMap().containsKey(operation)) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerOperationScope(
getPolicyURIs(getHandlers4OperationMap().get(operation),modelContext)
,getPolicyModels()
,operation
,service.getName()
,port.getName()
,operationName));
} // endif for portType:operation scope
// end operation scope
final EditableWSDLInput input = operation.getInput();
if (null!=input) {
EditableWSDLMessage inputMsg = input.getMessage();
if (inputMsg != null && getHandlers4MessageMap().containsKey(inputMsg)) {
messageSet.add(new BuilderHandlerMessageScope(
getPolicyURIs(
getHandlers4MessageMap().get(inputMsg), modelContext)
,getPolicyModels()
,inputMsg
,BuilderHandlerMessageScope.Scope.InputMessageScope
,service.getName()
,port.getName()
,operationName
,null)
);
}
}
if ( // binding op input msg
getHandlers4BindingInputOpMap().containsKey(boundOperation)) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4BindingInputOpMap().get(boundOperation),modelContext)
,getPolicyModels()
,boundOperation
,BuilderHandlerMessageScope.Scope.InputMessageScope
,service.getName()
,port.getName()
,operationName
,null));
} // endif binding op input msg
if ( null != input // portType op input msg
&& getHandlers4InputMap().containsKey(input)) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4InputMap().get(input),modelContext)
,getPolicyModels()
,input
,BuilderHandlerMessageScope.Scope.InputMessageScope
,service.getName()
,port.getName()
,operationName
,null));
} // endif portType op input msg
// end input message scope
final EditableWSDLOutput output = operation.getOutput();
if (null!=output) {
EditableWSDLMessage outputMsg = output.getMessage();
if (outputMsg != null && getHandlers4MessageMap().containsKey(outputMsg)) {
messageSet.add(new BuilderHandlerMessageScope(
getPolicyURIs(
getHandlers4MessageMap().get(outputMsg),modelContext)
,getPolicyModels()
,outputMsg
,BuilderHandlerMessageScope.Scope.OutputMessageScope
,service.getName()
,port.getName()
,operationName
,null)
);
}
}
if ( // binding op output msg
getHandlers4BindingOutputOpMap().containsKey(boundOperation)) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4BindingOutputOpMap().get(boundOperation),modelContext)
,getPolicyModels()
,boundOperation
,BuilderHandlerMessageScope.Scope.OutputMessageScope
,service.getName()
,port.getName()
,operationName
,null));
} // endif binding op output msg
if ( null != output // portType op output msg
&& getHandlers4OutputMap().containsKey(output)) {
getPolicyMapBuilder()
.registerHandler(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4OutputMap().get(output),modelContext)
,getPolicyModels()
,output
,BuilderHandlerMessageScope.Scope.OutputMessageScope
,service.getName()
,port.getName()
,operationName
,null));
} // endif portType op output msg
// end output message scope
for (EditableWSDLBoundFault boundFault : boundOperation.getFaults()) {
final EditableWSDLFault fault = boundFault.getFault();
// this shouldn't happen ususally,
// but since this scenario tested in lagacy tests, dont' fail here
if (fault == null) {
LOGGER.warning(PolicyMessages.WSP_1021_FAULT_NOT_BOUND(boundFault.getName()));
continue;
}
final EditableWSDLMessage faultMessage = fault.getMessage();
final QName faultName = new QName(boundOperation.getBoundPortType().getName().getNamespaceURI(), boundFault.getName());
// We store the message and portType/fault under the same namespace as the binding/fault so that we can match them up later
if (faultMessage != null && getHandlers4MessageMap().containsKey(faultMessage)) {
messageSet.add(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4MessageMap().get(faultMessage), modelContext)
,getPolicyModels()
,new WSDLBoundFaultContainer(boundFault, boundOperation)
,BuilderHandlerMessageScope.Scope.FaultMessageScope
,service.getName()
,port.getName()
,operationName
,faultName)
);
}
if (getHandlers4FaultMap().containsKey(fault)) {
messageSet.add(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4FaultMap().get(fault), modelContext)
,getPolicyModels()
,new WSDLBoundFaultContainer(boundFault, boundOperation)
,BuilderHandlerMessageScope.Scope.FaultMessageScope
,service.getName()
,port.getName()
,operationName
,faultName)
);
}
if (getHandlers4BindingFaultOpMap().containsKey(boundFault)) {
messageSet.add(
new BuilderHandlerMessageScope(
getPolicyURIs(getHandlers4BindingFaultOpMap().get(boundFault), modelContext)
,getPolicyModels()
,new WSDLBoundFaultContainer(boundFault, boundOperation)
,BuilderHandlerMessageScope.Scope.FaultMessageScope
,service.getName()
,port.getName()
,operationName
,faultName)
);
}
} // end foreach binding operation fault msg
// end fault message scope
} // end foreach boundOperation in port
} // endif port.getBinding() != null
} // end foreach port in service
} // end foreach service in wsdl
// Add handlers for wsdl:message elements
for (BuilderHandlerMessageScope scopeHandler : messageSet) {
getPolicyMapBuilder().registerHandler(scopeHandler);
}
} catch(PolicyException e) {
LOGGER.logSevereException(e);
}
// End-preparation of policy map builder
LOGGER.exiting();
}
// time to read possible config file and do alternative selection (on client side)
@Override
public void postFinished(final WSDLParserExtensionContext context) {
// finally register the PolicyMap on the WSDLModel
EditableWSDLModel wsdlModel = context.getWSDLModel();
PolicyMap effectiveMap;
try {
if(context.isClientSide())
effectiveMap = context.getPolicyResolver().resolve(new PolicyResolver.ClientContext(policyBuilder.getPolicyMap(),context.getContainer()));
else
effectiveMap = context.getPolicyResolver().resolve(new PolicyResolver.ServerContext(policyBuilder.getPolicyMap(), context.getContainer(),null));
wsdlModel.setPolicyMap(effectiveMap);
} catch (PolicyException e) {
LOGGER.logSevereException(e);
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1007_POLICY_EXCEPTION_WHILE_FINISHING_PARSING_WSDL(), e));
}
try {
PolicyUtil.configureModel(wsdlModel,effectiveMap);
} catch (PolicyException e) {
LOGGER.logSevereException(e);
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1012_FAILED_CONFIGURE_WSDL_MODEL(), e));
}
LOGGER.exiting();
}
/**
* Reads policy reference URIs from PolicyURIs attribute and returns them
* as a String array returns null if there is no such attribute. This method
* will attempt to check for the attribute in every supported policy namespace.
* Resulting array of URIs is concatenation of URIs defined in all found
* PolicyURIs attribute version.
*/
private String[] getPolicyURIsFromAttr(final XMLStreamReader reader) {
final StringBuilder policyUriBuffer = new StringBuilder();
for (NamespaceVersion version : NamespaceVersion.values()) {
final String value = reader.getAttributeValue(version.toString(), XmlToken.PolicyUris.toString());
if (value != null) {
policyUriBuffer.append(value).append(" ");
}
}
return (policyUriBuffer.length() > 0) ? policyUriBuffer.toString().split("[\\n ]+") : null;
}
}

View File

@@ -0,0 +1,331 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.api.policy.ModelUnmarshaller;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken;
import com.sun.xml.internal.ws.resources.PolicyMessages;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.ws.WebServiceException;
/**
* Provides methods to unmarshal policies from a XMLStreamReader safely
*
* @author Fabian Ritzmann
*/
public class SafePolicyReader {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(SafePolicyReader.class);
// urls of xml docs policies were read from
private final Set<String> urlsRead = new HashSet<String>();
private final Set<String> qualifiedPolicyUris = new HashSet<String>();
public final class PolicyRecord {
PolicyRecord next;
PolicySourceModel policyModel;
Set<String> unresolvedURIs;
private String uri;
PolicyRecord() {
// nothing to initialize
}
PolicyRecord insert(final PolicyRecord insertedRec) {
if (null==insertedRec.unresolvedURIs || insertedRec.unresolvedURIs.isEmpty()) {
insertedRec.next = this;
return insertedRec;
}
final PolicyRecord head = this;
PolicyRecord oneBeforeCurrent = null;
PolicyRecord current;
for (current = head ; null != current.next ; ) {
if ((null != current.unresolvedURIs) && current.unresolvedURIs.contains(insertedRec.uri)) {
if (null == oneBeforeCurrent) {
insertedRec.next = current;
return insertedRec;
} else { // oneBeforeCurrent != null
oneBeforeCurrent.next = insertedRec;
insertedRec.next = current;
return head;
} // end-if-else oneBeforeCurrent == null
}// end-if current record depends on inserted one
if (insertedRec.unresolvedURIs.remove(current.uri) && (insertedRec.unresolvedURIs.isEmpty())) {
insertedRec.next = current.next;
current.next = insertedRec;
return head;
} // end-if one of unresolved URIs resolved by current record and thus unresolvedURIs empty
oneBeforeCurrent = current;
current = current.next;
} // end for (current = head; null!=current.next; )
insertedRec.next = null;
current.next = insertedRec;
return head;
}
/**
* Set the URI that identifies the policy.
*
* @param uri The fully qualified URI of the policy. May be a relative URI
* if JAX-WS did not pass on any system id.
* @param id The short ID of the policy. Used for error reporting.
* @throws PolicyException If there already is a policy recorded with the
* same id.
*/
public void setUri(final String uri, final String id) throws PolicyException {
if (qualifiedPolicyUris.contains(uri)) {
throw LOGGER.logSevereException(new PolicyException(PolicyMessages.WSP_1020_DUPLICATE_ID(id)));
}
this.uri = uri;
qualifiedPolicyUris.add(uri);
}
public String getUri() {
return this.uri;
}
@Override
public String toString() {
String result = uri;
if (null!=next) {
result += "->" + next.toString();
}
return result;
}
}
/**
* Reads a policy expression from the XML stream.
*
* The XMLStreamReader should be in START_ELEMENT state and point to the policy element.
* The content of the stream is copied and then the copy is unmarshalled. The result
* is returned as a PolicyRecord.
*
* @param reader The XMLStreamReader should be in START_ELEMENT state and point to the policy element.
* @param baseUrl The system id of the document read by the reader.
* @return The policy that was read from the XML stream.
*/
public PolicyRecord readPolicyElement(final XMLStreamReader reader, final String baseUrl) {
if ((null == reader) || (!reader.isStartElement())) {
return null;
}
final StringBuffer elementCode = new StringBuffer();
final PolicyRecord policyRec = new PolicyRecord();
final QName elementName = reader.getName();
boolean insidePolicyReferenceAttr;
int depth = 0;
try{
do {
switch (reader.getEventType()) {
case XMLStreamConstants.START_ELEMENT: // process start of next element
QName curName = reader.getName();
insidePolicyReferenceAttr = NamespaceVersion.resolveAsToken(curName) == XmlToken.PolicyReference;
if (elementName.equals(curName)) { // it is our element !
depth++; // we are then deeper
}
final StringBuffer xmlnsCode = new StringBuffer(); // take care about namespaces as well
final Set<String> tmpNsSet = new HashSet<String>();
if ((null == curName.getPrefix()) || ("".equals(curName.getPrefix()))) { // no prefix
elementCode
.append('<') // start tag
.append(curName.getLocalPart());
xmlnsCode
.append(" xmlns=\"")
.append(curName.getNamespaceURI())
.append('"');
} else { // prefix presented
elementCode
.append('<') // start tag
.append(curName.getPrefix())
.append(':')
.append(curName.getLocalPart());
xmlnsCode
.append(" xmlns:")
.append(curName.getPrefix())
.append("=\"")
.append(curName.getNamespaceURI())
.append('"');
tmpNsSet.add(curName.getPrefix());
}
final int attrCount = reader.getAttributeCount(); // process element attributes
final StringBuffer attrCode = new StringBuffer();
for (int i=0; i < attrCount; i++) {
boolean uriAttrFlg = false;
if (insidePolicyReferenceAttr && "URI".equals(
reader.getAttributeName(i).getLocalPart())) { // PolicyReference found
uriAttrFlg = true;
if (null == policyRec.unresolvedURIs) { // first such URI found
policyRec.unresolvedURIs = new HashSet<String>(); // initialize URIs set
}
policyRec.unresolvedURIs.add( // add the URI
relativeToAbsoluteUrl(reader.getAttributeValue(i), baseUrl));
} // end-if PolicyReference attribute found
if ("xmlns".equals(reader.getAttributePrefix(i)) && tmpNsSet.contains(reader.getAttributeLocalName(i))) {
continue; // do not append already defined ns
}
if ((null == reader.getAttributePrefix(i)) || ("".equals(reader.getAttributePrefix(i)))) { // no attribute prefix
attrCode
.append(' ')
.append(reader.getAttributeLocalName(i))
.append("=\"")
.append(uriAttrFlg ? relativeToAbsoluteUrl(reader.getAttributeValue(i), baseUrl) : reader.getAttributeValue(i))
.append('"');
} else { // prefix`presented
attrCode
.append(' ')
.append(reader.getAttributePrefix(i))
.append(':')
.append(reader.getAttributeLocalName(i))
.append("=\"")
.append(uriAttrFlg ? relativeToAbsoluteUrl(reader.getAttributeValue(i), baseUrl) : reader.getAttributeValue(i))
.append('"');
if (!tmpNsSet.contains(reader.getAttributePrefix(i))) {
xmlnsCode
.append(" xmlns:")
.append(reader.getAttributePrefix(i))
.append("=\"")
.append(reader.getAttributeNamespace(i))
.append('"');
tmpNsSet.add(reader.getAttributePrefix(i));
} // end if prefix already processed
}
} // end foreach attr
elementCode
.append(xmlnsCode) // complete the start element tag
.append(attrCode)
.append('>');
break;
//case XMLStreamConstants.ATTRIBUTE: Unreachable (I hope ;-)
// break;
//case XMLStreamConstants.NAMESPACE: Unreachable (I hope ;-)
// break;
case XMLStreamConstants.END_ELEMENT:
curName = reader.getName();
if (elementName.equals(curName)) { // it is our element !
depth--; // go up
}
elementCode
.append("</") // append appropriate XML code
.append("".equals(curName.getPrefix())?"":curName.getPrefix()+':')
.append(curName.getLocalPart())
.append('>'); // complete the end element tag
break;
case XMLStreamConstants.CHARACTERS:
elementCode.append(reader.getText()); // append text data
break;
case XMLStreamConstants.CDATA:
elementCode
.append("<![CDATA[") // append CDATA delimiters
.append(reader.getText())
.append("]]>");
break;
case XMLStreamConstants.COMMENT: // Ignore any comments
break;
case XMLStreamConstants.SPACE: // Ignore spaces as well
break;
}
if (reader.hasNext() && depth>0) {
reader.next();
}
} while (XMLStreamConstants.END_DOCUMENT!=reader.getEventType() && depth>0);
policyRec.policyModel = ModelUnmarshaller.getUnmarshaller().unmarshalModel(
new StringReader(elementCode.toString()));
if (null != policyRec.policyModel.getPolicyId()) {
policyRec.setUri(baseUrl + "#" + policyRec.policyModel.getPolicyId(), policyRec.policyModel.getPolicyId());
} else if (policyRec.policyModel.getPolicyName() != null) {
policyRec.setUri(policyRec.policyModel.getPolicyName(), policyRec.policyModel.getPolicyName());
}
} catch(Exception e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1013_EXCEPTION_WHEN_READING_POLICY_ELEMENT(elementCode.toString()), e));
}
urlsRead.add(baseUrl);
return policyRec;
}
public Set<String> getUrlsRead() {
return this.urlsRead;
}
/**
* Reads policy reference element <wsp:PolicyReference/> and returns referenced policy URI as String
*
* @param reader The XMLStreamReader should be in START_ELEMENT state and point to the PolicyReference element.
* @return The URI contained in the PolicyReference
*/
public String readPolicyReferenceElement(final XMLStreamReader reader) {
try {
if (NamespaceVersion.resolveAsToken(reader.getName()) == XmlToken.PolicyReference) { // "PolicyReference" element interests me
for (int i = 0; i < reader.getAttributeCount(); i++) {
if (XmlToken.resolveToken(reader.getAttributeName(i).getLocalPart()) == XmlToken.Uri) {
final String uriValue = reader.getAttributeValue(i);
reader.next();
return uriValue;
}
}
}
reader.next();
return null;
} catch(XMLStreamException e) {
throw LOGGER.logSevereException(new WebServiceException(PolicyMessages.WSP_1001_XML_EXCEPTION_WHEN_PROCESSING_POLICY_REFERENCE(), e));
}
}
/**
* Utility method to construct an absolute URL from a relative URI and a base URL.
*
* If the relativeUri already is an absolute URL, the method returns the relativeUri.
*
* @param relativeUri The relative URI
* @param baseUri The base URL
* @return The relative URI appended to the base URL. If relativeUri already is
* an absolute URL, the method returns the relativeUri.
*/
public static String relativeToAbsoluteUrl(final String relativeUri, final String baseUri) {
if ('#' != relativeUri.charAt(0)) { // TODO: escaped char could be an issue?
return relativeUri; // absolute already
}
return (null == baseUri) ? relativeUri : baseUri + relativeUri;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundFault;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLObject;
import org.xml.sax.Locator;
/**
* We need data from the WSDL operation that the default WSDLBoundFault does not
* give us. This class holds all the necessary data.
*
* @author Fabian Ritzmann
*/
class WSDLBoundFaultContainer implements WSDLObject {
private final WSDLBoundFault boundFault;
private final WSDLBoundOperation boundOperation;
public WSDLBoundFaultContainer(final WSDLBoundFault fault, final WSDLBoundOperation operation) {
this.boundFault = fault;
this.boundOperation = operation;
}
public Locator getLocation() {
return null;
}
public WSDLBoundFault getBoundFault() {
return this.boundFault;
}
public WSDLBoundOperation getBoundOperation() {
return this.boundOperation;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws.spi;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import java.util.Collection;
import javax.xml.ws.WebServiceFeature;
/**
* The service provider implementing this interface will be discovered and called to configure
* wsdl model based on PolicyMap bound to it.
*
* @since JAX-WS 2.2
*
* @author japod
* @author Fabian Ritzmann
* @author Rama.Pulavarthi@sun.com
*/
public interface PolicyFeatureConfigurator {
/**
* A callback method that allows to retrieve policy related information from provided PolicyMap
* and return a list of corresponding WebServiceFeatures.
*
* @param key Identifies the policy in the policy map
* @param policyMap Provides policies as a source of information on proper configuration
* @return A list of features that correspond to the policy identified by the policy map key. May be empty but not null.
* @throws PolicyException If an error occurred
*/
public Collection<WebServiceFeature> getFeatures(PolicyMapKey key, PolicyMap policyMap) throws PolicyException;
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.jaxws.spi;
import com.sun.xml.internal.ws.api.WSBinding;
import com.sun.xml.internal.ws.api.model.SEIModel;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicySubject;
import java.util.Collection;
/**
* The service provider implementing this interface will be discovered and called to extend created PolicyMap instance with additional policy
* bindings. The call is performed directly after WSIT config file is parsed.
*
* @since JAX-WS 2.2
* @author Marek Potociar (marek.potociar at sun.com)
* @author Fabian Ritzmann
* @author Rama.Pulavarthi@sun.com
*/
public interface PolicyMapConfigurator {
/**
* A callback method that allows to retrieve policy related information from provided parameters
* return a collection of new policies that are added to the map.
*
* When new policies are returned, the caller may merge them with existing policies
* in the policy map.
*
* @param policyMap This map contains the policies that were already created
* @param model The WSDL model of the service
* @param wsBinding The binding of the service
* @return A collection of policies and the subject to which they are attached.
* May return null or an empty collection.
* @throws PolicyException Throw this exception if an error occurs
*/
Collection<PolicySubject> update(PolicyMap policyMap, SEIModel model, WSBinding wsBinding) throws PolicyException;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The root package of public policy API. The package contains interfaces expected to be
* used in the most common policy processing use cases, such as scope policy retrieval.
* <p/>
* Any policy API classes that are commonly used by other parts of policy API (such as
* policy-specific exceptions, constants etc.) are expected to be found in this package.
*/
package com.sun.xml.internal.ws.policy;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.privateutil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Utility class to invoke sun.reflect.misc.MethodUtil.invoke() if available. If not (other then Oracle JDK) fallbacks
* to java.lang,reflect.Method.invoke()
*/
class MethodUtil {
private static final Logger LOGGER = Logger.getLogger(MethodUtil.class.getName());
private static final Method INVOKE_METHOD;
static {
Method method;
try {
Class<?> clazz = Class.forName("sun.reflect.misc.MethodUtil");
method = clazz.getMethod("invoke", Method.class, Object.class, Object[].class);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil found; it will be used to invoke methods.");
}
} catch (Throwable t) {
method = null;
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Class sun.reflect.misc.MethodUtil not found, probably non-Oracle JVM");
}
}
INVOKE_METHOD = method;
}
static Object invoke(Object target, Method method, Object[] args) throws IllegalAccessException, InvocationTargetException {
if (INVOKE_METHOD != null) {
// sun.reflect.misc.MethodUtil.invoke(method, owner, args)
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Invoking method using sun.reflect.misc.MethodUtil");
}
try {
return INVOKE_METHOD.invoke(null, method, target, args);
} catch (InvocationTargetException ite) {
// unwrap invocation exception added by reflection code ...
throw unwrapException(ite);
}
} else {
// other then Oracle JDK ...
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Invoking method directly, probably non-Oracle JVM");
}
return method.invoke(target, args);
}
}
private static InvocationTargetException unwrapException(InvocationTargetException ite) {
Throwable targetException = ite.getTargetException();
if (targetException != null && targetException instanceof InvocationTargetException) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Unwrapping invocation target exception");
}
return (InvocationTargetException) targetException;
} else {
return ite;
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.privateutil;
import com.sun.istack.internal.logging.Logger;
import java.lang.reflect.Field;
/**
* This is a helper class that provides some conveniece methods wrapped around the
* standard {@link java.util.logging.Logger} interface.
*
* @author Marek Potociar
* @author Fabian Ritzmann
*/
public final class PolicyLogger extends Logger {
/**
* If we run with JAX-WS, we are using its logging domain (appended with ".wspolicy").
* Otherwise we default to "wspolicy".
*/
private static final String POLICY_PACKAGE_ROOT = "com.sun.xml.internal.ws.policy";
/**
* Make sure this class cannot be instantiated by client code.
*
* @param policyLoggerName The name of the subsystem to be logged.
* @param className The fully qualified class name.
*/
private PolicyLogger(final String policyLoggerName, final String className) {
super(policyLoggerName, className);
}
/**
* The factory method returns preconfigured PolicyLogger wrapper for the class. Since there is no caching implemented,
* it is advised that the method is called only once per a class in order to initialize a final static logger variable,
* which is then used through the class to perform actual logging tasks.
*
* @param componentClass class of the component that will use the logger instance. Must not be {@code null}.
* @return logger instance preconfigured for use with the component
* @throws NullPointerException if the componentClass parameter is {@code null}.
*/
public static PolicyLogger getLogger(final Class<?> componentClass) {
final String componentClassName = componentClass.getName();
if (componentClassName.startsWith(POLICY_PACKAGE_ROOT)) {
return new PolicyLogger(getLoggingSubsystemName() + componentClassName.substring(POLICY_PACKAGE_ROOT.length()),
componentClassName);
} else {
return new PolicyLogger(getLoggingSubsystemName() + "." + componentClassName, componentClassName);
}
}
private static String getLoggingSubsystemName() {
String loggingSubsystemName = "wspolicy";
try {
// Looking up JAX-WS class at run-time, so that we don't need to depend
// on it at compile-time.
Class jaxwsConstants = Class.forName("com.sun.xml.internal.ws.util.Constants");
Field loggingDomainField = jaxwsConstants.getField("LoggingDomain");
Object loggingDomain = loggingDomainField.get(null);
loggingSubsystemName = loggingDomain.toString().concat(".wspolicy");
} catch (RuntimeException e) {
// if we catch an exception, we stick with the default name
// this catch is redundant but works around a Findbugs warning
} catch (Exception e) {
// if we catch an exception, we stick with the default name
}
return loggingSubsystemName;
}
}

View File

@@ -0,0 +1,480 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.privateutil;
import com.sun.xml.internal.ws.policy.PolicyException;
import java.io.Closeable;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
/**
* This is a wrapper class for various utilities that may be reused within Policy API implementation.
* The class is not part of public Policy API. Do not use it from your client code!
*
* @author Marek Potociar
*/
public final class PolicyUtils {
private PolicyUtils() { }
public static class Commons {
/**
* Method returns the name of the method that is on the {@code methodIndexInStack}
* position in the call stack of the current {@link Thread}.
*
* @param methodIndexInStack index to the call stack to get the method name for.
* @return the name of the method that is on the {@code methodIndexInStack}
* position in the call stack of the current {@link Thread}.
*/
public static String getStackMethodName(final int methodIndexInStack) {
final String methodName;
final StackTraceElement[] stack = Thread.currentThread().getStackTrace();
if (stack.length > methodIndexInStack + 1) {
methodName = stack[methodIndexInStack].getMethodName();
} else {
methodName = "UNKNOWN METHOD";
}
return methodName;
}
/**
* Function returns the name of the caller method for the method executing this
* function.
*
* @return caller method name from the call stack of the current {@link Thread}.
*/
public static String getCallerMethodName() {
String result = getStackMethodName(5);
if (result.equals("invoke0")) {
// We are likely running on Mac OS X, which returns a shorter stack trace
result = getStackMethodName(4);
}
return result;
}
}
public static class IO {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtils.IO.class);
/**
* If the {@code resource} is not {@code null}, this method will try to close the
* {@code resource} instance and log warning about any unexpected
* {@link IOException} that may occur.
*
* @param resource resource to be closed
*/
public static void closeResource(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
LOGGER.warning(LocalizationMessages.WSP_0023_UNEXPECTED_ERROR_WHILE_CLOSING_RESOURCE(resource.toString()), e);
}
}
}
/**
* If the {@code reader} is not {@code null}, this method will try to close the
* {@code reader} instance and log warning about any unexpected
* {@link IOException} that may occur.
*
* @param reader resource to be closed
*/
public static void closeResource(XMLStreamReader reader) {
if (reader != null) {
try {
reader.close();
} catch (XMLStreamException e) {
LOGGER.warning(LocalizationMessages.WSP_0023_UNEXPECTED_ERROR_WHILE_CLOSING_RESOURCE(reader.toString()), e);
}
}
}
}
/**
* Text utilities wrapper.
*/
public static class Text {
/**
* System-specific line separator character retrieved from the Java system property
* <code>line.separator</code>
*/
public final static String NEW_LINE = System.getProperty("line.separator");
/**
* Method creates indent string consisting of as many {@code TAB} characters as specified by {@code indentLevel} parameter
*
* @param indentLevel indentation level
* @return indentation string as specified by indentation level
*
*/
public static String createIndent(final int indentLevel) {
final char[] charData = new char[indentLevel * 4];
Arrays.fill(charData, ' ');
return String.valueOf(charData);
}
}
public static class Comparison {
/**
* The comparator comapres QName objects according to their publicly accessible attributes, in the following
* order of attributes:
*
* 1. namespace (not null String)
* 2. local name (not null String)
*/
public static final Comparator<QName> QNAME_COMPARATOR = new Comparator<QName>() {
public int compare(final QName qn1, final QName qn2) {
if (qn1 == qn2 || qn1.equals(qn2)) {
return 0;
}
int result;
result = qn1.getNamespaceURI().compareTo(qn2.getNamespaceURI());
if (result != 0) {
return result;
}
return qn1.getLocalPart().compareTo(qn2.getLocalPart());
}
};
/**
* Compares two boolean values in the following way: {@code false < true}
*
* @return {@code -1} if {@code b1 < b2}, {@code 0} if {@code b1 == b2}, {@code 1} if {@code b1 > b2}
*/
public static int compareBoolean(final boolean b1, final boolean b2) {
final int i1 = (b1) ? 1 : 0;
final int i2 = (b2) ? 1 : 0;
return i1 - i2;
}
/**
* Compares two String values, that may possibly be null in the following way: {@code null < "string value"}
*
* @return {@code -1} if {@code s1 < s2}, {@code 0} if {@code s1 == s2}, {@code 1} if {@code s1 > s2}
*/
public static int compareNullableStrings(final String s1, final String s2) {
return ((s1 == null) ? ((s2 == null) ? 0 : -1) : ((s2 == null) ? 1 : s1.compareTo(s2)));
}
}
public static class Collections {
/**
* TODO javadocs
*
* @param initialBase the combination base that will be present in each combination. May be {@code null} or empty.
* @param options options that should be combined. May be {@code null} or empty.
* @param ignoreEmptyOption flag identifies whether empty options should be ignored or whether the method should halt
* processing and return {@code null} when an empty option is encountered
* @return TODO
*/
public static <E, T extends Collection<? extends E>, U extends Collection<? extends E>> Collection<Collection<E>> combine(final U initialBase, final Collection<T> options, final boolean ignoreEmptyOption) {
List<Collection<E>> combinations = null;
if (options == null || options.isEmpty()) {
// no combination creation needed
if (initialBase != null) {
combinations = new ArrayList<Collection<E>>(1);
combinations.add(new ArrayList<E>(initialBase));
}
return combinations;
}
// creating defensive and modifiable copy of the base
final Collection<E> base = new LinkedList<E>();
if (initialBase != null && !initialBase.isEmpty()) {
base.addAll(initialBase);
}
/**
* now we iterate over all options and build up an option processing queue:
* 1. if ignoreEmptyOption flag is not set and we found an empty option, we are going to stop processing and return null. Otherwise we
* ignore the empty option.
* 2. if the option has one child only, we add the child directly to the base.
* 3. if there are more children in examined node, we add it to the queue for further processing and precoumpute the final size of
* resulting collection of combinations.
*/
int finalCombinationsSize = 1;
final Queue<T> optionProcessingQueue = new LinkedList<T>();
for (T option : options) {
final int optionSize = option.size();
if (optionSize == 0) {
if (!ignoreEmptyOption) {
return null;
}
} else if (optionSize == 1) {
base.addAll(option);
} else {
optionProcessingQueue.offer(option);
finalCombinationsSize *= optionSize;
}
}
// creating final combinations
combinations = new ArrayList<Collection<E>>(finalCombinationsSize);
combinations.add(base);
if (finalCombinationsSize > 1) {
T processedOption;
while ((processedOption = optionProcessingQueue.poll()) != null) {
final int actualSemiCombinationCollectionSize = combinations.size();
final int newSemiCombinationCollectionSize = actualSemiCombinationCollectionSize * processedOption.size();
int semiCombinationIndex = 0;
for (E optionElement : processedOption) {
for (int i = 0; i < actualSemiCombinationCollectionSize; i++) {
final Collection<E> semiCombination = combinations.get(semiCombinationIndex); // unfinished combination
if (semiCombinationIndex + actualSemiCombinationCollectionSize < newSemiCombinationCollectionSize) {
// this is not the last optionElement => we create a new combination copy for the next child
combinations.add(new LinkedList<E>(semiCombination));
}
semiCombination.add(optionElement);
semiCombinationIndex++;
}
}
}
}
return combinations;
}
}
/**
* Reflection utilities wrapper
*/
static class Reflection {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtils.Reflection.class);
/**
* Reflectively invokes specified method on the specified target
*/
static <T> T invoke(final Object target, final String methodName,
final Class<T> resultClass, final Object... parameters) throws RuntimePolicyUtilsException {
Class[] parameterTypes;
if (parameters != null && parameters.length > 0) {
parameterTypes = new Class[parameters.length];
int i = 0;
for (Object parameter : parameters) {
parameterTypes[i++] = parameter.getClass();
}
} else {
parameterTypes = null;
}
return invoke(target, methodName, resultClass, parameters, parameterTypes);
}
/**
* Reflectively invokes specified method on the specified target
*/
public static <T> T invoke(final Object target, final String methodName, final Class<T> resultClass,
final Object[] parameters, final Class[] parameterTypes) throws RuntimePolicyUtilsException {
try {
final Method method = target.getClass().getMethod(methodName, parameterTypes);
final Object result = MethodUtil.invoke(target, method,parameters);
return resultClass.cast(result);
} catch (IllegalArgumentException e) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(createExceptionMessage(target, parameters, methodName), e));
} catch (InvocationTargetException e) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(createExceptionMessage(target, parameters, methodName), e));
} catch (IllegalAccessException e) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(createExceptionMessage(target, parameters, methodName), e.getCause()));
} catch (SecurityException e) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(createExceptionMessage(target, parameters, methodName), e));
} catch (NoSuchMethodException e) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(createExceptionMessage(target, parameters, methodName), e));
}
}
private static String createExceptionMessage(final Object target, final Object[] parameters, final String methodName) {
return LocalizationMessages.WSP_0061_METHOD_INVOCATION_FAILED(target.getClass().getName(), methodName,
parameters == null ? null : Arrays.asList(parameters).toString());
}
}
public static class ConfigFile {
/**
* Generates a config file resource name from provided config file identifier.
* The generated file name can be transformed into a URL instance using
* {@link #loadFromContext(String, Object)} or {@link #loadFromClasspath(String)}
* method.
*
* @param configFileIdentifier the string used to generate the config file URL that will be parsed. Each WSIT config
* file is in form of <code>wsit-<i>{configFileIdentifier}</i>.xml</code>. Must not be {@code null}.
* @return generated config file resource name
* @throw PolicyException If configFileIdentifier is null.
*/
public static String generateFullName(final String configFileIdentifier) throws PolicyException {
if (configFileIdentifier != null) {
final StringBuffer buffer = new StringBuffer("wsit-");
buffer.append(configFileIdentifier).append(".xml");
return buffer.toString();
} else {
throw new PolicyException(LocalizationMessages.WSP_0080_IMPLEMENTATION_EXPECTED_NOT_NULL());
}
}
/**
* Returns a URL pointing to the given config file. The file name is
* looked up as a resource from a ServletContext.
*
* May return null if the file can not be found.
*
* @param configFileName The name of the file resource
* @param context A ServletContext object. May not be null.
*/
public static URL loadFromContext(final String configFileName, final Object context) {
return Reflection.invoke(context, "getResource", URL.class, configFileName);
}
/**
* Returns a URL pointing to the given config file. The file is looked up as
* a resource on the classpath.
*
* May return null if the file can not be found.
*
* @param configFileName the name of the file resource. May not be {@code null}.
*/
public static URL loadFromClasspath(final String configFileName) {
final ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
return ClassLoader.getSystemResource(configFileName);
} else {
return cl.getResource(configFileName);
}
}
}
/**
* Wrapper for ServiceFinder class which is not part of the Java SE yet.
*/
public static class ServiceProvider {
/**
* Locates and incrementally instantiates the available providers of a
* given service using the given class loader.
* <p/>
* <p> This method transforms the name of the given service class into a
* provider-configuration filename as described above and then uses the
* <tt>getResources</tt> method of the given class loader to find all
* available files with that name. These files are then read and parsed to
* produce a list of provider-class names. Eventually each provider class is
* instantiated and array of those instances is returned.
* <p/>
* <p> Because it is possible for extensions to be installed into a running
* Java virtual machine, this method may return different results each time
* it is invoked. <p>
*
* @param serviceClass The service's abstract service class. Must not be {@code null}.
* @param loader The class loader to be used to load provider-configuration files
* and instantiate provider classes, or <tt>null</tt> if the system
* class loader (or, failing that the bootstrap class loader) is to
* be used
* @throws NullPointerException in case {@code service} input parameter is {@code null}.
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
* @see #load(Class)
*/
public static <T> T[] load(final Class<T> serviceClass, final ClassLoader loader) {
return ServiceFinder.find(serviceClass, loader).toArray();
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the context class loader. This convenience method
* is equivalent to
* <p/>
* <pre>
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
* return PolicyUtils.ServiceProvider.load(service, cl);
* </pre>
*
* @param serviceClass The service's abstract service class. Must not be {@code null}.
*
* @throws NullPointerException in case {@code service} input parameter is {@code null}.
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
* @see #load(Class, ClassLoader)
*/
public static <T> T[] load(final Class<T> serviceClass) {
return ServiceFinder.find(serviceClass).toArray();
}
}
public static class Rfc2396 {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyUtils.Reflection.class);
// converts "hello%20world" into "hello world"
public static String unquote(final String quoted) {
if (null == quoted) {
return null;
}
final byte[] unquoted = new byte[quoted.length()]; // result cannot be longer than original string
int newLength = 0;
char c;
int hi, lo;
for (int i=0; i < quoted.length(); i++) { // iterarate over all chars in the input
c = quoted.charAt(i);
if ('%' == c) { // next escape sequence found
if ((i + 2) >= quoted.length()) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(LocalizationMessages.WSP_0079_ERROR_WHILE_RFC_2396_UNESCAPING(quoted)), false);
}
hi = Character.digit(quoted.charAt(++i), 16);
lo = Character.digit(quoted.charAt(++i), 16);
if ((0 > hi) || (0 > lo)) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(LocalizationMessages.WSP_0079_ERROR_WHILE_RFC_2396_UNESCAPING(quoted)), false);
}
unquoted[newLength++] = (byte) (hi * 16 + lo);
} else { // regular character found
unquoted[newLength++] = (byte) c;
}
}
try {
return new String(unquoted, 0, newLength, "utf-8");
} catch (UnsupportedEncodingException uee) {
throw LOGGER.logSevereException(new RuntimePolicyUtilsException(LocalizationMessages.WSP_0079_ERROR_WHILE_RFC_2396_UNESCAPING(quoted), uee));
}
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.privateutil;
/**
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public final class RuntimePolicyUtilsException extends RuntimeException {
RuntimePolicyUtilsException(final String message) {
super(message);
}
RuntimePolicyUtilsException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.privateutil;
/**
* Error thrown when something goes wrong while looking up service providers.
* In particular, this error will be thrown in the following situations:
*
* <ul>
* <li> A concrete provider class cannot be found,
* <li> A concrete provider class cannot be instantiated,
* <li> The format of a provider-configuration file is illegal, or
* <li> An IOException occurs while reading a provider-configuration file.
* </ul>
*
* @author Mark Reinhold
* @version 1.7, 03/12/19
* @since 1.3
*/
public class ServiceConfigurationError extends Error {
/**
* Constructs a new instance with the specified detail string.
*/
public ServiceConfigurationError(String message) {
super(message);
}
/**
* Constructs a new instance that wraps the specified throwable.
*/
public ServiceConfigurationError(Throwable throwable) {
super(throwable);
}
}

View File

@@ -0,0 +1,380 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.privateutil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
/**
*
* A simple service-provider lookup mechanism. A <i>service</i> is a
* well-known set of interfaces and (usually abstract) classes. A <i>service
* provider</i> is a specific implementation of a service. The classes in a
* provider typically implement the interfaces and subclass the classes defined
* in the service itself. Service providers may be installed in an
* implementation of the Java platform in the form of extensions, that is, jar
* files placed into any of the usual extension directories. Providers may
* also be made available by adding them to the applet or application class
* path or by some other platform-specific means.
* <p/>
* <p> In this lookup mechanism a service is represented by an interface or an
* abstract class. (A concrete class may be used, but this is not
* recommended.) A provider of a given service contains one or more concrete
* classes that extend this <i>service class</i> with data and code specific to
* the provider. This <i>provider class</i> will typically not be the entire
* provider itself but rather a proxy that contains enough information to
* decide whether the provider is able to satisfy a particular request together
* with code that can create the actual provider on demand. The details of
* provider classes tend to be highly service-specific; no single class or
* interface could possibly unify them, so no such class has been defined. The
* only requirement enforced here is that provider classes must have a
* zero-argument constructor so that they may be instantiated during lookup.
* <p/>
* <p> A service provider identifies itself by placing a provider-configuration
* file in the resource directory <tt>META-INF/services</tt>. The file's name
* should consist of the fully-qualified name of the abstract service class.
* The file should contain a list of fully-qualified concrete provider-class
* names, one per line. Space and tab characters surrounding each name, as
* well as blank lines, are ignored. The comment character is <tt>'#'</tt>
* (<tt>0x23</tt>); on each line all characters following the first comment
* character are ignored. The file must be encoded in UTF-8.
* <p/>
* <p> If a particular concrete provider class is named in more than one
* configuration file, or is named in the same configuration file more than
* once, then the duplicates will be ignored. The configuration file naming a
* particular provider need not be in the same jar file or other distribution
* unit as the provider itself. The provider must be accessible from the same
* class loader that was initially queried to locate the configuration file;
* note that this is not necessarily the class loader that found the file.
* <p/>
* <p> <b>Example:</b> Suppose we have a service class named
* <tt>java.io.spi.CharCodec</tt>. It has two abstract methods:
* <p/>
* <pre>
* public abstract CharEncoder getEncoder(String encodingName);
* public abstract CharDecoder getDecoder(String encodingName);
* </pre>
* <p/>
* Each method returns an appropriate object or <tt>null</tt> if it cannot
* translate the given encoding. Typical <tt>CharCodec</tt> providers will
* support more than one encoding.
* <p/>
* <p> If <tt>sun.io.StandardCodec</tt> is a provider of the <tt>CharCodec</tt>
* service then its jar file would contain the file
* <tt>META-INF/services/java.io.spi.CharCodec</tt>. This file would contain
* the single line:
* <p/>
* <pre>
* sun.io.StandardCodec # Standard codecs for the platform
* </pre>
* <p/>
* To locate an encoder for a given encoding name, the internal I/O code would
* do something like this:
* <p/>
* <pre>
* CharEncoder getEncoder(String encodingName) {
* for( CharCodec cc : ServiceFinder.find(CharCodec.class) ) {
* CharEncoder ce = cc.getEncoder(encodingName);
* if (ce != null)
* return ce;
* }
* return null;
* }
* </pre>
* <p/>
* The provider-lookup mechanism always executes in the security context of the
* caller. Trusted system code should typically invoke the methods in this
* class from within a privileged security context.
*
* @author Mark Reinhold
* @version 1.11, 03/12/19
* @since 1.3
*/
final class ServiceFinder<T> implements Iterable<T> {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(ServiceFinder.class);
private static final String prefix = "META-INF/services/";
private final Class<T> serviceClass;
private final ClassLoader classLoader;
/**
* Locates and incrementally instantiates the available providers of a
* given service using the given class loader.
* <p/>
* <p> This method transforms the name of the given service class into a
* provider-configuration filename as described above and then uses the
* <tt>getResources</tt> method of the given class loader to find all
* available files with that name. These files are then read and parsed to
* produce a list of provider-class names. The iterator that is returned
* uses the given class loader to lookup and then instantiate each element
* of the list.
* <p/>
* <p> Because it is possible for extensions to be installed into a running
* Java virtual machine, this method may return different results each time
* it is invoked. <p>
*
* @param service The service's abstract service class
* @param loader The class loader to be used to load provider-configuration files
* and instantiate provider classes, or <tt>null</tt> if the system
* class loader (or, failing that the bootstrap class loader) is to
* be used
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
* @see #find(Class)
*/
static <T> ServiceFinder<T> find(final Class<T> service, final ClassLoader loader) {
if (null==service) {
throw LOGGER.logSevereException(new NullPointerException(LocalizationMessages.WSP_0032_SERVICE_CAN_NOT_BE_NULL()));
}
return new ServiceFinder<T>(service,loader);
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the context class loader. This convenience method
* is equivalent to
* <p/>
* <pre>
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
* return Service.providers(service, cl);
* </pre>
*
* @param service The service's abstract service class
*
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
* @see #find(Class, ClassLoader)
*/
public static <T> ServiceFinder<T> find(final Class<T> service) {
return find(service,Thread.currentThread().getContextClassLoader());
}
private ServiceFinder(Class<T> service, ClassLoader loader) {
this.serviceClass = service;
this.classLoader = loader;
}
/**
* Returns discovered objects incrementally.
*
* @return An <tt>Iterator</tt> that yields provider objects for the given
* service, in some arbitrary order. The iterator will throw a
* <tt>ServiceConfigurationError</tt> if a provider-configuration
* file violates the specified format or if a provider class cannot
* be found and instantiated.
*/
public Iterator<T> iterator() {
return new LazyIterator<T>(serviceClass,classLoader);
}
/**
* Returns discovered objects all at once.
*
* @return
* can be empty but never null.
*
* @throws ServiceConfigurationError
*/
@SuppressWarnings({"unchecked"})
public T[] toArray() {
List<T> result = new ArrayList<T>();
for (T t : this) {
result.add(t);
}
return result.toArray((T[])Array.newInstance(serviceClass,result.size()));
}
private static void fail(final Class service, final String msg, final Throwable cause)
throws ServiceConfigurationError {
final ServiceConfigurationError sce
= new ServiceConfigurationError(LocalizationMessages.WSP_0025_SPI_FAIL_SERVICE_MSG(service.getName(), msg));
if (null != cause) {
sce.initCause(cause);
}
throw LOGGER.logSevereException(sce);
}
/* private static void fail(Class service, String msg)
throws ServiceConfigurationError {
throw new ServiceConfigurationError(LocalizationMessages.WSP_0025_SPI_FAIL_SERVICE_MSG(service.getName(), msg));
}*/
private static void fail(final Class service, final URL u, final int line, final String msg, final Throwable cause)
throws ServiceConfigurationError {
fail(service, LocalizationMessages.WSP_0024_SPI_FAIL_SERVICE_URL_LINE_MSG(u , line, msg), cause);
}
/**
* Parse a single line from the given configuration file, adding the name
* on the line to both the names list and the returned set iff the name is
* not already a member of the returned set.
*/
private static int parseLine(final Class service, final URL u, final BufferedReader r, final int lc,
final List<String> names, final Set<String> returned)
throws IOException, ServiceConfigurationError {
String ln = r.readLine();
if (ln == null) {
return -1;
}
final int ci = ln.indexOf('#');
if (ci >= 0) ln = ln.substring(0, ci);
ln = ln.trim();
final int n = ln.length();
if (n != 0) {
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
fail(service, u, lc, LocalizationMessages.WSP_0067_ILLEGAL_CFG_FILE_SYNTAX(), null);
int cp = ln.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
fail(service, u, lc, LocalizationMessages.WSP_0066_ILLEGAL_PROVIDER_CLASSNAME(ln), null);
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
cp = ln.codePointAt(i);
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
fail(service, u, lc, LocalizationMessages.WSP_0066_ILLEGAL_PROVIDER_CLASSNAME(ln), null);
}
if (!returned.contains(ln)) {
names.add(ln);
returned.add(ln);
}
}
return lc + 1;
}
/**
* Parse the content of the given URL as a provider-configuration file.
*
* @param service The service class for which providers are being sought;
* used to construct error detail strings
* @param u The URL naming the configuration file to be parsed
* @param returned A Set containing the names of provider classes that have already
* been returned. This set will be updated to contain the names
* that will be yielded from the returned <tt>Iterator</tt>.
* @return A (possibly empty) <tt>Iterator</tt> that will yield the
* provider-class names in the given configuration file that are
* not yet members of the returned set
* @throws ServiceConfigurationError If an I/O error occurs while reading from the given URL, or
* if a configuration-file format error is detected
*/
@SuppressWarnings({"StatementWithEmptyBody"})
private static Iterator<String> parse(Class service, URL u, Set<String> returned)
throws ServiceConfigurationError {
InputStream in = null;
BufferedReader r = null;
ArrayList<String> names = new ArrayList<String>();
try {
in = u.openStream();
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
int lc = 1;
while ((lc = parseLine(service, u, r, lc, names, returned)) >= 0) ;
} catch (IOException x) {
fail(service, ": " + x, x);
} finally {
try {
if (r != null) r.close();
if (in != null) in.close();
} catch (IOException y) {
fail(service, ": " + y, y);
}
}
return names.iterator();
}
/**
* Private inner class implementing fully-lazy provider lookup
*/
private static class LazyIterator<T> implements Iterator<T> {
Class<T> service;
ClassLoader loader;
Enumeration<URL> configs = null;
Iterator<String> pending = null;
Set<String> returned = new TreeSet<String>();
String nextName = null;
private LazyIterator(Class<T> service, ClassLoader loader) {
this.service = service;
this.loader = loader;
}
public boolean hasNext() throws ServiceConfigurationError {
if (nextName != null) {
return true;
}
if (configs == null) {
try {
final String fullName = prefix + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
configs = loader.getResources(fullName);
} catch (IOException x) {
fail(service, ": " + x, x);
}
}
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return false;
}
pending = parse(service, configs.nextElement(), returned);
}
nextName = pending.next();
return true;
}
public T next() throws ServiceConfigurationError {
if (!hasNext()) {
throw new NoSuchElementException();
}
final String cn = nextName;
nextName = null;
try {
return service.cast(Class.forName(cn, true, loader).newInstance());
} catch (ClassNotFoundException x) {
fail(service, LocalizationMessages.WSP_0027_SERVICE_PROVIDER_NOT_FOUND(cn), x);
} catch (Exception x) {
fail(service, LocalizationMessages.WSP_0028_SERVICE_PROVIDER_COULD_NOT_BE_INSTANTIATED(cn), x);
}
return null; /* This cannot happen */
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This package contains utility classes that are not part of the public Policy API. None of the classes contained in this
* package should be used outside the Policy API implementation. The creators of the Policy API will not provide any support
* concerning usage of the classes in this package. I should be also clear that any method signatures, classes and interfaces
* may be changed or even removed without a prior notice.
* <p/>
* To put it simple: <b>Do not use classes in this package, unless you are member of the WS policy implementation team!!!</b>
*/
package com.sun.xml.internal.ws.policy.privateutil;

View File

@@ -0,0 +1,429 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.PolicyConstants;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
/**
* Wrapper class for possible data that each "assertion" and "assertion parameter content" policy source model node may
* have attached.
* <p/>
* This data, when stored in an 'assertion' model node, is intended to be used as input parameter when creating
* {@link com.sun.xml.internal.ws.policy.PolicyAssertion} objects via {@link com.sun.xml.internal.ws.policy.spi.PolicyAssertionCreator}
* implementations.
*
* @author Marek Potociar (marek.potociar@sun.com)
* @author Fabian Ritzmann
*/
public final class AssertionData implements Cloneable, Serializable {
private static final long serialVersionUID = 4416256070795526315L;
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(AssertionData.class);
private final QName name;
private final String value;
private final Map<QName, String> attributes;
private ModelNode.Type type;
private boolean optional;
private boolean ignorable;
/**
* Constructs assertion data wrapper instance for an assertion that does not
* contain any value nor any attributes.
*
* @param name the FQN of the assertion
*
* @throws IllegalArgumentException in case the {@code type} parameter is not
* {@link ModelNode.Type#ASSERTION ASSERTION} or
* {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE}
*/
public static AssertionData createAssertionData(final QName name) throws IllegalArgumentException {
return new AssertionData(name, null, null, ModelNode.Type.ASSERTION, false, false);
}
/**
* Constructs assertion data wrapper instance for an assertion parameter that
* does not contain any value nor any attributes.
*
* @param name the FQN of the assertion parameter
*
* @throws IllegalArgumentException in case the {@code type} parameter is not
* {@link ModelNode.Type#ASSERTION ASSERTION} or
* {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE}
*/
public static AssertionData createAssertionParameterData(final QName name) throws IllegalArgumentException {
return new AssertionData(name, null, null, ModelNode.Type.ASSERTION_PARAMETER_NODE, false, false);
}
/**
* Constructs assertion data wrapper instance for an assertion that does
* contain a value or attributes.
*
* @param name the FQN of the assertion
* @param value a {@link String} representation of model node value
* @param attributes map of model node's &lt;attribute name, attribute value&gt; pairs
* @param optional flag indicating whether the assertion is optional or not
* @param ignorable flag indicating whether the assertion is ignorable or not
*
* @throws IllegalArgumentException in case the {@code type} parameter is not
* {@link ModelNode.Type#ASSERTION ASSERTION} or
* {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE}
*/
public static AssertionData createAssertionData(final QName name, final String value, final Map<QName, String> attributes, boolean optional, boolean ignorable) throws IllegalArgumentException {
return new AssertionData(name, value, attributes, ModelNode.Type.ASSERTION, optional, ignorable);
}
/**
* Constructs assertion data wrapper instance for an assertion parameter that
* contains a value or attributes
*
* @param name the FQN of the assertion parameter
* @param value a {@link String} representation of model node value
* @param attributes map of model node's &lt;attribute name, attribute value&gt; pairs
*
* @throws IllegalArgumentException in case the {@code type} parameter is not
* {@link ModelNode.Type#ASSERTION ASSERTION} or
* {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE}
*/
public static AssertionData createAssertionParameterData(final QName name, final String value, final Map<QName, String> attributes) throws IllegalArgumentException {
return new AssertionData(name, value, attributes, ModelNode.Type.ASSERTION_PARAMETER_NODE, false, false);
}
/**
* Constructs assertion data wrapper instance for an assertion or assertion parameter that contains a value or
* some attributes. Whether the data wrapper is constructed for assertion or assertion parameter node is distinguished by
* the supplied {@code type} parameter.
*
* @param name the FQN of the assertion or assertion parameter
* @param value a {@link String} representation of model node value
* @param attributes map of model node's &lt;attribute name, attribute value&gt; pairs
* @param type specifies whether the data will belong to the assertion or assertion parameter node. This is
* a workaround solution that allows us to transfer this information about the owner node to
* a policy assertion instance factory without actualy having to touch the {@link PolicyAssertionCreator}
* interface and protected {@link PolicyAssertion} constructors.
*
* @throws IllegalArgumentException in case the {@code type} parameter is not
* {@link ModelNode.Type#ASSERTION ASSERTION} or
* {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE}
*/
AssertionData(QName name, String value, Map<QName, String> attributes, ModelNode.Type type, boolean optional, boolean ignorable) throws IllegalArgumentException {
this.name = name;
this.value = value;
this.optional = optional;
this.ignorable = ignorable;
this.attributes = new HashMap<QName, String>();
if (attributes != null && !attributes.isEmpty()) {
this.attributes.putAll(attributes);
}
setModelNodeType(type);
}
private void setModelNodeType(final ModelNode.Type type) throws IllegalArgumentException {
if (type == ModelNode.Type.ASSERTION || type == ModelNode.Type.ASSERTION_PARAMETER_NODE) {
this.type = type;
} else {
throw LOGGER.logSevereException(new IllegalArgumentException(
LocalizationMessages.WSP_0074_CANNOT_CREATE_ASSERTION_BAD_TYPE(type, ModelNode.Type.ASSERTION, ModelNode.Type.ASSERTION_PARAMETER_NODE)));
}
}
/**
* Copy constructor.
*
* @param data The instance that is to be copied.
*/
AssertionData(final AssertionData data) {
this.name = data.name;
this.value = data.value;
this.attributes = new HashMap<QName, String>();
if (!data.attributes.isEmpty()) {
this.attributes.putAll(data.attributes);
}
this.type = data.type;
}
@Override
protected AssertionData clone() throws CloneNotSupportedException {
return (AssertionData) super.clone();
}
/**
* Returns true if the given attribute exists, false otherwise.
*
* @param name The name of the attribute. Must not be null.
* @return True if the given attribute exists, false otherwise.
*/
public boolean containsAttribute(final QName name) {
synchronized (attributes) {
return attributes.containsKey(name);
}
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof AssertionData)) {
return false;
}
boolean result = true;
final AssertionData that = (AssertionData) obj;
result = result && this.name.equals(that.name);
result = result && ((this.value == null) ? that.value == null : this.value.equals(that.value));
synchronized (attributes) {
result = result && this.attributes.equals(that.attributes);
}
return result;
}
/**
* Returns the value of the given attribute. Returns null if the attribute
* does not exist.
*
* @param name The name of the attribute. Must not be null.
* @return The value of the given attribute. Returns null if the attribute
* does not exist.
*/
public String getAttributeValue(final QName name) {
synchronized (attributes) {
return attributes.get(name);
}
}
/**
* Returns the disconnected map of attributes attached to the assertion.
* <p/>
* 'Disconnected' means, that the result of this method will not be synchronized with any consequent assertion's attribute modification. It is
* also important to notice that a manipulation with returned set of attributes will not have any effect on the actual assertion's
* attributes.
*
* @return disconnected map of attributes attached to the assertion.
*/
public Map<QName, String> getAttributes() {
synchronized (attributes) {
return new HashMap<QName, String>(attributes);
}
}
/**
* Returns the disconnected set of attributes attached to the assertion. Each attribute is represented as a single
* {@code Map.Entry<attributeName, attributeValue>} element.
* <p/>
* 'Disconnected' means, that the result of this method will not be synchronized with any consequent assertion's attribute modification. It is
* also important to notice that a manipulation with returned set of attributes will not have any effect on the actual assertion's
* attributes.
*
* @return disconnected set of attributes attached to the assertion.
*/
public Set<Map.Entry<QName, String>> getAttributesSet() {
synchronized (attributes) {
return new HashSet<Map.Entry<QName, String>>(attributes.entrySet());
}
}
/**
* Returns the name of the assertion.
*
* @return assertion's name
*/
public QName getName() {
return name;
}
/**
* Returns the value of the assertion.
*
* @return assertion's value
*/
public String getValue() {
return value;
}
/**
* An {@code Object.hashCode()} method override.
*/
@Override
public int hashCode() {
int result = 17;
result = 37 * result + this.name.hashCode();
result = 37 * result + ((this.value == null) ? 0 : this.value.hashCode());
synchronized (attributes) {
result = 37 * result + this.attributes.hashCode();
}
return result;
}
/**
* Method specifies whether the assertion data contain proprietary visibility element set to "private" value.
*
* @return {@code 'true'} if the attribute is present and set properly (i.e. the node containing this assertion data instance should
* not be marshaled into generated WSDL documents). Returns {@code false} otherwise.
*/
public boolean isPrivateAttributeSet() {
return PolicyConstants.VISIBILITY_VALUE_PRIVATE.equals(getAttributeValue(PolicyConstants.VISIBILITY_ATTRIBUTE));
}
/**
* Removes the given attribute from the assertion data.
*
* @param name The name of the attribute. Must not be null
* @return The value of the removed attribute.
*/
public String removeAttribute(final QName name) {
synchronized (attributes) {
return attributes.remove(name);
}
}
/**
* Adds or overwrites an attribute.
*
* @param name The name of the attribute.
* @param value The value of the attribute.
*/
public void setAttribute(final QName name, final String value) {
synchronized (attributes) {
attributes.put(name, value);
}
}
/**
* Sets the optional attribute.
*
* @param value The value of the optional attribute.
*/
public void setOptionalAttribute(final boolean value) {
optional = value;
}
/**
* Tests if the optional attribute is set.
*
* @return True if optional is set and is true. False otherwise.
*/
public boolean isOptionalAttributeSet() {
return optional;
}
/**
* Sets the ignorable attribute.
*
* @param value The value of the ignorable attribute.
*/
public void setIgnorableAttribute(final boolean value) {
ignorable = value;
}
/**
* Tests if the ignorable attribute is set.
*
* @return True if ignorable is set and is true. False otherwise.
*/
public boolean isIgnorableAttributeSet() {
return ignorable;
}
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
public StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
final String innerDoubleIndent = PolicyUtils.Text.createIndent(indentLevel + 2);
buffer.append(indent);
if (type == ModelNode.Type.ASSERTION) {
buffer.append("assertion data {");
} else {
buffer.append("assertion parameter data {");
}
buffer.append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("namespace = '").append(name.getNamespaceURI()).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("prefix = '").append(name.getPrefix()).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("local name = '").append(name.getLocalPart()).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("value = '").append(value).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("optional = '").append(optional).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("ignorable = '").append(ignorable).append('\'').append(PolicyUtils.Text.NEW_LINE);
synchronized (attributes) {
if (attributes.isEmpty()) {
buffer.append(innerIndent).append("no attributes");
} else {
buffer.append(innerIndent).append("attributes {").append(PolicyUtils.Text.NEW_LINE);
for(Map.Entry<QName, String> entry : attributes.entrySet()) {
final QName aName = entry.getKey();
buffer.append(innerDoubleIndent).append("name = '").append(aName.getNamespaceURI()).append(':').append(aName.getLocalPart());
buffer.append("', value = '").append(entry.getValue()).append('\'').append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(innerIndent).append('}');
}
}
buffer.append(PolicyUtils.Text.NEW_LINE).append(indent).append('}');
return buffer;
}
public ModelNode.Type getNodeType() {
return type;
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.AssertionSet;
import com.sun.xml.internal.ws.policy.NestedPolicy;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
/**
* Create a compact WS-Policy infoset. ExactlyOne and All elements are omitted
* where possible.
*
* @author Fabian Ritzmann
*/
class CompactModelGenerator extends PolicyModelGenerator {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(CompactModelGenerator.class);
private final PolicySourceModelCreator sourceModelCreator;
CompactModelGenerator(PolicySourceModelCreator sourceModelCreator) {
this.sourceModelCreator = sourceModelCreator;
}
@Override
public PolicySourceModel translate(final Policy policy) throws PolicyException {
LOGGER.entering(policy);
PolicySourceModel model = null;
if (policy == null) {
LOGGER.fine(LocalizationMessages.WSP_0047_POLICY_IS_NULL_RETURNING());
} else {
model = this.sourceModelCreator.create(policy);
ModelNode rootNode = model.getRootNode();
final int numberOfAssertionSets = policy.getNumberOfAssertionSets();
if (numberOfAssertionSets > 1) {
rootNode = rootNode.createChildExactlyOneNode();
}
ModelNode alternativeNode = rootNode;
for (AssertionSet set : policy) {
if (numberOfAssertionSets > 1) {
alternativeNode = rootNode.createChildAllNode();
}
for (PolicyAssertion assertion : set) {
final AssertionData data = AssertionData.createAssertionData(assertion.getName(), assertion.getValue(), assertion.getAttributes(), assertion.isOptional(), assertion.isIgnorable());
final ModelNode assertionNode = alternativeNode.createChildAssertionNode(data);
if (assertion.hasNestedPolicy()) {
translate(assertionNode, assertion.getNestedPolicy());
}
if (assertion.hasParameters()) {
translate(assertionNode, assertion.getParametersIterator());
}
}
}
}
LOGGER.exiting(model);
return model;
}
@Override
protected ModelNode translate(final ModelNode parentAssertion, final NestedPolicy policy) {
final ModelNode nestedPolicyRoot = parentAssertion.createChildPolicyNode();
final AssertionSet set = policy.getAssertionSet();
translate(nestedPolicyRoot, set);
return nestedPolicyRoot;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.*;
import com.sun.xml.internal.ws.policy.spi.AssertionCreationException;
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionCreator;
import java.util.Collection;
/**
* Default implementation of a policy assertion creator. This implementation is used to create policy assertions in case
* no domain specific policy assertion creator is registered for the namespace of the policy assertion.
*
* This is the only PolicyAssertionCreator implementation that is allowed to break general contract, claiming that
* {@code getSupportedDomainNamespaceUri()} must not return empty String without causing PolicyAssertionCreator registration
* fail.
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
class DefaultPolicyAssertionCreator implements PolicyAssertionCreator {
private static final class DefaultPolicyAssertion extends PolicyAssertion {
DefaultPolicyAssertion(AssertionData data, Collection<PolicyAssertion> assertionParameters, AssertionSet nestedAlternative) {
super (data, assertionParameters, nestedAlternative);
}
}
/**
* Creates a new instance of DefaultPolicyAssertionCreator
*/
DefaultPolicyAssertionCreator() {
// nothing to initialize
}
/**
* See {@link PolicyAssertionCreator#getSupportedDomainNamespaceURIs() method documentation in interface}
*/
public String[] getSupportedDomainNamespaceURIs() {
return null;
}
/**
* See {@link PolicyAssertionCreator#createAssertion(AssertionData, Collection, AssertionSet, PolicyAssertionCreator) method documentation in interface}
*/
public PolicyAssertion createAssertion(final AssertionData data, final Collection<PolicyAssertion> assertionParameters, final AssertionSet nestedAlternative, final PolicyAssertionCreator defaultCreator) throws AssertionCreationException {
return new DefaultPolicyAssertion(data, assertionParameters, nestedAlternative);
}
}

View File

@@ -0,0 +1,596 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
/**
* The general representation of a single node within a {@link com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel} instance.
* The model node is created via factory methods of the {@link com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel} instance.
* It may also hold {@link com.sun.xml.internal.ws.policy.sourcemodel.AssertionData} instance in case its type is {@code ModelNode.Type.ASSERTION}.
*
* @author Marek Potociar
*/
public final class ModelNode implements Iterable<ModelNode>, Cloneable {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(ModelNode.class);
/**
* Policy source model node type enumeration
*/
public static enum Type {
POLICY(XmlToken.Policy),
ALL(XmlToken.All),
EXACTLY_ONE(XmlToken.ExactlyOne),
POLICY_REFERENCE(XmlToken.PolicyReference),
ASSERTION(XmlToken.UNKNOWN),
ASSERTION_PARAMETER_NODE(XmlToken.UNKNOWN);
private XmlToken token;
Type(XmlToken token) {
this.token = token;
}
public XmlToken getXmlToken() {
return token;
}
/**
* Method checks the PSM state machine if the creation of new child of given type is plausible for a node element
* with type set to this type instance.
*
* @param childType The type.
* @return True if the type is supported, false otherwise
*/
private boolean isChildTypeSupported(final Type childType) {
switch (this) {
case POLICY:
case ALL:
case EXACTLY_ONE:
switch (childType) {
case ASSERTION_PARAMETER_NODE:
return false;
default:
return true;
}
case POLICY_REFERENCE:
return false;
case ASSERTION:
switch (childType) {
case POLICY:
case POLICY_REFERENCE:
case ASSERTION_PARAMETER_NODE:
return true;
default:
return false;
}
case ASSERTION_PARAMETER_NODE:
switch (childType) {
case ASSERTION_PARAMETER_NODE:
return true;
default:
return false;
}
default:
throw LOGGER.logSevereException(new IllegalStateException(
LocalizationMessages.WSP_0060_POLICY_ELEMENT_TYPE_UNKNOWN(this)));
}
}
}
// comon model node attributes
private LinkedList<ModelNode> children;
private Collection<ModelNode> unmodifiableViewOnContent;
private final ModelNode.Type type;
private ModelNode parentNode;
private PolicySourceModel parentModel;
// attributes used only in 'POLICY_REFERENCE' model node
private PolicyReferenceData referenceData;
private PolicySourceModel referencedModel;
// attibutes used only in 'ASSERTION' or 'ASSERTION_PARAMETER_NODE' model node
private AssertionData nodeData;
/**
* The factory method creates and initializes the POLICY model node and sets it's parent model reference to point to
* the model supplied as an input parameter. This method is intended to be used ONLY from {@link PolicySourceModel} during
* the initialization of its own internal structures.
*
* @param model policy source model to be used as a parent model of the newly created {@link ModelNode}. Must not be {@code null}
* @return POLICY model node with the parent model reference initialized to the model supplied as an input parameter
* @throws IllegalArgumentException if the {@code model} input parameter is {@code null}
*/
static ModelNode createRootPolicyNode(final PolicySourceModel model) throws IllegalArgumentException {
if (model == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0039_POLICY_SRC_MODEL_INPUT_PARAMETER_MUST_NOT_BE_NULL()));
}
return new ModelNode(ModelNode.Type.POLICY, model);
}
private ModelNode(Type type, PolicySourceModel parentModel) {
this.type = type;
this.parentModel = parentModel;
this.children = new LinkedList<ModelNode>();
this.unmodifiableViewOnContent = Collections.unmodifiableCollection(this.children);
}
private ModelNode(Type type, PolicySourceModel parentModel, AssertionData data) {
this(type, parentModel);
this.nodeData = data;
}
private ModelNode(PolicySourceModel parentModel, PolicyReferenceData data) {
this(Type.POLICY_REFERENCE, parentModel);
this.referenceData = data;
}
private void checkCreateChildOperationSupportForType(final Type type) throws UnsupportedOperationException {
if (!this.type.isChildTypeSupported(type)) {
throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0073_CREATE_CHILD_NODE_OPERATION_NOT_SUPPORTED(type, this.type)));
}
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @return A new Policy node.
*/
public ModelNode createChildPolicyNode() {
checkCreateChildOperationSupportForType(Type.POLICY);
final ModelNode node = new ModelNode(ModelNode.Type.POLICY, parentModel);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @return A new All node.
*/
public ModelNode createChildAllNode() {
checkCreateChildOperationSupportForType(Type.ALL);
final ModelNode node = new ModelNode(ModelNode.Type.ALL, parentModel);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @return A new ExactlyOne node.
*/
public ModelNode createChildExactlyOneNode() {
checkCreateChildOperationSupportForType(Type.EXACTLY_ONE);
final ModelNode node = new ModelNode(ModelNode.Type.EXACTLY_ONE, parentModel);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @return A new policy assertion node.
*/
public ModelNode createChildAssertionNode() {
checkCreateChildOperationSupportForType(Type.ASSERTION);
final ModelNode node = new ModelNode(ModelNode.Type.ASSERTION, parentModel);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @param nodeData The policy assertion data.
* @return A new policy assertion node.
*/
public ModelNode createChildAssertionNode(final AssertionData nodeData) {
checkCreateChildOperationSupportForType(Type.ASSERTION);
final ModelNode node = new ModelNode(Type.ASSERTION, parentModel, nodeData);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @return A new assertion parameter node.
*/
public ModelNode createChildAssertionParameterNode() {
checkCreateChildOperationSupportForType(Type.ASSERTION_PARAMETER_NODE);
final ModelNode node = new ModelNode(ModelNode.Type.ASSERTION_PARAMETER_NODE, parentModel);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @param nodeData The assertion parameter data.
* @return A new assertion parameter node.
*/
ModelNode createChildAssertionParameterNode(final AssertionData nodeData) {
checkCreateChildOperationSupportForType(Type.ASSERTION_PARAMETER_NODE);
final ModelNode node = new ModelNode(Type.ASSERTION_PARAMETER_NODE, parentModel, nodeData);
this.addChild(node);
return node;
}
/**
* Factory method that creates new policy source model node as specified by a factory method name and input parameters.
* Each node is created with respect to its enclosing policy source model.
*
* @param referenceData The PolicyReference data.
* @return A new PolicyReference node.
*/
ModelNode createChildPolicyReferenceNode(final PolicyReferenceData referenceData) {
checkCreateChildOperationSupportForType(Type.POLICY_REFERENCE);
final ModelNode node = new ModelNode(parentModel, referenceData);
this.parentModel.addNewPolicyReference(node);
this.addChild(node);
return node;
}
Collection<ModelNode> getChildren() {
return unmodifiableViewOnContent;
}
/**
* Sets the parent model reference on the node and its children. The method may be invoked only on the root node
* of the policy source model (or - in general - on a model node that dose not reference a parent node). Otherwise an
* exception is thrown.
*
* @param model new parent policy source model to be set.
* @throws IllegalAccessException in case this node references a parent node (i.e. is not a root node of the model).
*/
void setParentModel(final PolicySourceModel model) throws IllegalAccessException {
if (parentNode != null) {
throw LOGGER.logSevereException(new IllegalAccessException(LocalizationMessages.WSP_0049_PARENT_MODEL_CAN_NOT_BE_CHANGED()));
}
this.updateParentModelReference(model);
}
/**
* The method updates the parentModel reference on current model node instance and all of it's children
*
* @param model new policy source model reference.
*/
private void updateParentModelReference(final PolicySourceModel model) {
this.parentModel = model;
for (ModelNode child : children) {
child.updateParentModelReference(model);
}
}
/**
* Returns the parent policy source model that contains this model node.
*
* @return the parent policy source model
*/
public PolicySourceModel getParentModel() {
return parentModel;
}
/**
* Returns the type of this policy source model node.
*
* @return actual type of this policy source model node
*/
public ModelNode.Type getType() {
return type;
}
/**
* Returns the parent referenced by this policy source model node.
*
* @return current parent of this policy source model node or {@code null} if the node does not have a parent currently.
*/
public ModelNode getParentNode() {
return parentNode;
}
/**
* Returns the data for this policy source model node (if any). The model node data are expected to be not {@code null} only in
* case the type of this node is ASSERTION or ASSERTION_PARAMETER_NODE.
*
* @return the data of this policy source model node or {@code null} if the node does not have any data associated to it
* attached.
*/
public AssertionData getNodeData() {
return nodeData;
}
/**
* Returns the policy reference data for this policy source model node. The policy reference data are expected to be not {@code null} only in
* case the type of this node is POLICY_REFERENCE.
*
* @return the policy reference data for this policy source model node or {@code null} if the node does not have any policy reference data
* attached.
*/
PolicyReferenceData getPolicyReferenceData() {
return referenceData;
}
/**
* The method may be used to set or replace assertion data set for this node. If there are assertion data set already,
* those are replaced by a new reference and eventualy returned from the method.
* <p/>
* This method is supported only in case this model node instance's type is {@code ASSERTION} or {@code ASSERTION_PARAMETER_NODE}.
* If used from other node types, an exception is thrown.
*
* @param newData new assertion data to be set.
* @return old and replaced assertion data if any or {@code null} otherwise.
*
* @throws UnsupportedOperationException in case this method is called on nodes of type other than {@code ASSERTION}
* or {@code ASSERTION_PARAMETER_NODE}
*/
public AssertionData setOrReplaceNodeData(final AssertionData newData) {
if (!isDomainSpecific()) {
throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0051_OPERATION_NOT_SUPPORTED_FOR_THIS_BUT_ASSERTION_RELATED_NODE_TYPE(type)));
}
final AssertionData oldData = this.nodeData;
this.nodeData = newData;
return oldData;
}
/**
* The method specifies whether the model node instance represents assertion related node, it means whether its type
* is 'ASSERTION' or 'ASSERTION_PARAMETER_NODE'. This is, for example, the way to determine whether the node supports
* setting a {@link AssertionData} object via {@link #setOrReplaceNodeData(AssertionData)} method or not.
*
* @return {@code true} or {@code false} according to whether the node instance represents assertion related node or not.
*/
boolean isDomainSpecific() {
return type == Type.ASSERTION || type == Type.ASSERTION_PARAMETER_NODE;
}
/**
* Appends the specified child node to the end of the children list of this node and sets it's parent to reference
* this node.
*
* @param child node to be appended to the children list of this node.
* @return {@code true} (as per the general contract of the {@code Collection.add} method).
*
* @throws NullPointerException if the specified node is {@code null}.
* @throws IllegalArgumentException if child has a parent node set already to point to some node
*/
private boolean addChild(final ModelNode child) {
children.add(child);
child.parentNode = this;
return true;
}
void setReferencedModel(final PolicySourceModel model) {
if (this.type != Type.POLICY_REFERENCE) {
throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0050_OPERATION_NOT_SUPPORTED_FOR_THIS_BUT_POLICY_REFERENCE_NODE_TYPE(type)));
}
referencedModel = model;
}
PolicySourceModel getReferencedModel() {
return referencedModel;
}
/**
* Returns the number of child policy source model nodes. If this model node contains
* more than {@code Integer.MAX_VALUE} children, returns {@code Integer.MAX_VALUE}.
*
* @return the number of children of this node.
*/
public int childrenSize() {
return children.size();
}
/**
* Returns true if the node has at least one child node.
*
* @return true if the node has at least one child node, false otherwise.
*/
public boolean hasChildren() {
return !children.isEmpty();
}
/**
* Iterates through all child nodes.
*
* @return An iterator for the child nodes
*/
public Iterator<ModelNode> iterator() {
return children.iterator();
}
/**
* An {@code Object.equals(Object obj)} method override. Method ignores the parent source model. It means that two
* model nodes may be the same even if they belong to different models.
* <p/>
* If parent model comparison is desired, it must be accomplished separately. To perform that, the reference equality
* test is sufficient ({@code nodeA.getParentModel() == nodeB.getParentModel()}), since all model nodes are created
* for specific model instances.
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof ModelNode)) {
return false;
}
boolean result = true;
final ModelNode that = (ModelNode) obj;
result = result && this.type.equals(that.type);
// result = result && ((this.parentNode == null) ? that.parentNode == null : this.parentNode.equals(that.parentNode));
result = result && ((this.nodeData == null) ? that.nodeData == null : this.nodeData.equals(that.nodeData));
result = result && ((this.children == null) ? that.children == null : this.children.equals(that.children));
return result;
}
/**
* An {@code Object.hashCode()} method override.
*/
@Override
public int hashCode() {
int result = 17;
result = 37 * result + this.type.hashCode();
result = 37 * result + ((this.parentNode == null) ? 0 : this.parentNode.hashCode());
result = 37 * result + ((this.nodeData == null) ? 0 : this.nodeData.hashCode());
result = 37 * result + this.children.hashCode();
return result;
}
/**
* Returns a string representation of the object. In general, the <code>toString</code> method
* returns a string that "textually represents" this object.
*
* @return a string representation of the object.
*/
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
public StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
buffer.append(indent).append(type).append(" {").append(PolicyUtils.Text.NEW_LINE);
if (type == Type.ASSERTION) {
if (nodeData == null) {
buffer.append(innerIndent).append("no assertion data set");
} else {
nodeData.toString(indentLevel + 1, buffer);
}
buffer.append(PolicyUtils.Text.NEW_LINE);
} else if (type == Type.POLICY_REFERENCE) {
if (referenceData == null) {
buffer.append(innerIndent).append("no policy reference data set");
} else {
referenceData.toString(indentLevel + 1, buffer);
}
buffer.append(PolicyUtils.Text.NEW_LINE);
} else if (type == Type.ASSERTION_PARAMETER_NODE) {
if (nodeData == null) {
buffer.append(innerIndent).append("no parameter data set");
}
else {
nodeData.toString(indentLevel + 1, buffer);
}
buffer.append(PolicyUtils.Text.NEW_LINE);
}
if (children.size() > 0) {
for (ModelNode child : children) {
child.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE);
}
} else {
buffer.append(innerIndent).append("no child nodes").append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(indent).append('}');
return buffer;
}
@Override
protected ModelNode clone() throws CloneNotSupportedException {
final ModelNode clone = (ModelNode) super.clone();
if (this.nodeData != null) {
clone.nodeData = this.nodeData.clone();
}
// no need to clone PolicyReferenceData, since those are immutable
if (this.referencedModel != null) {
clone.referencedModel = this.referencedModel.clone();
}
clone.children = new LinkedList<ModelNode>();
clone.unmodifiableViewOnContent = Collections.unmodifiableCollection(clone.children);
for (ModelNode thisChild : this.children) {
clone.addChild(thisChild.clone());
}
return clone;
}
PolicyReferenceData getReferenceData() {
return referenceData;
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.AssertionSet;
import com.sun.xml.internal.ws.policy.NestedPolicy;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
/**
* Create a fully normalized WS-Policy infoset.
*
* @author Fabian Ritzmann
*/
class NormalizedModelGenerator extends PolicyModelGenerator {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(NormalizedModelGenerator.class);
private final PolicySourceModelCreator sourceModelCreator;
NormalizedModelGenerator(PolicySourceModelCreator sourceModelCreator) {
this.sourceModelCreator = sourceModelCreator;
}
@Override
public PolicySourceModel translate(final Policy policy) throws PolicyException {
LOGGER.entering(policy);
PolicySourceModel model = null;
if (policy == null) {
LOGGER.fine(LocalizationMessages.WSP_0047_POLICY_IS_NULL_RETURNING());
} else {
model = this.sourceModelCreator.create(policy);
final ModelNode rootNode = model.getRootNode();
final ModelNode exactlyOneNode = rootNode.createChildExactlyOneNode();
for (AssertionSet set : policy) {
final ModelNode alternativeNode = exactlyOneNode.createChildAllNode();
for (PolicyAssertion assertion : set) {
final AssertionData data = AssertionData.createAssertionData(assertion.getName(), assertion.getValue(), assertion.getAttributes(), assertion.isOptional(), assertion.isIgnorable());
final ModelNode assertionNode = alternativeNode.createChildAssertionNode(data);
if (assertion.hasNestedPolicy()) {
translate(assertionNode, assertion.getNestedPolicy());
}
if (assertion.hasParameters()) {
translate(assertionNode, assertion.getParametersIterator());
}
}
}
}
LOGGER.exiting(model);
return model;
}
@Override
protected ModelNode translate(final ModelNode parentAssertion, final NestedPolicy policy) {
final ModelNode nestedPolicyRoot = parentAssertion.createChildPolicyNode();
final ModelNode exactlyOneNode = nestedPolicyRoot.createChildExactlyOneNode();
final AssertionSet set = policy.getAssertionSet();
final ModelNode alternativeNode = exactlyOneNode.createChildAllNode();
translate(alternativeNode, set);
return nestedPolicyRoot;
}
}

View File

@@ -0,0 +1,171 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.AssertionSet;
import com.sun.xml.internal.ws.policy.NestedPolicy;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import java.util.Iterator;
/**
* Translate a policy into a PolicySourceModel.
*
* Code that depends on JAX-WS should use com.sun.xml.internal.ws.api.policy.ModelGenerator
* instead of this class.
*
* @author Marek Potociar
* @author Fabian Ritzmann
*/
public abstract class PolicyModelGenerator {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyModelGenerator.class);
/**
* This protected constructor avoids direct instantiation from outside of the class
*/
protected PolicyModelGenerator() {
// nothing to initialize
}
/**
* Factory method that returns a {@link PolicyModelGenerator} instance.
*
* @return {@link PolicyModelGenerator} instance
*/
public static PolicyModelGenerator getGenerator() {
return getNormalizedGenerator(new PolicySourceModelCreator());
}
/**
* Allows derived classes to create instances of the package private
* CompactModelGenerator.
*
* @param creator An implementation of the PolicySourceModelCreator.
* @return An instance of CompactModelGenerator.
*/
protected static PolicyModelGenerator getCompactGenerator(PolicySourceModelCreator creator) {
return new CompactModelGenerator(creator);
}
/**
* Allows derived classes to create instances of the package private
* NormalizedModelGenerator.
*
* @param creator An implementation of the PolicySourceModelCreator.
* @return An instance of NormalizedModelGenerator.
*/
protected static PolicyModelGenerator getNormalizedGenerator(PolicySourceModelCreator creator) {
return new NormalizedModelGenerator(creator);
}
/**
* This method translates a {@link Policy} into a
* {@link com.sun.xml.internal.ws.policy.sourcemodel policy infoset}. The resulting
* PolicySourceModel is disconnected from the input policy, thus any
* additional changes in the policy will have no effect on the PolicySourceModel.
*
* @param policy The policy to be translated into an infoset. May be null.
* @return translated The policy infoset. May be null if the input policy was
* null.
* @throws PolicyException in case Policy translation fails.
*/
public abstract PolicySourceModel translate(final Policy policy) throws PolicyException;
/**
* Iterates through a nested policy and returns the corresponding policy info model.
*
* @param parentAssertion The parent node.
* @param policy The nested policy.
* @return The nested policy translated to the policy info model.
*/
protected abstract ModelNode translate(final ModelNode parentAssertion, final NestedPolicy policy);
/**
* Add the contents of the assertion set as child node to the given model node.
*
* @param node The content of this assertion set are added as child nodes to this node.
* May not be null.
* @param assertions The assertions that are to be added to the node. May not be null.
*/
protected void translate(final ModelNode node, final AssertionSet assertions) {
for (PolicyAssertion assertion : assertions) {
final AssertionData data = AssertionData.createAssertionData(assertion.getName(), assertion.getValue(), assertion.getAttributes(), assertion.isOptional(), assertion.isIgnorable());
final ModelNode assertionNode = node.createChildAssertionNode(data);
if (assertion.hasNestedPolicy()) {
translate(assertionNode, assertion.getNestedPolicy());
}
if (assertion.hasParameters()) {
translate(assertionNode, assertion.getParametersIterator());
}
}
}
/**
* Iterates through all contained assertions and adds them to the info model.
*
* @param assertionParametersIterator The contained assertions.
* @param assertionNode The node to which the assertions are added as child nodes
*/
protected void translate(final ModelNode assertionNode, final Iterator<PolicyAssertion> assertionParametersIterator) {
while (assertionParametersIterator.hasNext()) {
final PolicyAssertion assertionParameter = assertionParametersIterator.next();
final AssertionData data = AssertionData.createAssertionParameterData(assertionParameter.getName(), assertionParameter.getValue(), assertionParameter.getAttributes());
final ModelNode assertionParameterNode = assertionNode.createChildAssertionParameterNode(data);
if (assertionParameter.hasNestedPolicy()) {
throw LOGGER.logSevereException(new IllegalStateException(LocalizationMessages.WSP_0005_UNEXPECTED_POLICY_ELEMENT_FOUND_IN_ASSERTION_PARAM(assertionParameter)));
}
if (assertionParameter.hasNestedAssertions()) {
translate(assertionParameterNode, assertionParameter.getNestedAssertionsIterator());
}
}
}
/**
* Allows derived classes to pass their own implementation of PolicySourceModelCreator
* into the PolicyModelGenerator instance.
*/
protected static class PolicySourceModelCreator {
/**
* Create an instance of the PolicySourceModel.
*
* @param policy The policy that underlies the created PolicySourceModel.
* @return An instance of the PolicySourceModel.
*/
protected PolicySourceModel create(final Policy policy) {
return PolicySourceModel.createPolicySourceModel(policy.getNamespaceVersion(),
policy.getId(), policy.getName());
}
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import java.util.Collection;
import com.sun.xml.internal.ws.policy.PolicyException;
/**
* Abstract class defines interface for policy model marshaller implementations that are specific to underlying
* persistence layer.
*
* @author Marek Potociar
*/
public abstract class PolicyModelMarshaller {
private static final PolicyModelMarshaller defaultXmlMarshaller = new XmlPolicyModelMarshaller(false);
private static final PolicyModelMarshaller invisibleAssertionXmlMarshaller = new XmlPolicyModelMarshaller(true);
/**
* Default constructor to ensure we have a common model marshaller base, but only our API classes implemented in this
* package will be able to extend this abstract class. This is to restrict attempts of extending the class from
* a client code.
*/
PolicyModelMarshaller() {
// nothing to instantiate
}
/**
* Marshalls the policy source model using provided storage reference
*
* @param model policy source model to be marshalled
* @param storage reference to underlying storage that should be used for model marshalling
* @throws PolicyException If marshalling failed
*/
public abstract void marshal(PolicySourceModel model, Object storage) throws PolicyException;
/**
* Marshalls the collection of policy source models using provided storage reference
*
* @param models collection of policy source models to be marshalled
* @param storage reference to underlying storage that should be used for model marshalling
* @throws PolicyException If marshalling failed
*/
public abstract void marshal(Collection<PolicySourceModel> models, Object storage) throws PolicyException;
/**
* Factory methods that returns a marshaller instance based on input parameter.
*
* @param marshallInvisible boolean parameter indicating whether the marshaller
* returned by this method does marshall private assertions or not.
*
* @return policy model marshaller that either marshalls private assertions or not
* based on the input argument.
*/
public static PolicyModelMarshaller getXmlMarshaller(final boolean marshallInvisible) {
return (marshallInvisible) ? invisibleAssertionXmlMarshaller : defaultXmlMarshaller;
}
}

View File

@@ -0,0 +1,459 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import com.sun.xml.internal.ws.policy.AssertionSet;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.spi.AssertionCreationException;
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionCreator;
/**
* This class provides a method for translating a {@link PolicySourceModel} structure to a normalized {@link Policy} expression.
* The resulting Policy is disconnected from its model, thus any additional changes in the model will have no effect on the Policy
* expression.
*
* @author Marek Potociar
* @author Fabian Ritzmann
*/
public class PolicyModelTranslator {
private static final class ContentDecomposition {
final List<Collection<ModelNode>> exactlyOneContents = new LinkedList<Collection<ModelNode>>();
final List<ModelNode> assertions = new LinkedList<ModelNode>();
void reset() {
exactlyOneContents.clear();
assertions.clear();
}
}
private static final class RawAssertion {
ModelNode originalNode; // used to initialize nestedPolicy and nestedAssertions in the constructor of RawAlternative
Collection<RawAlternative> nestedAlternatives = null;
final Collection<ModelNode> parameters;
RawAssertion(ModelNode originalNode, Collection<ModelNode> parameters) {
this.parameters = parameters;
this.originalNode = originalNode;
}
}
private static final class RawAlternative {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyModelTranslator.RawAlternative.class);
final List<RawPolicy> allNestedPolicies = new LinkedList<RawPolicy>(); // used to track the nested policies which need to be normalized
final Collection<RawAssertion> nestedAssertions;
RawAlternative(Collection<ModelNode> assertionNodes) throws PolicyException {
this.nestedAssertions = new LinkedList<RawAssertion>();
for (ModelNode node : assertionNodes) {
RawAssertion assertion = new RawAssertion(node, new LinkedList<ModelNode>());
nestedAssertions.add(assertion);
for (ModelNode assertionNodeChild : assertion.originalNode.getChildren()) {
switch (assertionNodeChild.getType()) {
case ASSERTION_PARAMETER_NODE:
assertion.parameters.add(assertionNodeChild);
break;
case POLICY:
case POLICY_REFERENCE:
if (assertion.nestedAlternatives == null) {
assertion.nestedAlternatives = new LinkedList<RawAlternative>();
RawPolicy nestedPolicy;
if (assertionNodeChild.getType() == ModelNode.Type.POLICY) {
nestedPolicy = new RawPolicy(assertionNodeChild, assertion.nestedAlternatives);
} else {
nestedPolicy = new RawPolicy(getReferencedModelRootNode(assertionNodeChild), assertion.nestedAlternatives);
}
this.allNestedPolicies.add(nestedPolicy);
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0006_UNEXPECTED_MULTIPLE_POLICY_NODES()));
}
break;
default:
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0008_UNEXPECTED_CHILD_MODEL_TYPE(assertionNodeChild.getType())));
}
}
}
}
}
private static final class RawPolicy {
final Collection<ModelNode> originalContent;
final Collection<RawAlternative> alternatives;
RawPolicy(ModelNode policyNode, Collection<RawAlternative> alternatives) {
originalContent = policyNode.getChildren();
this.alternatives = alternatives;
}
}
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyModelTranslator.class);
private static final PolicyAssertionCreator defaultCreator = new DefaultPolicyAssertionCreator();
private final Map<String, PolicyAssertionCreator> assertionCreators;
private PolicyModelTranslator() throws PolicyException {
this(null);
}
protected PolicyModelTranslator(final Collection<PolicyAssertionCreator> creators) throws PolicyException {
LOGGER.entering(creators);
final Collection<PolicyAssertionCreator> allCreators = new LinkedList<PolicyAssertionCreator>();
final PolicyAssertionCreator[] discoveredCreators = PolicyUtils.ServiceProvider.load(PolicyAssertionCreator.class);
for (PolicyAssertionCreator creator : discoveredCreators) {
allCreators.add(creator);
}
if (creators != null) {
for (PolicyAssertionCreator creator : creators) {
allCreators.add(creator);
}
}
final Map<String, PolicyAssertionCreator> pacMap = new HashMap<String, PolicyAssertionCreator>();
for (PolicyAssertionCreator creator : allCreators) {
final String[] supportedURIs = creator.getSupportedDomainNamespaceURIs();
final String creatorClassName = creator.getClass().getName();
if (supportedURIs == null || supportedURIs.length == 0) {
LOGGER.warning(LocalizationMessages.WSP_0077_ASSERTION_CREATOR_DOES_NOT_SUPPORT_ANY_URI(creatorClassName));
continue;
}
for (String supportedURI : supportedURIs) {
LOGGER.config(LocalizationMessages.WSP_0078_ASSERTION_CREATOR_DISCOVERED(creatorClassName, supportedURI));
if (supportedURI == null || supportedURI.length() == 0) {
throw LOGGER.logSevereException(new PolicyException(
LocalizationMessages.WSP_0070_ERROR_REGISTERING_ASSERTION_CREATOR(creatorClassName)));
}
final PolicyAssertionCreator oldCreator = pacMap.put(supportedURI, creator);
if (oldCreator != null) {
throw LOGGER.logSevereException(new PolicyException(
LocalizationMessages.WSP_0071_ERROR_MULTIPLE_ASSERTION_CREATORS_FOR_NAMESPACE(
supportedURI, oldCreator.getClass().getName(), creator.getClass().getName())));
}
}
}
this.assertionCreators = Collections.unmodifiableMap(pacMap);
LOGGER.exiting();
}
/**
* Method returns thread-safe policy model translator instance.
*
* This method is only intended to be used by code that has no dependencies on
* JAX-WS. Otherwise use com.sun.xml.internal.ws.policy.api.ModelTranslator.
*
* @return A policy model translator instance.
* @throws PolicyException If instantiating a PolicyAssertionCreator failed.
*/
public static PolicyModelTranslator getTranslator() throws PolicyException {
return new PolicyModelTranslator();
}
/**
* The method translates {@link PolicySourceModel} structure into normalized {@link Policy} expression. The resulting Policy
* is disconnected from its model, thus any additional changes in model will have no effect on the Policy expression.
*
* @param model the model to be translated into normalized policy expression. Must not be {@code null}.
* @return translated policy expression in it's normalized form.
* @throws PolicyException in case of translation failure
*/
public Policy translate(final PolicySourceModel model) throws PolicyException {
LOGGER.entering(model);
if (model == null) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0043_POLICY_MODEL_TRANSLATION_ERROR_INPUT_PARAM_NULL()));
}
PolicySourceModel localPolicyModelCopy;
try {
localPolicyModelCopy = model.clone();
} catch (CloneNotSupportedException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0016_UNABLE_TO_CLONE_POLICY_SOURCE_MODEL(), e));
}
final String policyId = localPolicyModelCopy.getPolicyId();
final String policyName = localPolicyModelCopy.getPolicyName();
final Collection<AssertionSet> alternatives = createPolicyAlternatives(localPolicyModelCopy);
LOGGER.finest(LocalizationMessages.WSP_0052_NUMBER_OF_ALTERNATIVE_COMBINATIONS_CREATED(alternatives.size()));
Policy policy = null;
if (alternatives.size() == 0) {
policy = Policy.createNullPolicy(model.getNamespaceVersion(), policyName, policyId);
LOGGER.finest(LocalizationMessages.WSP_0055_NO_ALTERNATIVE_COMBINATIONS_CREATED());
} else if (alternatives.size() == 1 && alternatives.iterator().next().isEmpty()) {
policy = Policy.createEmptyPolicy(model.getNamespaceVersion(), policyName, policyId);
LOGGER.finest(LocalizationMessages.WSP_0026_SINGLE_EMPTY_ALTERNATIVE_COMBINATION_CREATED());
} else {
policy = Policy.createPolicy(model.getNamespaceVersion(), policyName, policyId, alternatives);
LOGGER.finest(LocalizationMessages.WSP_0057_N_ALTERNATIVE_COMBINATIONS_M_POLICY_ALTERNATIVES_CREATED(alternatives.size(), policy.getNumberOfAssertionSets()));
}
LOGGER.exiting(policy);
return policy;
}
/**
* Method creates policy alternatives according to provided model. The model structure is modified in the process.
*
* @return created policy alternatives resulting from policy source model.
*/
private Collection<AssertionSet> createPolicyAlternatives(final PolicySourceModel model) throws PolicyException {
// creating global method variables
final ContentDecomposition decomposition = new ContentDecomposition();
// creating processing queue and starting the processing iterations
final Queue<RawPolicy> policyQueue = new LinkedList<RawPolicy>();
final Queue<Collection<ModelNode>> contentQueue = new LinkedList<Collection<ModelNode>>();
final RawPolicy rootPolicy = new RawPolicy(model.getRootNode(), new LinkedList<RawAlternative>());
RawPolicy processedPolicy = rootPolicy;
do {
Collection<ModelNode> processedContent = processedPolicy.originalContent;
do {
decompose(processedContent, decomposition);
if (decomposition.exactlyOneContents.isEmpty()) {
final RawAlternative alternative = new RawAlternative(decomposition.assertions);
processedPolicy.alternatives.add(alternative);
if (!alternative.allNestedPolicies.isEmpty()) {
policyQueue.addAll(alternative.allNestedPolicies);
}
} else { // we have a non-empty collection of exactly ones
final Collection<Collection<ModelNode>> combinations = PolicyUtils.Collections.combine(decomposition.assertions, decomposition.exactlyOneContents, false);
if (combinations != null && !combinations.isEmpty()) {
// processed alternative was split into some new alternatives, which we need to process
contentQueue.addAll(combinations);
}
}
} while ((processedContent = contentQueue.poll()) != null);
} while ((processedPolicy = policyQueue.poll()) != null);
// normalize nested policies to contain single alternative only
final Collection<AssertionSet> assertionSets = new LinkedList<AssertionSet>();
for (RawAlternative rootAlternative : rootPolicy.alternatives) {
final Collection<AssertionSet> normalizedAlternatives = normalizeRawAlternative(rootAlternative);
assertionSets.addAll(normalizedAlternatives);
}
return assertionSets;
}
/**
* Decomposes the unprocessed alternative content into two different collections:
* <p/>
* Content of 'EXACTLY_ONE' child nodes is expanded and placed in one list and
* 'ASSERTION' nodes are placed into other list. Direct 'ALL' and 'POLICY' child nodes are 'dissolved' in the process.
*
* Method reuses precreated ContentDecomposition object, which is reset before reuse.
*/
private void decompose(final Collection<ModelNode> content, final ContentDecomposition decomposition) throws PolicyException {
decomposition.reset();
final Queue<ModelNode> allContentQueue = new LinkedList<ModelNode>(content);
ModelNode node;
while ((node = allContentQueue.poll()) != null) {
// dissolving direct 'POLICY', 'POLICY_REFERENCE' and 'ALL' child nodes
switch (node.getType()) {
case POLICY :
case ALL :
allContentQueue.addAll(node.getChildren());
break;
case POLICY_REFERENCE :
allContentQueue.addAll(getReferencedModelRootNode(node).getChildren());
break;
case EXACTLY_ONE :
decomposition.exactlyOneContents.add(expandsExactlyOneContent(node.getChildren()));
break;
case ASSERTION :
decomposition.assertions.add(node);
break;
default :
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0007_UNEXPECTED_MODEL_NODE_TYPE_FOUND(node.getType())));
}
}
}
private static ModelNode getReferencedModelRootNode(final ModelNode policyReferenceNode) throws PolicyException {
final PolicySourceModel referencedModel = policyReferenceNode.getReferencedModel();
if (referencedModel == null) {
final PolicyReferenceData refData = policyReferenceNode.getPolicyReferenceData();
if (refData == null) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0041_POLICY_REFERENCE_NODE_FOUND_WITH_NO_POLICY_REFERENCE_IN_IT()));
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0010_UNEXPANDED_POLICY_REFERENCE_NODE_FOUND_REFERENCING(refData.getReferencedModelUri())));
}
} else {
return referencedModel.getRootNode();
}
}
/**
* Expands content of 'EXACTLY_ONE' node. Direct 'EXACTLY_ONE' child nodes are dissolved in the process.
*/
private Collection<ModelNode> expandsExactlyOneContent(final Collection<ModelNode> content) throws PolicyException {
final Collection<ModelNode> result = new LinkedList<ModelNode>();
final Queue<ModelNode> eoContentQueue = new LinkedList<ModelNode>(content);
ModelNode node;
while ((node = eoContentQueue.poll()) != null) {
// dissolving direct 'EXACTLY_ONE' child nodes
switch (node.getType()) {
case POLICY :
case ALL :
case ASSERTION :
result.add(node);
break;
case POLICY_REFERENCE :
result.add(getReferencedModelRootNode(node));
break;
case EXACTLY_ONE :
eoContentQueue.addAll(node.getChildren());
break;
default :
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0001_UNSUPPORTED_MODEL_NODE_TYPE(node.getType())));
}
}
return result;
}
private List<AssertionSet> normalizeRawAlternative(final RawAlternative alternative) throws AssertionCreationException, PolicyException {
final List<PolicyAssertion> normalizedContentBase = new LinkedList<PolicyAssertion>();
final Collection<List<PolicyAssertion>> normalizedContentOptions = new LinkedList<List<PolicyAssertion>>();
if (!alternative.nestedAssertions.isEmpty()) {
final Queue<RawAssertion> nestedAssertionsQueue = new LinkedList<RawAssertion>(alternative.nestedAssertions);
RawAssertion rawAssertion;
while((rawAssertion = nestedAssertionsQueue.poll()) != null) {
final List<PolicyAssertion> normalized = normalizeRawAssertion(rawAssertion);
// if there is only a single result, we can add it direclty to the content base collection
// more elements in the result indicate that we will have to create combinations
if (normalized.size() == 1) {
normalizedContentBase.addAll(normalized);
} else {
normalizedContentOptions.add(normalized);
}
}
}
final List<AssertionSet> options = new LinkedList<AssertionSet>();
if (normalizedContentOptions.isEmpty()) {
// we do not have any options to combine => returning this assertion
options.add(AssertionSet.createAssertionSet(normalizedContentBase));
} else {
// we have some options to combine => creating assertion options based on content combinations
final Collection<Collection<PolicyAssertion>> contentCombinations = PolicyUtils.Collections.combine(normalizedContentBase, normalizedContentOptions, true);
for (Collection<PolicyAssertion> contentOption : contentCombinations) {
options.add(AssertionSet.createAssertionSet(contentOption));
}
}
return options;
}
private List<PolicyAssertion> normalizeRawAssertion(final RawAssertion assertion) throws AssertionCreationException, PolicyException {
List<PolicyAssertion> parameters;
if (assertion.parameters.isEmpty()) {
parameters = null;
} else {
parameters = new ArrayList<PolicyAssertion>(assertion.parameters.size());
for (ModelNode parameterNode : assertion.parameters) {
parameters.add(createPolicyAssertionParameter(parameterNode));
}
}
final List<AssertionSet> nestedAlternatives = new LinkedList<AssertionSet>();
if (assertion.nestedAlternatives != null && !assertion.nestedAlternatives.isEmpty()) {
final Queue<RawAlternative> nestedAlternativeQueue = new LinkedList<RawAlternative>(assertion.nestedAlternatives);
RawAlternative rawAlternative;
while((rawAlternative = nestedAlternativeQueue.poll()) != null) {
nestedAlternatives.addAll(normalizeRawAlternative(rawAlternative));
}
// if there is only a single result, we can add it direclty to the content base collection
// more elements in the result indicate that we will have to create combinations
}
final List<PolicyAssertion> assertionOptions = new LinkedList<PolicyAssertion>();
final boolean nestedAlternativesAvailable = !nestedAlternatives.isEmpty();
if (nestedAlternativesAvailable) {
for (AssertionSet nestedAlternative : nestedAlternatives) {
assertionOptions.add(createPolicyAssertion(assertion.originalNode.getNodeData(), parameters, nestedAlternative));
}
} else {
assertionOptions.add(createPolicyAssertion(assertion.originalNode.getNodeData(), parameters, null));
}
return assertionOptions;
}
private PolicyAssertion createPolicyAssertionParameter(final ModelNode parameterNode) throws AssertionCreationException, PolicyException {
if (parameterNode.getType() != ModelNode.Type.ASSERTION_PARAMETER_NODE) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0065_INCONSISTENCY_IN_POLICY_SOURCE_MODEL(parameterNode.getType())));
}
List<PolicyAssertion> childParameters = null;
if (parameterNode.hasChildren()) {
childParameters = new ArrayList<PolicyAssertion>(parameterNode.childrenSize());
for (ModelNode childParameterNode : parameterNode) {
childParameters.add(createPolicyAssertionParameter(childParameterNode));
}
}
return createPolicyAssertion(parameterNode.getNodeData(), childParameters, null /* parameters do not have any nested alternatives */);
}
private PolicyAssertion createPolicyAssertion(final AssertionData data, final Collection<PolicyAssertion> assertionParameters, final AssertionSet nestedAlternative) throws AssertionCreationException {
final String assertionNamespace = data.getName().getNamespaceURI();
final PolicyAssertionCreator domainSpecificPAC = assertionCreators.get(assertionNamespace);
if (domainSpecificPAC == null) {
return defaultCreator.createAssertion(data, assertionParameters, nestedAlternative, null);
} else {
return domainSpecificPAC.createAssertion(data, assertionParameters, nestedAlternative, defaultCreator);
}
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.PolicyException;
/**
* Abstract class defines interface for policy model unmarshaller implementations that are specific to underlying
* persistence layer.
*
* Code that depends on JAX-WS should use com.sun.xml.internal.ws.api.policy.ModelUnmarshaller
* instead of this class.
*
* @author Marek Potociar
* @author Fabian Ritzmann
*/
public abstract class PolicyModelUnmarshaller {
private static final PolicyModelUnmarshaller xmlUnmarshaller = new XmlPolicyModelUnmarshaller();
/**
* Default constructor to ensure we have a common model unmarshaller base, but only our API classes implemented in this
* package will be able to extend this abstract class. This is to restrict attempts of extending the class from
* a client code.
*/
PolicyModelUnmarshaller() {
// nothing to intitialize
}
/**
* Unmarshalls single policy source model from provided storage reference. Method expects that the storage
* cursor to be alread placed on the start of a policy expression. Inner comments and whitespaces are skipped
* in processing. Any other cursor position results in a PolicyException being thrown.
*
* @param storage reference to underlying storage that should be used for model unmarshalling
* @return unmarshalled policy source model. If no policies are found, returns {@code null}.
* @throws PolicyException in case of the unmarshalling problems
*/
public abstract PolicySourceModel unmarshalModel(Object storage) throws PolicyException;
/**
* Factory method that returns policy model unmarshaller able to unmarshal
* policy expressions from XML source.
*
* Code that depends on JAX-WS should use com.sun.xml.internal.ws.api.policy.ModelUnmarshaller.getUnmarshaller()
* instead of this method.
*
* @return policy model unmarshaller able to unmarshal policy expressions from XML source.
*/
public static PolicyModelUnmarshaller getXmlUnmarshaller() {
return xmlUnmarshaller;
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import java.net.URI;
import java.net.URISyntaxException;
/**
*
* @author Marek Potociar
*/
final class PolicyReferenceData {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyReferenceData.class);
private static final URI DEFAULT_DIGEST_ALGORITHM_URI;
private static final URISyntaxException CLASS_INITIALIZATION_EXCEPTION;
static {
URISyntaxException tempEx = null;
URI tempUri = null;
try {
tempUri = new URI("http://schemas.xmlsoap.org/ws/2004/09/policy/Sha1Exc");
} catch (URISyntaxException e) {
tempEx = e;
} finally {
DEFAULT_DIGEST_ALGORITHM_URI = tempUri;
CLASS_INITIALIZATION_EXCEPTION = tempEx;
}
}
private final URI referencedModelUri;
private final String digest;
private final URI digestAlgorithmUri;
/** Creates a new instance of PolicyReferenceData */
public PolicyReferenceData(URI referencedModelUri) {
this.referencedModelUri = referencedModelUri;
this.digest = null;
this.digestAlgorithmUri = null;
}
public PolicyReferenceData(URI referencedModelUri, String expectedDigest, URI usedDigestAlgorithm) {
if (CLASS_INITIALIZATION_EXCEPTION != null) {
throw LOGGER.logSevereException(new IllegalStateException(LocalizationMessages.WSP_0015_UNABLE_TO_INSTANTIATE_DIGEST_ALG_URI_FIELD(), CLASS_INITIALIZATION_EXCEPTION));
}
if (usedDigestAlgorithm != null && expectedDigest == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0072_DIGEST_MUST_NOT_BE_NULL_WHEN_ALG_DEFINED()));
}
this.referencedModelUri = referencedModelUri;
if (expectedDigest == null) {
this.digest = null;
this.digestAlgorithmUri = null;
} else {
this.digest = expectedDigest;
if (usedDigestAlgorithm == null) {
this.digestAlgorithmUri = DEFAULT_DIGEST_ALGORITHM_URI;
} else {
this.digestAlgorithmUri = usedDigestAlgorithm;
}
}
}
public URI getReferencedModelUri() {
return referencedModelUri;
}
public String getDigest() {
return digest;
}
public URI getDigestAlgorithmUri() {
return digestAlgorithmUri;
}
/**
* An {@code Object.toString()} method override.
*/
@Override
public String toString() {
return toString(0, new StringBuffer()).toString();
}
/**
* A helper method that appends indented string representation of this instance to the input string buffer.
*
* @param indentLevel indentation level to be used.
* @param buffer buffer to be used for appending string representation of this instance
* @return modified buffer containing new string representation of the instance
*/
public StringBuffer toString(final int indentLevel, final StringBuffer buffer) {
final String indent = PolicyUtils.Text.createIndent(indentLevel);
final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1);
buffer.append(indent).append("reference data {").append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("referenced policy model URI = '").append(referencedModelUri).append('\'').append(PolicyUtils.Text.NEW_LINE);
if (digest == null) {
buffer.append(innerIndent).append("no digest specified").append(PolicyUtils.Text.NEW_LINE);
} else {
buffer.append(innerIndent).append("digest algorith URI = '").append(digestAlgorithmUri).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("digest = '").append(digest).append('\'').append(PolicyUtils.Text.NEW_LINE);
}
buffer.append(indent).append('}');
return buffer;
}
}

View File

@@ -0,0 +1,428 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import com.sun.xml.internal.ws.policy.PolicyConstants;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.sun.xml.internal.ws.policy.spi.PrefixMapper;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import javax.xml.namespace.QName;
/**
* This class is a root of unmarshaled policy source structure. Each instance of the class contains factory method
* to create new {@link com.sun.xml.internal.ws.policy.sourcemodel.ModelNode} instances associated with the actual model instance.
*
* @author Marek Potociar
* @author Fabian Ritzmann
*/
public class PolicySourceModel implements Cloneable {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicySourceModel.class);
private static final Map<String, String> DEFAULT_NAMESPACE_TO_PREFIX = new HashMap<String, String>();
static {
PrefixMapper[] prefixMappers = PolicyUtils.ServiceProvider.load(PrefixMapper.class);
if (prefixMappers != null) {
for (PrefixMapper mapper: prefixMappers) {
DEFAULT_NAMESPACE_TO_PREFIX.putAll(mapper.getPrefixMap());
}
}
for (NamespaceVersion version : NamespaceVersion.values()) {
DEFAULT_NAMESPACE_TO_PREFIX.put(version.toString(), version.getDefaultNamespacePrefix());
}
DEFAULT_NAMESPACE_TO_PREFIX.put(PolicyConstants.WSU_NAMESPACE_URI,
PolicyConstants.WSU_NAMESPACE_PREFIX);
DEFAULT_NAMESPACE_TO_PREFIX.put(PolicyConstants.SUN_POLICY_NAMESPACE_URI,
PolicyConstants.SUN_POLICY_NAMESPACE_PREFIX);
}
// Map namespaces to prefixes
private final Map<String, String> namespaceToPrefix =
new HashMap<String, String>(DEFAULT_NAMESPACE_TO_PREFIX);
private ModelNode rootNode;
private final String policyId;
private final String policyName;
private final NamespaceVersion nsVersion;
private final List<ModelNode> references = new LinkedList<ModelNode>(); // links to policy reference nodes
private boolean expanded = false;
/**
* Factory method that creates new policy source model instance.
*
* This method is only intended to be used by code that has no dependencies on
* JAX-WS. Otherwise use com.sun.xml.internal.ws.policy.api.SourceModel.
*
* @param nsVersion The policy version
* @return Newly created policy source model instance.
*/
public static PolicySourceModel createPolicySourceModel(final NamespaceVersion nsVersion) {
return new PolicySourceModel(nsVersion);
}
/**
* Factory method that creates new policy source model instance and initializes it according to parameters provided.
*
* This method is only intended to be used by code that has no dependencies on
* JAX-WS. Otherwise use com.sun.xml.internal.ws.policy.api.SourceModel.
*
* @param nsVersion The policy version
* @param policyId local policy identifier - relative URI. May be {@code null}.
* @param policyName global policy identifier - absolute policy expression URI. May be {@code null}.
* @return Newly created policy source model instance with its name and id properly set.
*/
public static PolicySourceModel createPolicySourceModel(final NamespaceVersion nsVersion, final String policyId, final String policyName) {
return new PolicySourceModel(nsVersion, policyId, policyName);
}
/**
* Constructor that creates a new policy source model instance without any
* id or name identifier. The namespace-to-prefix map is initialized with mapping
* of policy namespace to the default value set by
* {@link PolicyConstants#POLICY_NAMESPACE_PREFIX POLICY_NAMESPACE_PREFIX constant}.
*
* @param nsVersion The WS-Policy version.
*/
private PolicySourceModel(NamespaceVersion nsVersion) {
this(nsVersion, null, null);
}
/**
* Constructor that creates a new policy source model instance with given
* id or name identifier.
*
* @param nsVersion The WS-Policy version.
* @param policyId Relative policy reference within an XML document. May be {@code null}.
* @param policyName Absolute IRI of policy expression. May be {@code null}.
*/
private PolicySourceModel(NamespaceVersion nsVersion, String policyId, String policyName) {
this(nsVersion, policyId, policyName, null);
}
/**
* Constructor that creates a new policy source model instance with given
* id or name identifier and a set of PrefixMappers.
*
* This constructor is intended to be used by the JAX-WS com.sun.xml.internal.ws.policy.api.SourceModel.
*
* @param nsVersion The WS-Policy version.
* @param policyId Relative policy reference within an XML document. May be {@code null}.
* @param policyName Absolute IRI of policy expression. May be {@code null}.
* @param prefixMappers A collection of PrefixMappers to be used with this instance. May be {@code null}.
*/
protected PolicySourceModel(NamespaceVersion nsVersion, String policyId,
String policyName, Collection<PrefixMapper> prefixMappers) {
this.rootNode = ModelNode.createRootPolicyNode(this);
this.nsVersion = nsVersion;
this.policyId = policyId;
this.policyName = policyName;
if (prefixMappers != null) {
for (PrefixMapper prefixMapper : prefixMappers) {
this.namespaceToPrefix.putAll(prefixMapper.getPrefixMap());
}
}
}
/**
* Returns a root node of this policy source model. It is allways of POLICY type.
*
* @return root policy source model node - allways of POLICY type.
*/
public ModelNode getRootNode() {
return rootNode;
}
/**
* Returns a policy name of this policy source model.
*
* @return policy name.
*/
public String getPolicyName() {
return policyName;
}
/**
* Returns a policy ID of this policy source model.
*
* @return policy ID.
*/
public String getPolicyId() {
return policyId;
}
/**
* Returns an original namespace version of this policy source model.
*
* @return namespace version.
*/
public NamespaceVersion getNamespaceVersion() {
return nsVersion;
}
/**
* Provides information about how namespaces used in this {@link PolicySourceModel}
* instance should be mapped to their default prefixes when marshalled.
*
* @return immutable map that holds information about namespaces used in the
* model and their mapping to prefixes that should be used when marshalling
* this model.
* @throws PolicyException Thrown if one of the prefix mappers threw an exception.
*/
Map<String, String> getNamespaceToPrefixMapping() throws PolicyException {
final Map<String, String> nsToPrefixMap = new HashMap<String, String>();
final Collection<String> namespaces = getUsedNamespaces();
for (String namespace : namespaces) {
final String prefix = getDefaultPrefix(namespace);
if (prefix != null) {
nsToPrefixMap.put(namespace, prefix);
}
}
return nsToPrefixMap;
}
/**
* An {@code Object.equals(Object obj)} method override.
* <p/>
* When child nodes are tested for equality, the parent policy source model is not considered. Thus two different
* policy source models instances may be equal based on their node content.
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof PolicySourceModel)) {
return false;
}
boolean result = true;
final PolicySourceModel that = (PolicySourceModel) obj;
result = result && ((this.policyId == null) ? that.policyId == null : this.policyId.equals(that.policyId));
result = result && ((this.policyName == null) ? that.policyName == null : this.policyName.equals(that.policyName));
result = result && this.rootNode.equals(that.rootNode);
return result;
}
/**
* An {@code Object.hashCode()} method override.
*/
@Override
public int hashCode() {
int result = 17;
result = 37 * result + ((this.policyId == null) ? 0 : this.policyId.hashCode());
result = 37 * result + ((this.policyName == null) ? 0 : this.policyName.hashCode());
result = 37 * result + this.rootNode.hashCode();
return result;
}
/**
* Returns a string representation of the object. In general, the <code>toString</code> method
* returns a string that "textually represents" this object.
*
* @return a string representation of the object.
*/
@Override
public String toString() {
final String innerIndent = PolicyUtils.Text.createIndent(1);
final StringBuffer buffer = new StringBuffer(60);
buffer.append("Policy source model {").append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("policy id = '").append(policyId).append('\'').append(PolicyUtils.Text.NEW_LINE);
buffer.append(innerIndent).append("policy name = '").append(policyName).append('\'').append(PolicyUtils.Text.NEW_LINE);
rootNode.toString(1, buffer).append(PolicyUtils.Text.NEW_LINE).append('}');
return buffer.toString();
}
@Override
protected PolicySourceModel clone() throws CloneNotSupportedException {
final PolicySourceModel clone = (PolicySourceModel) super.clone();
clone.rootNode = this.rootNode.clone();
try {
clone.rootNode.setParentModel(clone);
} catch (IllegalAccessException e) {
throw LOGGER.logSevereException(new CloneNotSupportedException(LocalizationMessages.WSP_0013_UNABLE_TO_SET_PARENT_MODEL_ON_ROOT()), e);
}
return clone;
}
/**
* Returns a boolean value indicating whether this policy source model contains references to another policy source models.
* <p/>
* Every source model that references other policies must be expanded before it can be translated into a Policy objects. See
* {@link #expand(PolicySourceModelContext)} and {@link #isExpanded()} for more details.
*
* @return {@code true} or {code false} depending on whether this policy source model contains references to another policy source models.
*/
public boolean containsPolicyReferences() {
return !references.isEmpty();
}
/**
* Returns a boolean value indicating whether this policy source model contains is already expanded (i.e. contains no unexpanded
* policy references) or not. This means that if model does not originally contain any policy references, it is considered as expanded,
* thus this method returns {@code true} in such case. Also this method does not check whether the references policy source models are expanded
* as well, so after expanding this model a value of {@code true} is returned even if referenced models are not expanded yet. Thus each model
* can be considered to be fully expanded only if all policy source models stored in PolicySourceModelContext instance are expanded, provided the
* PolicySourceModelContext instance contains full set of policy source models.
* <p/>
* Every source model that references other policies must be expanded before it can be translated into a Policy object. See
* {@link #expand(PolicySourceModelContext)} and {@link #containsPolicyReferences()} for more details.
*
* @return {@code true} or {@code false} depending on whether this policy source model contains is expanded or not.
*/
private boolean isExpanded() {
return references.isEmpty() || expanded;
}
/**
* Expands current policy model. This means, that if this model contains any (unexpanded) policy references, then the method expands those
* references by placing the content of the referenced policy source models under the policy reference nodes. This operation merely creates
* a link between this and referenced policy source models. Thus any change in the referenced models will be visible wihtin this model as well.
* <p/>
* Please, notice that the method does not check if the referenced models are already expanded nor does the method try to expand unexpanded
* referenced models. This must be preformed manually within client's code. Consecutive calls of this method will have no effect.
* <p/>
* Every source model that references other policies must be expanded before it can be translated into a Policy object. See
* {@link #isExpanded()} and {@link #containsPolicyReferences()} for more details.
*
* @param context a policy source model context holding the set of unmarshalled policy source models within the same context.
* @throws PolicyException Thrown if a referenced policy could not be resolved
*/
public synchronized void expand(final PolicySourceModelContext context) throws PolicyException {
if (!isExpanded()) {
for (ModelNode reference : references) {
final PolicyReferenceData refData = reference.getPolicyReferenceData();
final String digest = refData.getDigest();
PolicySourceModel referencedModel;
if (digest == null) {
referencedModel = context.retrieveModel(refData.getReferencedModelUri());
} else {
referencedModel = context.retrieveModel(refData.getReferencedModelUri(), refData.getDigestAlgorithmUri(), digest);
}
reference.setReferencedModel(referencedModel);
}
expanded = true;
}
}
/**
* Adds new policy reference to the policy source model. The method is used by
* the ModelNode instances of type POLICY_REFERENCE that need to register themselves
* as policy references in the model.
*
* @param node policy reference model node to be registered as a policy reference
* in this model.
*/
void addNewPolicyReference(final ModelNode node) {
if (node.getType() != ModelNode.Type.POLICY_REFERENCE) {
throw new IllegalArgumentException(LocalizationMessages.WSP_0042_POLICY_REFERENCE_NODE_EXPECTED_INSTEAD_OF(node.getType()));
}
references.add(node);
}
/**
* Iterates through policy vocabulary and extracts set of namespaces used in
* the policy expression.
*
* @return collection of used namespaces within given policy instance
* @throws PolicyException Thrown if internal processing failed.
*/
private Collection<String> getUsedNamespaces() throws PolicyException {
final Set<String> namespaces = new HashSet<String>();
namespaces.add(getNamespaceVersion().toString());
if (this.policyId != null) {
namespaces.add(PolicyConstants.WSU_NAMESPACE_URI);
}
final Queue<ModelNode> nodesToBeProcessed = new LinkedList<ModelNode>();
nodesToBeProcessed.add(rootNode);
ModelNode processedNode;
while ((processedNode = nodesToBeProcessed.poll()) != null) {
for (ModelNode child : processedNode.getChildren()) {
if (child.hasChildren()) {
if (!nodesToBeProcessed.offer(child)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0081_UNABLE_TO_INSERT_CHILD(nodesToBeProcessed, child)));
}
}
if (child.isDomainSpecific()) {
final AssertionData nodeData = child.getNodeData();
namespaces.add(nodeData.getName().getNamespaceURI());
if (nodeData.isPrivateAttributeSet()) {
namespaces.add(PolicyConstants.SUN_POLICY_NAMESPACE_URI);
}
for (Entry<QName, String> attribute : nodeData.getAttributesSet()) {
namespaces.add(attribute.getKey().getNamespaceURI());
}
}
}
}
return namespaces;
}
/**
* Method retrieves default prefix for given namespace. Method returns null if
* no default prefix is defined..
*
* @param namespace to get default prefix for.
* @return default prefix for given namespace. May return {@code null} if the
* default prefix for given namespace is not defined.
*/
private String getDefaultPrefix(final String namespace) {
return namespaceToPrefix.get(namespace);
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author Marek Potociar, Jakub Podlesak
*/
public final class PolicySourceModelContext {
Map<URI,PolicySourceModel> policyModels;
/**
* Private constructor prevents instantiation of the instance from outside of the class
*/
private PolicySourceModelContext() {
// nothing to initialize
}
private Map<URI,PolicySourceModel> getModels() {
if (null==policyModels) {
policyModels = new HashMap<URI,PolicySourceModel>();
}
return policyModels;
}
public void addModel(final URI modelUri, final PolicySourceModel model) {
getModels().put(modelUri,model);
}
public static PolicySourceModelContext createContext() {
return new PolicySourceModelContext();
}
public boolean containsModel(final URI modelUri) {
return getModels().containsKey(modelUri);
}
PolicySourceModel retrieveModel(final URI modelUri) {
return getModels().get(modelUri);
}
PolicySourceModel retrieveModel(final URI modelUri, final URI digestAlgorithm, final String digest) {
// TODO: implement
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return "PolicySourceModelContext: policyModels = " + this.policyModels;
}
}

View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.txw2.TXW;
import com.sun.xml.internal.txw2.TypedXmlWriter;
import com.sun.xml.internal.txw2.output.StaxSerializer;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import com.sun.xml.internal.ws.policy.PolicyConstants;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamWriter;
public final class XmlPolicyModelMarshaller extends PolicyModelMarshaller {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(XmlPolicyModelMarshaller.class);
private final boolean marshallInvisible;
XmlPolicyModelMarshaller(boolean marshallInvisible) {
this.marshallInvisible = marshallInvisible;
}
public void marshal(final PolicySourceModel model, final Object storage) throws PolicyException {
if (storage instanceof StaxSerializer) {
marshal(model, (StaxSerializer) storage);
} else if (storage instanceof TypedXmlWriter) {
marshal(model, (TypedXmlWriter) storage);
} else if (storage instanceof XMLStreamWriter) {
marshal(model, (XMLStreamWriter) storage);
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0022_STORAGE_TYPE_NOT_SUPPORTED(storage.getClass().getName())));
}
}
public void marshal(final Collection<PolicySourceModel> models, final Object storage) throws PolicyException {
for (PolicySourceModel model : models) {
marshal(model, storage);
}
}
/**
* Marshal a policy onto the given StaxSerializer.
*
* @param model A policy source model.
* @param writer A Stax serializer.
* @throws PolicyException If marshalling failed.
*/
private void marshal(final PolicySourceModel model, final StaxSerializer writer) throws PolicyException {
final TypedXmlWriter policy = TXW.create(model.getNamespaceVersion().asQName(XmlToken.Policy), TypedXmlWriter.class, writer);
marshalDefaultPrefixes(model, policy);
marshalPolicyAttributes(model, policy);
marshal(model.getNamespaceVersion(), model.getRootNode(), policy);
policy.commit();
}
/**
* Marshal a policy onto the given TypedXmlWriter.
*
* @param model A policy source model.
* @param writer A typed XML writer.
* @throws PolicyException If marshalling failed.
*/
private void marshal(final PolicySourceModel model, final TypedXmlWriter writer) throws PolicyException {
final TypedXmlWriter policy = writer._element(model.getNamespaceVersion().asQName(XmlToken.Policy), TypedXmlWriter.class);
marshalDefaultPrefixes(model, policy);
marshalPolicyAttributes(model, policy);
marshal(model.getNamespaceVersion(), model.getRootNode(), policy);
}
/**
* Marshal a policy onto the given XMLStreamWriter.
*
* @param model A policy source model.
* @param writer An XML stream writer.
* @throws PolicyException If marshalling failed.
*/
private void marshal(final PolicySourceModel model, final XMLStreamWriter writer) throws PolicyException {
final StaxSerializer serializer = new StaxSerializer(writer);
final TypedXmlWriter policy = TXW.create(model.getNamespaceVersion().asQName(XmlToken.Policy), TypedXmlWriter.class, serializer);
marshalDefaultPrefixes(model, policy);
marshalPolicyAttributes(model, policy);
marshal(model.getNamespaceVersion(), model.getRootNode(), policy);
policy.commit();
serializer.flush();
}
/**
* Marshal the Policy root element attributes onto the TypedXmlWriter.
*
* @param model The policy source model.
* @param writer The typed XML writer.
*/
private static void marshalPolicyAttributes(final PolicySourceModel model, final TypedXmlWriter writer) {
final String policyId = model.getPolicyId();
if (policyId != null) {
writer._attribute(PolicyConstants.WSU_ID, policyId);
}
final String policyName = model.getPolicyName();
if (policyName != null) {
writer._attribute(model.getNamespaceVersion().asQName(XmlToken.Name), policyName);
}
}
/**
* Marshal given ModelNode and child elements on given TypedXmlWriter.
*
* @param nsVersion The WS-Policy version.
* @param rootNode The ModelNode that is marshalled.
* @param writer The TypedXmlWriter onto which the content of the rootNode is marshalled.
*/
private void marshal(final NamespaceVersion nsVersion, final ModelNode rootNode, final TypedXmlWriter writer) {
for (ModelNode node : rootNode) {
final AssertionData data = node.getNodeData();
if (marshallInvisible || data == null || !data.isPrivateAttributeSet()) {
TypedXmlWriter child = null;
if (data == null) {
child = writer._element(nsVersion.asQName(node.getType().getXmlToken()), TypedXmlWriter.class);
} else {
child = writer._element(data.getName(), TypedXmlWriter.class);
final String value = data.getValue();
if (value != null) {
child._pcdata(value);
}
if (data.isOptionalAttributeSet()) {
child._attribute(nsVersion.asQName(XmlToken.Optional), Boolean.TRUE);
}
if (data.isIgnorableAttributeSet()) {
child._attribute(nsVersion.asQName(XmlToken.Ignorable), Boolean.TRUE);
}
for (Entry<QName, String> entry : data.getAttributesSet()) {
child._attribute(entry.getKey(), entry.getValue());
}
}
marshal(nsVersion, node, child);
}
}
}
/**
* Write default prefixes onto the given TypedXmlWriter
*
* @param model The policy source model. May not be null.
* @param writer The TypedXmlWriter. May not be null.
* @throws PolicyException If the creation of the prefix to namespace URI map failed.
*/
private void marshalDefaultPrefixes(final PolicySourceModel model, final TypedXmlWriter writer) throws PolicyException {
final Map<String, String> nsMap = model.getNamespaceToPrefixMapping();
if (!marshallInvisible && nsMap.containsKey(PolicyConstants.SUN_POLICY_NAMESPACE_URI)) {
nsMap.remove(PolicyConstants.SUN_POLICY_NAMESPACE_URI);
}
for (Map.Entry<String, String> nsMappingEntry : nsMap.entrySet()) {
writer._namespace(nsMappingEntry.getKey(), nsMappingEntry.getValue());
}
}
}

View File

@@ -0,0 +1,374 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;
import com.sun.xml.internal.ws.policy.PolicyConstants;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
/**
* Unmarshal XML policy expressions.
*
* @author Marek Potociar
* @author Fabian Ritzmann
*/
public class XmlPolicyModelUnmarshaller extends PolicyModelUnmarshaller {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(XmlPolicyModelUnmarshaller.class);
/**
* Creates a new instance of XmlPolicyModelUnmarshaller
*/
protected XmlPolicyModelUnmarshaller() {
// nothing to initialize
}
/**
* See {@link PolicyModelUnmarshaller#unmarshalModel(Object) base method documentation}.
*/
public PolicySourceModel unmarshalModel(final Object storage) throws PolicyException {
final XMLEventReader reader = createXMLEventReader(storage);
PolicySourceModel model = null;
loop:
while (reader.hasNext()) {
try {
final XMLEvent event = reader.peek();
switch (event.getEventType()) {
case XMLStreamConstants.START_DOCUMENT:
case XMLStreamConstants.COMMENT:
reader.nextEvent();
break; // skipping the comments and start document events
case XMLStreamConstants.CHARACTERS:
processCharacters(ModelNode.Type.POLICY, event.asCharacters(), null);
// we advance the reader only if there is no exception thrown from
// the processCharacters(...) call. Otherwise we don't modify the stream
reader.nextEvent();
break;
case XMLStreamConstants.START_ELEMENT:
if (NamespaceVersion.resolveAsToken(event.asStartElement().getName()) == XmlToken.Policy) {
StartElement rootElement = reader.nextEvent().asStartElement();
model = initializeNewModel(rootElement);
unmarshalNodeContent(model.getNamespaceVersion(), model.getRootNode(), rootElement.getName(), reader);
break loop;
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0048_POLICY_ELEMENT_EXPECTED_FIRST()));
}
default:
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0048_POLICY_ELEMENT_EXPECTED_FIRST()));
}
} catch (XMLStreamException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0068_FAILED_TO_UNMARSHALL_POLICY_EXPRESSION(), e));
}
}
return model;
}
/**
* Allow derived classes to pass in a custom instance of PolicySourceModel.
*
* @param nsVersion
* @param id
* @param name
* @return
*/
protected PolicySourceModel createSourceModel(NamespaceVersion nsVersion, String id, String name) {
return PolicySourceModel.createPolicySourceModel(nsVersion, id, name);
}
private PolicySourceModel initializeNewModel(final StartElement element) throws PolicyException, XMLStreamException {
PolicySourceModel model;
final NamespaceVersion nsVersion = NamespaceVersion.resolveVersion(element.getName().getNamespaceURI());
final Attribute policyName = getAttributeByName(element, nsVersion.asQName(XmlToken.Name));
final Attribute xmlId = getAttributeByName(element, PolicyConstants.XML_ID);
Attribute policyId = getAttributeByName(element, PolicyConstants.WSU_ID);
if (policyId == null) {
policyId = xmlId;
} else if (xmlId != null) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0058_MULTIPLE_POLICY_IDS_NOT_ALLOWED()));
}
model = createSourceModel(nsVersion,
(policyId == null) ? null : policyId.getValue(),
(policyName == null) ? null : policyName.getValue());
return model;
}
private ModelNode addNewChildNode(final NamespaceVersion nsVersion, final ModelNode parentNode, final StartElement childElement) throws PolicyException {
ModelNode childNode;
final QName childElementName = childElement.getName();
if (parentNode.getType() == ModelNode.Type.ASSERTION_PARAMETER_NODE) {
childNode = parentNode.createChildAssertionParameterNode();
} else {
XmlToken token = NamespaceVersion.resolveAsToken(childElementName);
switch (token) {
case Policy:
childNode = parentNode.createChildPolicyNode();
break;
case All:
childNode = parentNode.createChildAllNode();
break;
case ExactlyOne:
childNode = parentNode.createChildExactlyOneNode();
break;
case PolicyReference:
final Attribute uri = getAttributeByName(childElement, nsVersion.asQName(XmlToken.Uri));
if (uri == null) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0040_POLICY_REFERENCE_URI_ATTR_NOT_FOUND()));
} else {
try {
final URI reference = new URI(uri.getValue());
final Attribute digest = getAttributeByName(childElement, nsVersion.asQName(XmlToken.Digest));
PolicyReferenceData refData;
if (digest == null) {
refData = new PolicyReferenceData(reference);
} else {
final Attribute digestAlgorithm = getAttributeByName(childElement, nsVersion.asQName(XmlToken.DigestAlgorithm));
URI algorithmRef = null;
if (digestAlgorithm != null) {
algorithmRef = new URI(digestAlgorithm.getValue());
}
refData = new PolicyReferenceData(reference, digest.getValue(), algorithmRef);
}
childNode = parentNode.createChildPolicyReferenceNode(refData);
} catch (URISyntaxException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0012_UNABLE_TO_UNMARSHALL_POLICY_MALFORMED_URI(), e));
}
}
break;
default:
if (parentNode.isDomainSpecific()) {
childNode = parentNode.createChildAssertionParameterNode();
} else {
childNode = parentNode.createChildAssertionNode();
}
}
}
return childNode;
}
private void parseAssertionData(NamespaceVersion nsVersion, String value, ModelNode childNode, final StartElement childElement) throws IllegalArgumentException, PolicyException {
// finish assertion node processing: create and set assertion data...
final Map<QName, String> attributeMap = new HashMap<QName, String>();
boolean optional = false;
boolean ignorable = false;
final Iterator iterator = childElement.getAttributes();
while (iterator.hasNext()) {
final Attribute nextAttribute = (Attribute) iterator.next();
final QName name = nextAttribute.getName();
if (attributeMap.containsKey(name)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0059_MULTIPLE_ATTRS_WITH_SAME_NAME_DETECTED_FOR_ASSERTION(nextAttribute.getName(), childElement.getName())));
} else {
if (nsVersion.asQName(XmlToken.Optional).equals(name)) {
optional = parseBooleanValue(nextAttribute.getValue());
} else if (nsVersion.asQName(XmlToken.Ignorable).equals(name)) {
ignorable = parseBooleanValue(nextAttribute.getValue());
} else {
attributeMap.put(name, nextAttribute.getValue());
}
}
}
final AssertionData nodeData = new AssertionData(childElement.getName(), value, attributeMap, childNode.getType(), optional, ignorable);
// check visibility value syntax if present...
if (nodeData.containsAttribute(PolicyConstants.VISIBILITY_ATTRIBUTE)) {
final String visibilityValue = nodeData.getAttributeValue(PolicyConstants.VISIBILITY_ATTRIBUTE);
if (!PolicyConstants.VISIBILITY_VALUE_PRIVATE.equals(visibilityValue)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0004_UNEXPECTED_VISIBILITY_ATTR_VALUE(visibilityValue)));
}
}
childNode.setOrReplaceNodeData(nodeData);
}
private Attribute getAttributeByName(final StartElement element,
final QName attributeName) {
// call standard API method to retrieve the attribute by name
Attribute attribute = element.getAttributeByName(attributeName);
// try to find the attribute without a prefix.
if (attribute == null) {
final String localAttributeName = attributeName.getLocalPart();
final Iterator iterator = element.getAttributes();
while (iterator.hasNext()) {
final Attribute nextAttribute = (Attribute) iterator.next();
final QName aName = nextAttribute.getName();
final boolean attributeFoundByWorkaround = aName.equals(attributeName) || (aName.getLocalPart().equals(localAttributeName) && (aName.getPrefix() == null || "".equals(aName.getPrefix())));
if (attributeFoundByWorkaround) {
attribute = nextAttribute;
break;
}
}
}
return attribute;
}
private String unmarshalNodeContent(final NamespaceVersion nsVersion, final ModelNode node, final QName nodeElementName, final XMLEventReader reader) throws PolicyException {
StringBuilder valueBuffer = null;
loop:
while (reader.hasNext()) {
try {
final XMLEvent xmlParserEvent = reader.nextEvent();
switch (xmlParserEvent.getEventType()) {
case XMLStreamConstants.COMMENT:
break; // skipping the comments
case XMLStreamConstants.CHARACTERS:
valueBuffer = processCharacters(node.getType(), xmlParserEvent.asCharacters(), valueBuffer);
break;
case XMLStreamConstants.END_ELEMENT:
checkEndTagName(nodeElementName, xmlParserEvent.asEndElement());
break loop; // data exctraction for currently processed policy node is done
case XMLStreamConstants.START_ELEMENT:
final StartElement childElement = xmlParserEvent.asStartElement();
ModelNode childNode = addNewChildNode(nsVersion, node, childElement);
String value = unmarshalNodeContent(nsVersion, childNode, childElement.getName(), reader);
if (childNode.isDomainSpecific()) {
parseAssertionData(nsVersion, value, childNode, childElement);
}
break;
default:
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0011_UNABLE_TO_UNMARSHALL_POLICY_XML_ELEM_EXPECTED()));
}
} catch (XMLStreamException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0068_FAILED_TO_UNMARSHALL_POLICY_EXPRESSION(), e));
}
}
return (valueBuffer == null) ? null : valueBuffer.toString().trim();
}
/**
* Method checks if the storage type is supported and transforms it to XMLEventReader instance which is then returned.
* Throws PolicyException if the transformation is not succesfull or if the storage type is not supported.
*
* @param storage An XMLEventReader instance.
* @return The storage cast to an XMLEventReader.
* @throws PolicyException If the XMLEventReader cast failed.
*/
private XMLEventReader createXMLEventReader(final Object storage)
throws PolicyException {
if (storage instanceof XMLEventReader) {
return (XMLEventReader) storage;
}
else if (!(storage instanceof Reader)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0022_STORAGE_TYPE_NOT_SUPPORTED(storage.getClass().getName())));
}
try {
return XMLInputFactory.newInstance().createXMLEventReader((Reader) storage);
} catch (XMLStreamException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0014_UNABLE_TO_INSTANTIATE_READER_FOR_STORAGE(), e));
}
}
/**
* Method checks whether the actual name of the end tag is equal to the expected name - the name of currently unmarshalled
* XML policy model element. Throws exception, if the two FQNs are not equal as expected.
*
* @param expected The expected element name.
* @param element The actual element.
* @throws PolicyException If the actual element name did not match the expected element.
*/
private void checkEndTagName(final QName expected, final EndElement element) throws PolicyException {
final QName actual = element.getName();
if (!expected.equals(actual)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0003_UNMARSHALLING_FAILED_END_TAG_DOES_NOT_MATCH(expected, actual)));
}
}
private StringBuilder processCharacters(final ModelNode.Type currentNodeType, final Characters characters,
final StringBuilder currentValueBuffer)
throws PolicyException {
if (characters.isWhiteSpace()) {
return currentValueBuffer;
} else {
final StringBuilder buffer = (currentValueBuffer == null) ? new StringBuilder() : currentValueBuffer;
final String data = characters.getData();
if (currentNodeType == ModelNode.Type.ASSERTION || currentNodeType == ModelNode.Type.ASSERTION_PARAMETER_NODE) {
return buffer.append(data);
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0009_UNEXPECTED_CDATA_ON_SOURCE_MODEL_NODE(currentNodeType, data)));
}
}
}
/**
* Return true if the value is "true" or "1". Return false if the value is
* "false" or "0". Throw an exception otherwise. The test is case sensitive.
*
* @param value The String representation of the value. Must not be null.
* @return True if the value is "true" or "1". False if the value is
* "false" or "0".
* @throws PolicyException If the value is not "true", "false", "0" or "1".
*/
private boolean parseBooleanValue(String value) throws PolicyException {
if ("true".equals(value) || "1".equals(value)) {
return true;
}
else if ("false".equals(value) || "0".equals(value)) {
return false;
}
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0095_INVALID_BOOLEAN_VALUE(value)));
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel.attach;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.WeakHashMap;
/**
* Simple utility ensuring that the value is cached only in case it is non-internal implementation
*/
abstract class ContextClassloaderLocal<V> {
private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE";
private WeakHashMap<ClassLoader, V> CACHE = new WeakHashMap<ClassLoader, V>();
public V get() throws Error {
ClassLoader tccl = getContextClassLoader();
V instance = CACHE.get(tccl);
if (instance == null) {
instance = createNewInstance();
CACHE.put(tccl, instance);
}
return instance;
}
public void set(V instance) {
CACHE.put(getContextClassLoader(), instance);
}
protected abstract V initialValue() throws Exception;
private V createNewInstance() {
try {
return initialValue();
} catch (Exception e) {
throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e);
}
}
private static String format(String property, Object... args) {
String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property);
return MessageFormat.format(text, args);
}
private static ClassLoader getContextClassLoader() {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (SecurityException ex) {
}
return cl;
}
});
}
}

View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel.attach;
import com.sun.xml.internal.ws.policy.Policy;
import com.sun.xml.internal.ws.policy.PolicyConstants;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicyModelTranslator;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicyModelUnmarshaller;
import com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
/**
* Unmarshal external policy attachments.
*
* @author Fabian Ritzmann
*/
public class ExternalAttachmentsUnmarshaller {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(ExternalAttachmentsUnmarshaller.class);
public static final URI BINDING_ID;
public static final URI BINDING_OPERATION_ID;
public static final URI BINDING_OPERATION_INPUT_ID;
public static final URI BINDING_OPERATION_OUTPUT_ID;
public static final URI BINDING_OPERATION_FAULT_ID;
static {
try {
BINDING_ID = new URI("urn:uuid:c9bef600-0d7a-11de-abc1-0002a5d5c51b");
BINDING_OPERATION_ID = new URI("urn:uuid:62e66b60-0d7b-11de-a1a2-0002a5d5c51b");
BINDING_OPERATION_INPUT_ID = new URI("urn:uuid:730d8d20-0d7b-11de-84e9-0002a5d5c51b");
BINDING_OPERATION_OUTPUT_ID = new URI("urn:uuid:85b0f980-0d7b-11de-8e9d-0002a5d5c51b");
BINDING_OPERATION_FAULT_ID = new URI("urn:uuid:917cb060-0d7b-11de-9e80-0002a5d5c51b");
} catch (URISyntaxException e) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0094_INVALID_URN()), e);
}
}
private static final QName POLICY_ATTACHMENT = new QName("http://www.w3.org/ns/ws-policy", "PolicyAttachment");
private static final QName APPLIES_TO = new QName("http://www.w3.org/ns/ws-policy", "AppliesTo");
private static final QName POLICY = new QName("http://www.w3.org/ns/ws-policy", "Policy");
private static final QName URI = new QName("http://www.w3.org/ns/ws-policy", "URI");
private static final QName POLICIES = new QName(PolicyConstants.SUN_MANAGEMENT_NAMESPACE, "Policies");
private static final ContextClassloaderLocal<XMLInputFactory> XML_INPUT_FACTORY = new ContextClassloaderLocal<XMLInputFactory>() {
@Override
protected XMLInputFactory initialValue() throws Exception {
return XMLInputFactory.newInstance();
}
};
private static final PolicyModelUnmarshaller POLICY_UNMARSHALLER = PolicyModelUnmarshaller.getXmlUnmarshaller();
private final Map<URI, Policy> map = new HashMap<URI, Policy>();
private URI currentUri = null;
private Policy currentPolicy = null;
public static Map<URI, Policy> unmarshal(final Reader source) throws PolicyException {
LOGGER.entering(source);
try {
XMLEventReader reader = XML_INPUT_FACTORY.get().createXMLEventReader(source);
ExternalAttachmentsUnmarshaller instance = new ExternalAttachmentsUnmarshaller();
final Map<URI, Policy> map = instance.unmarshal(reader, null);
LOGGER.exiting(map);
return Collections.unmodifiableMap(map);
} catch (XMLStreamException ex) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0086_FAILED_CREATE_READER(source)), ex);
}
}
private Map<URI, Policy> unmarshal(final XMLEventReader reader, final StartElement parentElement) throws PolicyException {
XMLEvent event = null;
while (reader.hasNext()) {
try {
event = reader.peek();
switch (event.getEventType()) {
case XMLStreamConstants.START_DOCUMENT:
case XMLStreamConstants.COMMENT:
reader.nextEvent();
break;
case XMLStreamConstants.CHARACTERS:
processCharacters(event.asCharacters(), parentElement, map);
reader.nextEvent();
break;
case XMLStreamConstants.END_ELEMENT:
processEndTag(event.asEndElement(), parentElement);
reader.nextEvent();
return map;
case XMLStreamConstants.START_ELEMENT:
final StartElement element = event.asStartElement();
processStartTag(element, parentElement, reader, map);
break;
case XMLStreamConstants.END_DOCUMENT:
return map;
default:
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0087_UNKNOWN_EVENT(event)));
}
} catch (XMLStreamException e) {
final Location location = event == null ? null : event.getLocation();
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0088_FAILED_PARSE(location)), e);
}
}
return map;
}
private void processStartTag(final StartElement element, final StartElement parent,
final XMLEventReader reader, final Map<URI, Policy> map)
throws PolicyException {
try {
final QName name = element.getName();
if (parent == null) {
if (!name.equals(POLICIES)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<Policies>", name, element.getLocation())));
}
} else {
final QName parentName = parent.getName();
if (parentName.equals(POLICIES)) {
if (!name.equals(POLICY_ATTACHMENT)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<PolicyAttachment>", name, element.getLocation())));
}
} else if (parentName.equals(POLICY_ATTACHMENT)) {
if (name.equals(POLICY)) {
readPolicy(reader);
return;
} else if (!name.equals(APPLIES_TO)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<AppliesTo> or <Policy>", name, element.getLocation())));
}
} else if (parentName.equals(APPLIES_TO)) {
if (!name.equals(URI)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0089_EXPECTED_ELEMENT("<URI>", name, element.getLocation())));
}
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0090_UNEXPECTED_ELEMENT(name, element.getLocation())));
}
}
reader.nextEvent();
this.unmarshal(reader, element);
} catch (XMLStreamException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0088_FAILED_PARSE(element.getLocation()), e));
}
}
private void readPolicy(final XMLEventReader reader) throws PolicyException {
final PolicySourceModel policyModel = POLICY_UNMARSHALLER.unmarshalModel(reader);
final PolicyModelTranslator translator = PolicyModelTranslator.getTranslator();
final Policy policy = translator.translate(policyModel);
if (this.currentUri != null) {
map.put(this.currentUri, policy);
this.currentUri = null;
this.currentPolicy = null;
}
else {
this.currentPolicy = policy;
}
}
private void processEndTag(EndElement element, StartElement startElement) throws PolicyException {
checkEndTagName(startElement.getName(), element);
}
private void checkEndTagName(final QName expectedName, final EndElement element) throws PolicyException {
final QName actualName = element.getName();
if (!expectedName.equals(actualName)) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0091_END_ELEMENT_NO_MATCH(expectedName, element, element.getLocation())));
}
}
private void processCharacters(final Characters chars, final StartElement currentElement, final Map<URI, Policy> map)
throws PolicyException {
if (chars.isWhiteSpace()) {
return;
}
else {
final String data = chars.getData();
if ((currentElement != null) && URI.equals(currentElement.getName())) {
processUri(chars, map);
return;
} else {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0092_CHARACTER_DATA_UNEXPECTED(currentElement, data, chars.getLocation())));
}
}
}
private void processUri(final Characters chars, final Map<URI, Policy> map) throws PolicyException {
final String data = chars.getData().trim();
try {
final URI uri = new URI(data);
if (this.currentPolicy != null) {
map.put(uri, this.currentPolicy);
this.currentUri = null;
this.currentPolicy = null;
} else {
this.currentUri = uri;
}
} catch (URISyntaxException e) {
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0093_INVALID_URI(data, chars.getLocation())), e);
}
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel.attach;
/**
* Implements utility routines to parse external policy attachments as defined
* by WS-PolicyAttachment.
*/

View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The part of public policy API that defines the classes and interfaces dealing with
* the policy tree structure (policy source model) creation and manipulation.
*/
package com.sun.xml.internal.ws.policy.sourcemodel;

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel.wspolicy;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
/**
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public enum NamespaceVersion {
v1_2("http://schemas.xmlsoap.org/ws/2004/09/policy", "wsp1_2", new XmlToken[] {
XmlToken.Policy,
XmlToken.ExactlyOne,
XmlToken.All,
XmlToken.PolicyReference,
XmlToken.UsingPolicy,
XmlToken.Name,
XmlToken.Optional,
XmlToken.Ignorable,
XmlToken.PolicyUris,
XmlToken.Uri,
XmlToken.Digest,
XmlToken.DigestAlgorithm
}),
v1_5("http://www.w3.org/ns/ws-policy", "wsp", new XmlToken[] {
XmlToken.Policy,
XmlToken.ExactlyOne,
XmlToken.All,
XmlToken.PolicyReference,
XmlToken.UsingPolicy,
XmlToken.Name,
XmlToken.Optional,
XmlToken.Ignorable,
XmlToken.PolicyUris,
XmlToken.Uri,
XmlToken.Digest,
XmlToken.DigestAlgorithm
});
/**
* Resolves URI represented as a String into an enumeration value. If the URI
* doesn't represent any existing enumeration value, method returns
* {@code null}.
*
* @param uri WS-Policy namespace URI
* @return Enumeration value that represents given URI or {@code null} if
* no enumeration value exists for given URI.
*/
public static NamespaceVersion resolveVersion(String uri) {
for (NamespaceVersion namespaceVersion : NamespaceVersion.values()) {
if (namespaceVersion.toString().equalsIgnoreCase(uri)) {
return namespaceVersion;
}
}
return null;
}
/**
* Resolves fully qualified name defined in the WS-Policy namespace into an
* enumeration value. If the URI in the name doesn't represent any existing
* enumeration value, method returns {@code null}
*
* @param name fully qualified name defined in the WS-Policy namespace
* @return Enumeration value that represents given namespace or {@code null} if
* no enumeration value exists for given namespace.
*/
public static NamespaceVersion resolveVersion(QName name) {
return resolveVersion(name.getNamespaceURI());
}
/**
* Returns latest supported version of the policy namespace
*
* @return latest supported policy namespace version.
*/
public static NamespaceVersion getLatestVersion() {
return v1_5;
}
/**
* Resolves FQN into a policy XML token. The version of the token can be determined
* by invoking {@link #resolveVersion(QName)}.
*
* @param name fully qualified name defined in the WS-Policy namespace
* @return XML token enumeration that represents this fully qualified name.
* If the token or the namespace is not resolved {@link XmlToken#UNKNOWN} value
* is returned.
*/
public static XmlToken resolveAsToken(QName name) {
NamespaceVersion nsVersion = resolveVersion(name);
if (nsVersion != null) {
XmlToken token = XmlToken.resolveToken(name.getLocalPart());
if (nsVersion.tokenToQNameCache.containsKey(token)) {
return token;
}
}
return XmlToken.UNKNOWN;
}
private final String nsUri;
private final String defaultNsPrefix;
private final Map<XmlToken, QName> tokenToQNameCache;
private NamespaceVersion(String uri, String prefix, XmlToken... supportedTokens) {
nsUri = uri;
defaultNsPrefix = prefix;
Map<XmlToken, QName> temp = new HashMap<XmlToken, QName>();
for (XmlToken token : supportedTokens) {
temp.put(token, new QName(nsUri, token.toString()));
}
tokenToQNameCache = Collections.unmodifiableMap(temp);
}
/**
* Method returns default namespace prefix for given namespace version.
*
* @return default namespace prefix for given namespace version
*/
public String getDefaultNamespacePrefix() {
return defaultNsPrefix;
}
/**
* Resolves XML token into a fully qualified name within given namespace version.
*
* @param token XML token enumeration value.
* @return fully qualified name of the {@code token} within given namespace
* version. Method returns {@code null} in case the token is not supported in
* given namespace version or in case {@link XmlToken#UNKNOWN} was used as
* an input parameter.
*/
public QName asQName(XmlToken token) throws IllegalArgumentException {
return tokenToQNameCache.get(token);
}
@Override
public String toString() {
return nsUri;
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.sourcemodel.wspolicy;
/**
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public enum XmlToken {
Policy("Policy", true),
ExactlyOne("ExactlyOne", true),
All("All", true),
PolicyReference("PolicyReference", true),
UsingPolicy("UsingPolicy", true),
Name("Name", false),
Optional("Optional", false),
Ignorable("Ignorable", false),
PolicyUris("PolicyURIs", false),
Uri("URI", false),
Digest("Digest", false),
DigestAlgorithm("DigestAlgorithm", false),
UNKNOWN("", true);
/**
* Resolves URI represented as a String into an enumeration value. If the URI
* doesn't represent any existing enumeration value, method returns {@code null}
*
* @param uri
* @return Enumeration value that represents given URI or {@code null} if
* no enumeration value exists for given URI.
*/
public static XmlToken resolveToken(String name) {
for (XmlToken token : XmlToken.values()) {
if (token.toString().equals(name)) {
return token;
}
}
return UNKNOWN;
}
private String tokenName;
private boolean element;
private XmlToken(final String name, boolean element) {
this.tokenName = name;
this.element = element;
}
public boolean isElement() {
return element;
}
@Override
public String toString() {
return tokenName;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.spi;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
/**
* This abstract policy assertion validator validates assertions by their qualified
* name. Server and client side validation methods return {@link Fitness} based on
* following schema:
*
* <ul>
* <li>{@link Fitness#SUPPORTED} - if the assertion qualified name is in the list of
* supported assertion names on the server/client side</li>
* <li>{@link Fitness#UNSUPPORTED} - if the assertion qualified name is not in the list of
* supported assertion names on the server/client side, however it is in the list of
* assertion names supported on the other side</li>
* <li>{@link Fitness#UNKNOWN} - if the assertion qualified name is not present in the any of
* the lists of supported assertion names</li>
* </ul>
*
* For some domains such validation may be sufficient enough. Other domains may
* use functionality of this base class as a first step validation before any attempts
* to validate content of the assertion. To do this one needs to override and reuse
* the default behavior of {@link #validateClientSide(PolicyAssertion)} and
* {@link #validateServerSide(PolicyAssertion)} methods.
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public abstract class AbstractQNameValidator implements PolicyAssertionValidator {
private final Set<String> supportedDomains = new HashSet<String>();
private final Collection<QName> serverAssertions;
private final Collection<QName> clientAssertions;
/**
* Constructor that takes two collections specifying qualified names of assertions
* supported on either server or client side. The set of all assertion namespaces
* defines list of all domains supported by the assertion validator
* (see {@link PolicyAssertionValidator#declareSupportedDomains}).
*
* @param serverSideAssertions The server-side assertions.
* @param clientSideAssertions The client-side assertions.
*/
protected AbstractQNameValidator(Collection<QName> serverSideAssertions, Collection<QName> clientSideAssertions) {
if (serverSideAssertions != null) {
this.serverAssertions = new HashSet<QName>(serverSideAssertions);
for (QName assertion : this.serverAssertions) {
supportedDomains.add(assertion.getNamespaceURI());
}
} else {
this.serverAssertions = new HashSet<QName>(0);
}
if (clientSideAssertions != null) {
this.clientAssertions = new HashSet<QName>(clientSideAssertions);
for (QName assertion : this.clientAssertions) {
supportedDomains.add(assertion.getNamespaceURI());
}
} else {
this.clientAssertions = new HashSet<QName>(0);
}
}
public String[] declareSupportedDomains() {
return supportedDomains.toArray(new String[supportedDomains.size()]);
}
public Fitness validateClientSide(PolicyAssertion assertion) {
return validateAssertion(assertion, clientAssertions, serverAssertions);
}
public Fitness validateServerSide(PolicyAssertion assertion) {
return validateAssertion(assertion, serverAssertions, clientAssertions);
}
private Fitness validateAssertion(PolicyAssertion assertion, Collection<QName> thisSideAssertions, Collection<QName> otherSideAssertions) {
QName assertionName = assertion.getName();
if (thisSideAssertions.contains(assertionName)) {
return Fitness.SUPPORTED;
} else if (otherSideAssertions.contains(assertionName)) {
return Fitness.UNSUPPORTED;
} else {
return Fitness.UNKNOWN;
}
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.spi;
import com.sun.xml.internal.ws.policy.PolicyException;
import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
/**
* Exception thrown in case of assertion creation failure.
*
* @author Marek Potociar
*/
public final class AssertionCreationException extends PolicyException {
private final AssertionData assertionData;
/**
* Constructs a new assertion creation exception with the specified detail message and cause.
* <p/>
* Note that the detail message associated with {@code cause} is <emph>not</emph> automatically incorporated in
* this exception's detail message.
*
* @param assertionData the data provided for assertion creation
* @param message the detail message.
*/
public AssertionCreationException(final AssertionData assertionData, final String message) {
super(message);
this.assertionData = assertionData;
}
/**
* Constructs a new assertion creation exception with the specified detail message and cause.
* <p/>
* Note that the detail message associated with {@code cause} is <emph>not</emph> automatically incorporated in
* this exception's detail message.
*
* @param assertionData the data provided for assertion creation
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.)
*/
public AssertionCreationException(final AssertionData assertionData, final String message, final Throwable cause) {
super(message, cause);
this.assertionData = assertionData;
}
/**
* Constructs a new assertion creation exception with the specified detail message and cause.
*
* @param assertionData the data provided for assertion creation
* @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.)
*/
public AssertionCreationException(AssertionData assertionData, Throwable cause) {
super(cause);
this.assertionData = assertionData;
}
/**
* Retrieves assertion data associated with the exception.
*
* @return associated assertion data (present when assertion creation failed raising this exception).
*/
public AssertionData getAssertionData() {
return this.assertionData;
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.spi;
import com.sun.xml.internal.ws.policy.AssertionSet;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
import java.util.Collection;
/**
* The interface defines contract for custom (domain specific) policy assertion
* factories. The implementations are discovered using service provider mechanism
* described in the
* <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">J2SE JAR File Specification</a>.
*<p/>
* Every implementation of policy assertion creator is expected to <b>fully</b>
* handle the creation of assertions for the domain (namespace) it claims to
* support by returning the namespace string from the {link #getSupportedDomainNamespaceUri()}
* method. To handle creation of domain-specific assertions that are not intended
* to be customized, the default policy assertion creator (passed as one of the
* input parameters into the {@link #createAssertion(AssertionData, Collection, AssertionSet, PolicyAssertionCreator)} method)
* shall be used.
*
* @author Marek Potociar
*/
public interface PolicyAssertionCreator {
/**
* This method returns the namespace URIs of the domains that are supported by the implementation of
* this inteface. There can be multiple URIs supported per single implementation.
* <p/>
* Supporting domain namespace URI means that particular {@code PolicyAssertionCreator} implementation
* is able to create assertion instances for the domains identified by the namespace URIs returned from this
* method. It is required that each {@code PolicyAssertionCreator} implementation handles the policy
* assertion creation for <b>each</b> assertion in every domain it claims to support.
*
* @return string array representing the namespace URIs of the supported domains. It is expected that multiple calls on this method return the
* same value each time. <b>Returned string array must be neither {@code null} nor empty. Also each string value in the array must not be {@code null}
* nor empty.</b>
*
*/
String[] getSupportedDomainNamespaceURIs();
/**
* Creates domain-specific policy assertion instance according to assertion data provided. For the provided
* assertion data and this policy assertion creator instance, it will allways be true that assertion namespace
* URI equals to one of supported domain namespace URIs.
*<p/>
* Additional method parameter (which must not be {@code null}) supplied by the policy framework specifies a default policy
* assertion creator that might be used to handle creation of unsupported domain assertion in the default way. This is
* to give policy assertion creator a chance to handle also creation of "unsupported" domain assertions and to encourage
* implemetors to use class composition instad of class inheritance.
*
* @param data assertion creation data specifying the details of newly created assertion
* @param assertionParameters collection of assertions parameters of this policy assertion. May be {@code null}.
* @param nestedAlternative assertion set specifying nested policy alternative. May be {@code null}.
* @param defaultCreator default policy assertion creator implementation that shall be used to handle creation of assertions
* which are not explicitly supported by this policy assertion creator implementation
* @return domain specific policy assertion implementation according to assertion data provided.
*
* @throws AssertionCreationException in case of assertion creation failure
*/
PolicyAssertion createAssertion(AssertionData data, Collection<PolicyAssertion> assertionParameters, AssertionSet nestedAlternative, PolicyAssertionCreator defaultCreator) throws AssertionCreationException;
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.spi;
import com.sun.xml.internal.ws.policy.PolicyAssertion;
/**
*
*
* @author Marek Potociar (marek.potociar at sun.com)
*/
public interface PolicyAssertionValidator {
public static enum Fitness {
UNKNOWN,
INVALID,
UNSUPPORTED,
SUPPORTED;
public Fitness combine(Fitness other) {
if (this.compareTo(other) < 0) {
return other;
} else {
return this;
}
}
}
/**
* An implementation of this method must return:
* <ul>
* <li>
* {@code Fitness.UNKNOWN} if the policy assertion type is not recognized
* </li>
* <li>
* {@code Fitness.SUPPORTED} if the policy assertion is supported in the
* client-side context
* </li>
* <li>
* {@code Fitness.UNSUPPORTED} if the policy assertion is recognized however
* it's content is not supported. For each assetion that will be eventually marked with
* this validation value, the policy processor will log a WARNING message however
* an attempt to call the web service will be made.
* </li>
* <li>
* {@code Fitness.INVALID} if the policy assertion is recognized however
* its content (value, parameters, nested assertions) is invalid. For each assetion
* that will be eventually marked with this validation value, the policy processor
* will log a SEVERE error and throw an exception. No further attempts to call
* the web service will be made.
* </li>
* </ul>
*
* @param assertion A policy asssertion (See {@link com.sun.xml.internal.ws.policy.PolicyAssertion PolicyAssertion}).
* May contain nested policies and assertions.
* @return fitness of the {@code assertion} on in the client-side context. Must not be {@code null}.
*/
public Fitness validateClientSide(PolicyAssertion assertion);
/**
* An implementation of this method must return:
* <ul>
* <li>
* {@code Fitness.UNKNOWN} if the policy assertion type is not recognized
* </li>
* <li>
* {@code Fitness.SUPPORTED} if the policy assertion is supported in the
* server-side context
* </li>
* <li>
* {@code Fitness.UNSUPPORTED} if the policy assertion is recognized however
* it's content is not supported.
* </li>
* <li>
* {@code Fitness.INVALID} if the policy assertion is recognized however
* its content (value, parameters, nested assertions) is invalid.
* </li>
* </ul>
*
* For each assetion that will be eventually marked with validation value of
* UNKNOWN, UNSUPPORTED or INVALID, the policy processor will log a SEVERE error
* and throw an exception.
*
* @param assertion A policy asssertion (See {@link com.sun.xml.internal.ws.policy.PolicyAssertion PolicyAssertion}).
* May contain nested policies and assertions.
* @return fitness of the {@code assertion} on in the server-side context. Must not be {@code null}.
*/
public Fitness validateServerSide(PolicyAssertion assertion);
/**
* Each service provider that implements this SPI must make sure to identify all possible domains it supports.
* This operation must be implemented as idempotent (must return same values on multiple calls).
* <p/>
* It is legal for two or more {@code PolicyAssertionValidator}s to support the same domain. In such case,
* the most significant result returned from validation methods will be eventually assigned to the assertion.
* The significance of validation results is as follows (from most to least significant):
* <ol>
* <li>SUPPORTED</li>
* <li>UNSUPPORTED</li>
* <li>INVALID</li>
* <li>UNKNOWN</li>
* </ol>
*
*
* @return {@code String} array holding {@code String} representations of identifiers of all supported domains.
* Usually a domain identifier is represented by a namespace.
*/
public String[] declareSupportedDomains();
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.spi;
import java.util.Map;
/**
* Maps an XML prefix to a namespace.
*
* This class allows policy domains to configure to which XML prefix an XML
* namespace is mapped.
*
* @author Fabian Ritzmann
*/
public interface PrefixMapper {
/**
* Returns a map of XML prefixes to namespaces for the domain.
*
* The keys of the map must be a name for an XML prefix, e.g. "wsrmp". The
* values must be the name of an XML namespace, e.g.
* "http://docs.oasis-open.org/ws-rx/wsrmp/200702".
*
* @return A map of XML prefixes to namespaces for the domain.
*/
Map<String, String> getPrefixMap();
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The package contains policy API extension point definitions.
*/
package com.sun.xml.internal.ws.policy.spi;

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.subject;
import com.sun.xml.internal.ws.policy.PolicyMap;
import com.sun.xml.internal.ws.policy.PolicyMapKey;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import com.sun.xml.internal.ws.policy.subject.WsdlBindingSubject.WsdlMessageType;
import javax.xml.namespace.QName;
/**
* Computes a PolicyMapKey instance for a given WsdlBindingSubject.
*
* @author Fabian Ritzmann
*/
public class PolicyMapKeyConverter {
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyMapKeyConverter.class);
private final QName serviceName;
private final QName portName;
public PolicyMapKeyConverter(QName serviceName, QName portName) {
this.serviceName = serviceName;
this.portName = portName;
}
public PolicyMapKey getPolicyMapKey(final WsdlBindingSubject subject) {
LOGGER.entering(subject);
PolicyMapKey key = null;
if (subject.isBindingSubject()) {
key = PolicyMap.createWsdlEndpointScopeKey(this.serviceName, this.portName);
}
else if (subject.isBindingOperationSubject()) {
key = PolicyMap.createWsdlOperationScopeKey(this.serviceName, this.portName, subject.getName());
}
else if (subject.isBindingMessageSubject()) {
if (subject.getMessageType() == WsdlMessageType.FAULT) {
key = PolicyMap.createWsdlFaultMessageScopeKey(this.serviceName, this.portName,
subject.getParent().getName(), subject.getName());
}
else {
key = PolicyMap.createWsdlMessageScopeKey(this.serviceName, this.portName, subject.getParent().getName());
}
}
LOGGER.exiting(key);
return key;
}
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.xml.internal.ws.policy.subject;
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
import javax.xml.namespace.QName;
/**
* Provides objects for use as WSDL 1.0/1.1 policy subjects.
*
* An instance of this class may represent a wsdl:binding element or a wsdl:binding/operation
* element or a wsdl:binding/operation/message element.
*
* @author Fabian Ritzmann
*/
public class WsdlBindingSubject {
/**
* For message subjects, this needs to be set to one of the values INPUT, OUTPUT
* or FAULT. Any other subject has the message type NO_MESSAGE.
*/
public enum WsdlMessageType {
NO_MESSAGE,
INPUT,
OUTPUT,
FAULT
}
/**
* Identifies the scope to which this subject belongs. See WS-PolicyAttachment
* for an explanation on WSDL scopes.
*
* The SERVICE scope is not actually used and only listed here for completeness
* sake.
*/
public enum WsdlNameScope {
SERVICE,
ENDPOINT,
OPERATION,
MESSAGE
}
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(WsdlBindingSubject.class);
private final QName name;
private final WsdlMessageType messageType;
private final WsdlNameScope nameScope;
private final WsdlBindingSubject parent;
WsdlBindingSubject(final QName name, final WsdlNameScope scope, final WsdlBindingSubject parent) {
this(name, WsdlMessageType.NO_MESSAGE, scope, parent);
}
WsdlBindingSubject(final QName name, final WsdlMessageType messageType, final WsdlNameScope scope, final WsdlBindingSubject parent) {
this.name = name;
this.messageType = messageType;
this.nameScope = scope;
this.parent = parent;
}
public static WsdlBindingSubject createBindingSubject(QName bindingName) {
return new WsdlBindingSubject(bindingName, WsdlNameScope.ENDPOINT, null);
}
public static WsdlBindingSubject createBindingOperationSubject(QName bindingName, QName operationName) {
final WsdlBindingSubject bindingSubject = createBindingSubject(bindingName);
return new WsdlBindingSubject(operationName, WsdlNameScope.OPERATION, bindingSubject);
}
public static WsdlBindingSubject createBindingMessageSubject(QName bindingName, QName operationName, QName messageName, WsdlMessageType messageType) {
if (messageType == null) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0083_MESSAGE_TYPE_NULL()));
}
if (messageType == WsdlMessageType.NO_MESSAGE) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0084_MESSAGE_TYPE_NO_MESSAGE()));
}
if ((messageType == WsdlMessageType.FAULT) && (messageName == null)) {
throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0085_MESSAGE_FAULT_NO_NAME()));
}
final WsdlBindingSubject operationSubject = createBindingOperationSubject(bindingName, operationName);
return new WsdlBindingSubject(messageName, messageType, WsdlNameScope.MESSAGE, operationSubject);
}
public QName getName() {
return this.name;
}
public WsdlMessageType getMessageType() {
return this.messageType;
}
public WsdlBindingSubject getParent() {
return this.parent;
}
public boolean isBindingSubject() {
if (this.nameScope == WsdlNameScope.ENDPOINT) {
return this.parent == null;
}
else {
return false;
}
}
public boolean isBindingOperationSubject() {
if (this.nameScope == WsdlNameScope.OPERATION) {
if (this.parent != null) {
return this.parent.isBindingSubject();
}
}
return false;
}
public boolean isBindingMessageSubject() {
if (this.nameScope == WsdlNameScope.MESSAGE) {
if (this.parent != null) {
return this.parent.isBindingOperationSubject();
}
}
return false;
}
@Override
public boolean equals(final Object that) {
if (this == that) {
return true;
}
if (that == null || !(that instanceof WsdlBindingSubject)) {
return false;
}
final WsdlBindingSubject thatSubject = (WsdlBindingSubject) that;
boolean isEqual = true;
isEqual = isEqual && ((this.name == null) ? thatSubject.name == null : this.name.equals(thatSubject.name));
isEqual = isEqual && this.messageType.equals(thatSubject.messageType);
isEqual = isEqual && this.nameScope.equals(thatSubject.nameScope);
isEqual = isEqual && ((this.parent == null) ? thatSubject.parent == null : this.parent.equals(thatSubject.parent));
return isEqual;
}
@Override
public int hashCode() {
int result = 23;
result = 31 * result + ((this.name == null) ? 0 : this.name.hashCode());
result = 31 * result + this.messageType.hashCode();
result = 31 * result + this.nameScope.hashCode();
result = 31 * result + ((this.parent == null) ? 0 : this.parent.hashCode());
return result;
}
@Override
public String toString() {
final StringBuilder result = new StringBuilder("WsdlBindingSubject[");
result.append(this.name).append(", ").append(this.messageType);
result.append(", ").append(this.nameScope).append(", ").append(this.parent);
return result.append("]").toString();
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Provides utility classes and objects that can serve as policy subjects for
* {@link com.sun.xml.internal.ws.policy.PolicySubject}. The current implementation provides
* subjects for WSDL 1.0/1.1 binding elements.
*
* We are not trying to provide an exact model of WSDL elements. The JAX-WS
* WSDLModel does that already. Instead, we are aiming at providing a light-weight
* and easy to use representation of WSDL elements.
*
* At the same time, this implementation is providing a simple way of mapping the
* subjects to WSDL scopes. That limits how the WsdlSubjects can be used. Ultimately,
* each subject is always linked to one service, port and binding element. That
* means that WsdlSubjects cannot accurately represent e.g. a WSDL message element
* that is referenced by multiple WSDL binding operations.
*/
package com.sun.xml.internal.ws.policy.subject;