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

changeset 0
373ffda63c9a
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
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 */
25
26 package com.sun.xml.internal.ws.policy;
27
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;
36
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 }
47
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);
51
52 private CompatibilityMode mode;
53
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 }
61
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 }
70
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 }
79
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 }
96
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 }
116
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 }
125
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();
132
133 testedAlternatives.clear();
134 testedAlternatives.addAll(finalAlternatives);
135 finalAlternatives.clear();
136
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 }
149
150 return Policy.createPolicy(latestVersion, null, null, finalAlternatives);
151 }
152 }

mercurial