src/share/jaxws_classes/com/sun/xml/internal/ws/policy/PolicyIntersector.java

Thu, 12 Oct 2017 19:44:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 19:44:07 +0800
changeset 760
e530533619ec
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.policy;
    28 import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
    29 import java.util.Collection;
    30 import java.util.LinkedList;
    31 import java.util.List;
    32 import java.util.Queue;
    33 import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages;
    34 import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.NamespaceVersion;
    35 import java.util.ArrayList;
    37 /**
    38  * The instance of this class is intended to provide policy intersection mechanism.
    39  *
    40  * @author Marek Potociar (marek.potociar@sun.com)
    41  */
    42 public final class PolicyIntersector {
    43     static enum CompatibilityMode {
    44         STRICT,
    45         LAX
    46     }
    48     private static final PolicyIntersector STRICT_INTERSECTOR = new PolicyIntersector(CompatibilityMode.STRICT);
    49     private static final PolicyIntersector LAX_INTERSECTOR = new PolicyIntersector(CompatibilityMode.LAX);
    50     private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyIntersector.class);
    52     private CompatibilityMode mode;
    54     /**
    55      * Prevents direct instantiation of this class from outside
    56      * @param intersectionMode intersection mode
    57      */
    58     private PolicyIntersector(CompatibilityMode intersectionMode) {
    59         this.mode = intersectionMode;
    60     }
    62     /**
    63      * Returns a strict policy intersector that can be used to intersect group of policies.
    64      *
    65      * @return policy intersector instance.
    66      */
    67     public static PolicyIntersector createStrictPolicyIntersector() {
    68         return PolicyIntersector.STRICT_INTERSECTOR;
    69     }
    71     /**
    72      * Returns a strict policy intersector that can be used to intersect group of policies.
    73      *
    74      * @return policy intersector instance.
    75      */
    76     public static PolicyIntersector createLaxPolicyIntersector() {
    77         return PolicyIntersector.LAX_INTERSECTOR;
    78     }
    80     /**
    81      * Performs intersection on the input collection of policies and returns the resulting (intersected) policy. If input policy
    82      * collection contains only a single policy instance, no intersection is performed and the instance is directly returned
    83      * as a method call result.
    84      *
    85      * @param policies collection of policies to be intersected. Must not be {@code null} nor empty, otherwise exception is thrown.
    86      * @return intersected policy as a result of perfromed policy intersection. A {@code null} value is never returned.
    87      *
    88      * @throws IllegalArgumentException in case {@code policies} argument is either {@code null} or empty collection.
    89      */
    90     public Policy intersect(final Policy... policies) {
    91         if (policies == null || policies.length == 0) {
    92             throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0056_NEITHER_NULL_NOR_EMPTY_POLICY_COLLECTION_EXPECTED()));
    93         } else if (policies.length == 1) {
    94             return policies[0];
    95         }
    97         // check for "null" and "empty" policy: if such policy is found return "null" policy,
    98         // or if all policies are "empty", return "empty" policy
    99         boolean found = false;
   100         boolean allPoliciesEmpty = true;
   101         NamespaceVersion latestVersion = null;
   102         for (Policy tested : policies) {
   103             if (tested.isEmpty()) {
   104                 found = true;
   105             } else {
   106                 if (tested.isNull()) {
   107                     found = true;
   108                 }
   109                 allPoliciesEmpty = false;
   110             }
   111             if (latestVersion == null) {
   112                 latestVersion = tested.getNamespaceVersion();
   113             } else if (latestVersion.compareTo(tested.getNamespaceVersion()) < 0) {
   114                 latestVersion = tested.getNamespaceVersion();
   115             }
   117             if (found && !allPoliciesEmpty) {
   118                 return Policy.createNullPolicy(latestVersion, null, null);
   119             }
   120         }
   121         latestVersion = (latestVersion != null) ? latestVersion : NamespaceVersion.getLatestVersion();
   122         if (allPoliciesEmpty) {
   123             return Policy.createEmptyPolicy(latestVersion, null, null);
   124         }
   126         // simple tests didn't lead to final answer => let's performe some intersecting ;)
   127         final List<AssertionSet> finalAlternatives = new LinkedList<AssertionSet>(policies[0].getContent());
   128         final Queue<AssertionSet> testedAlternatives = new LinkedList<AssertionSet>();
   129         final List<AssertionSet> alternativesToMerge = new ArrayList<AssertionSet>(2);
   130         for (int i = 1; i < policies.length; i++) {
   131             final Collection<AssertionSet> currentAlternatives = policies[i].getContent();
   133             testedAlternatives.clear();
   134             testedAlternatives.addAll(finalAlternatives);
   135             finalAlternatives.clear();
   137             AssertionSet testedAlternative;
   138             while ((testedAlternative = testedAlternatives.poll()) != null) {
   139                 for (AssertionSet currentAlternative : currentAlternatives) {
   140                     if (testedAlternative.isCompatibleWith(currentAlternative, this.mode)) {
   141                         alternativesToMerge.add(testedAlternative);
   142                         alternativesToMerge.add(currentAlternative);
   143                         finalAlternatives.add(AssertionSet.createMergedAssertionSet(alternativesToMerge));
   144                         alternativesToMerge.clear();
   145                     }
   146                 }
   147             }
   148         }
   150         return Policy.createPolicy(latestVersion, null, null, finalAlternatives);
   151     }
   152 }

mercurial