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