author | mkos |
Sun, 30 Dec 2012 00:00:00 +0100 | |
changeset 22678 | ac1ea46be942 |
parent 12009 | 4abb694f273a |
permissions | -rw-r--r-- |
12009 | 1 |
/* |
22678
ac1ea46be942
8029237: Update copyright year to match last edit in jaxws repository for 2012
mkos
parents:
12009
diff
changeset
|
2 |
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
12009 | 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.sourcemodel; |
|
27 |
||
28 |
import java.util.ArrayList; |
|
29 |
import java.util.Collection; |
|
30 |
import java.util.Collections; |
|
31 |
import java.util.HashMap; |
|
32 |
import java.util.LinkedList; |
|
33 |
import java.util.List; |
|
34 |
import java.util.Map; |
|
35 |
import java.util.Queue; |
|
36 |
||
37 |
import com.sun.xml.internal.ws.policy.AssertionSet; |
|
38 |
import com.sun.xml.internal.ws.policy.Policy; |
|
39 |
import com.sun.xml.internal.ws.policy.PolicyAssertion; |
|
40 |
import com.sun.xml.internal.ws.policy.PolicyException; |
|
41 |
import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages; |
|
42 |
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger; |
|
43 |
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; |
|
44 |
import com.sun.xml.internal.ws.policy.spi.AssertionCreationException; |
|
45 |
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionCreator; |
|
46 |
||
47 |
/** |
|
48 |
* This class provides a method for translating a {@link PolicySourceModel} structure to a normalized {@link Policy} expression. |
|
49 |
* The resulting Policy is disconnected from its model, thus any additional changes in the model will have no effect on the Policy |
|
50 |
* expression. |
|
51 |
* |
|
52 |
* @author Marek Potociar |
|
53 |
* @author Fabian Ritzmann |
|
54 |
*/ |
|
55 |
public class PolicyModelTranslator { |
|
56 |
||
57 |
private static final class ContentDecomposition { |
|
58 |
final List<Collection<ModelNode>> exactlyOneContents = new LinkedList<Collection<ModelNode>>(); |
|
59 |
final List<ModelNode> assertions = new LinkedList<ModelNode>(); |
|
60 |
||
61 |
void reset() { |
|
62 |
exactlyOneContents.clear(); |
|
63 |
assertions.clear(); |
|
64 |
} |
|
65 |
} |
|
66 |
||
67 |
private static final class RawAssertion { |
|
68 |
ModelNode originalNode; // used to initialize nestedPolicy and nestedAssertions in the constructor of RawAlternative |
|
69 |
Collection<RawAlternative> nestedAlternatives = null; |
|
70 |
final Collection<ModelNode> parameters; |
|
71 |
||
72 |
RawAssertion(ModelNode originalNode, Collection<ModelNode> parameters) { |
|
73 |
this.parameters = parameters; |
|
74 |
this.originalNode = originalNode; |
|
75 |
} |
|
76 |
} |
|
77 |
||
78 |
private static final class RawAlternative { |
|
79 |
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyModelTranslator.RawAlternative.class); |
|
80 |
||
81 |
final List<RawPolicy> allNestedPolicies = new LinkedList<RawPolicy>(); // used to track the nested policies which need to be normalized |
|
82 |
final Collection<RawAssertion> nestedAssertions; |
|
83 |
||
84 |
RawAlternative(Collection<ModelNode> assertionNodes) throws PolicyException { |
|
85 |
this.nestedAssertions = new LinkedList<RawAssertion>(); |
|
86 |
for (ModelNode node : assertionNodes) { |
|
87 |
RawAssertion assertion = new RawAssertion(node, new LinkedList<ModelNode>()); |
|
88 |
nestedAssertions.add(assertion); |
|
89 |
||
90 |
for (ModelNode assertionNodeChild : assertion.originalNode.getChildren()) { |
|
91 |
switch (assertionNodeChild.getType()) { |
|
92 |
case ASSERTION_PARAMETER_NODE: |
|
93 |
assertion.parameters.add(assertionNodeChild); |
|
94 |
break; |
|
95 |
case POLICY: |
|
96 |
case POLICY_REFERENCE: |
|
97 |
if (assertion.nestedAlternatives == null) { |
|
98 |
assertion.nestedAlternatives = new LinkedList<RawAlternative>(); |
|
99 |
RawPolicy nestedPolicy; |
|
100 |
if (assertionNodeChild.getType() == ModelNode.Type.POLICY) { |
|
101 |
nestedPolicy = new RawPolicy(assertionNodeChild, assertion.nestedAlternatives); |
|
102 |
} else { |
|
103 |
nestedPolicy = new RawPolicy(getReferencedModelRootNode(assertionNodeChild), assertion.nestedAlternatives); |
|
104 |
} |
|
105 |
this.allNestedPolicies.add(nestedPolicy); |
|
106 |
} else { |
|
107 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0006_UNEXPECTED_MULTIPLE_POLICY_NODES())); |
|
108 |
} |
|
109 |
break; |
|
110 |
default: |
|
111 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0008_UNEXPECTED_CHILD_MODEL_TYPE(assertionNodeChild.getType()))); |
|
112 |
} |
|
113 |
} |
|
114 |
} |
|
115 |
} |
|
116 |
||
117 |
} |
|
118 |
||
119 |
private static final class RawPolicy { |
|
120 |
final Collection<ModelNode> originalContent; |
|
121 |
final Collection<RawAlternative> alternatives; |
|
122 |
||
123 |
RawPolicy(ModelNode policyNode, Collection<RawAlternative> alternatives) { |
|
124 |
originalContent = policyNode.getChildren(); |
|
125 |
this.alternatives = alternatives; |
|
126 |
} |
|
127 |
} |
|
128 |
||
129 |
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(PolicyModelTranslator.class); |
|
130 |
||
131 |
private static final PolicyAssertionCreator defaultCreator = new DefaultPolicyAssertionCreator(); |
|
132 |
||
133 |
private final Map<String, PolicyAssertionCreator> assertionCreators; |
|
134 |
||
135 |
||
136 |
private PolicyModelTranslator() throws PolicyException { |
|
137 |
this(null); |
|
138 |
} |
|
139 |
||
140 |
protected PolicyModelTranslator(final Collection<PolicyAssertionCreator> creators) throws PolicyException { |
|
141 |
LOGGER.entering(creators); |
|
142 |
||
143 |
final Collection<PolicyAssertionCreator> allCreators = new LinkedList<PolicyAssertionCreator>(); |
|
144 |
final PolicyAssertionCreator[] discoveredCreators = PolicyUtils.ServiceProvider.load(PolicyAssertionCreator.class); |
|
145 |
for (PolicyAssertionCreator creator : discoveredCreators) { |
|
146 |
allCreators.add(creator); |
|
147 |
} |
|
148 |
if (creators != null) { |
|
149 |
for (PolicyAssertionCreator creator : creators) { |
|
150 |
allCreators.add(creator); |
|
151 |
} |
|
152 |
} |
|
153 |
||
154 |
final Map<String, PolicyAssertionCreator> pacMap = new HashMap<String, PolicyAssertionCreator>(); |
|
155 |
for (PolicyAssertionCreator creator : allCreators) { |
|
156 |
final String[] supportedURIs = creator.getSupportedDomainNamespaceURIs(); |
|
157 |
final String creatorClassName = creator.getClass().getName(); |
|
158 |
||
159 |
if (supportedURIs == null || supportedURIs.length == 0) { |
|
160 |
LOGGER.warning(LocalizationMessages.WSP_0077_ASSERTION_CREATOR_DOES_NOT_SUPPORT_ANY_URI(creatorClassName)); |
|
161 |
continue; |
|
162 |
} |
|
163 |
||
164 |
for (String supportedURI : supportedURIs) { |
|
165 |
LOGGER.config(LocalizationMessages.WSP_0078_ASSERTION_CREATOR_DISCOVERED(creatorClassName, supportedURI)); |
|
166 |
if (supportedURI == null || supportedURI.length() == 0) { |
|
167 |
throw LOGGER.logSevereException(new PolicyException( |
|
168 |
LocalizationMessages.WSP_0070_ERROR_REGISTERING_ASSERTION_CREATOR(creatorClassName))); |
|
169 |
} |
|
170 |
||
171 |
final PolicyAssertionCreator oldCreator = pacMap.put(supportedURI, creator); |
|
172 |
if (oldCreator != null) { |
|
173 |
throw LOGGER.logSevereException(new PolicyException( |
|
174 |
LocalizationMessages.WSP_0071_ERROR_MULTIPLE_ASSERTION_CREATORS_FOR_NAMESPACE( |
|
175 |
supportedURI, oldCreator.getClass().getName(), creator.getClass().getName()))); |
|
176 |
} |
|
177 |
} |
|
178 |
} |
|
179 |
||
180 |
this.assertionCreators = Collections.unmodifiableMap(pacMap); |
|
181 |
LOGGER.exiting(); |
|
182 |
} |
|
183 |
||
184 |
/** |
|
185 |
* Method returns thread-safe policy model translator instance. |
|
186 |
* |
|
187 |
* This method is only intended to be used by code that has no dependencies on |
|
188 |
* JAX-WS. Otherwise use com.sun.xml.internal.ws.policy.api.ModelTranslator. |
|
189 |
* |
|
190 |
* @return A policy model translator instance. |
|
191 |
* @throws PolicyException If instantiating a PolicyAssertionCreator failed. |
|
192 |
*/ |
|
193 |
public static PolicyModelTranslator getTranslator() throws PolicyException { |
|
194 |
return new PolicyModelTranslator(); |
|
195 |
} |
|
196 |
||
197 |
/** |
|
198 |
* The method translates {@link PolicySourceModel} structure into normalized {@link Policy} expression. The resulting Policy |
|
199 |
* is disconnected from its model, thus any additional changes in model will have no effect on the Policy expression. |
|
200 |
* |
|
201 |
* @param model the model to be translated into normalized policy expression. Must not be {@code null}. |
|
202 |
* @return translated policy expression in it's normalized form. |
|
203 |
* @throws PolicyException in case of translation failure |
|
204 |
*/ |
|
205 |
public Policy translate(final PolicySourceModel model) throws PolicyException { |
|
206 |
LOGGER.entering(model); |
|
207 |
||
208 |
if (model == null) { |
|
209 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0043_POLICY_MODEL_TRANSLATION_ERROR_INPUT_PARAM_NULL())); |
|
210 |
} |
|
211 |
||
212 |
PolicySourceModel localPolicyModelCopy; |
|
213 |
try { |
|
214 |
localPolicyModelCopy = model.clone(); |
|
215 |
} catch (CloneNotSupportedException e) { |
|
216 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0016_UNABLE_TO_CLONE_POLICY_SOURCE_MODEL(), e)); |
|
217 |
} |
|
218 |
||
219 |
final String policyId = localPolicyModelCopy.getPolicyId(); |
|
220 |
final String policyName = localPolicyModelCopy.getPolicyName(); |
|
221 |
||
222 |
final Collection<AssertionSet> alternatives = createPolicyAlternatives(localPolicyModelCopy); |
|
223 |
LOGGER.finest(LocalizationMessages.WSP_0052_NUMBER_OF_ALTERNATIVE_COMBINATIONS_CREATED(alternatives.size())); |
|
224 |
||
225 |
Policy policy = null; |
|
226 |
if (alternatives.size() == 0) { |
|
227 |
policy = Policy.createNullPolicy(model.getNamespaceVersion(), policyName, policyId); |
|
228 |
LOGGER.finest(LocalizationMessages.WSP_0055_NO_ALTERNATIVE_COMBINATIONS_CREATED()); |
|
229 |
} else if (alternatives.size() == 1 && alternatives.iterator().next().isEmpty()) { |
|
230 |
policy = Policy.createEmptyPolicy(model.getNamespaceVersion(), policyName, policyId); |
|
231 |
LOGGER.finest(LocalizationMessages.WSP_0026_SINGLE_EMPTY_ALTERNATIVE_COMBINATION_CREATED()); |
|
232 |
} else { |
|
233 |
policy = Policy.createPolicy(model.getNamespaceVersion(), policyName, policyId, alternatives); |
|
234 |
LOGGER.finest(LocalizationMessages.WSP_0057_N_ALTERNATIVE_COMBINATIONS_M_POLICY_ALTERNATIVES_CREATED(alternatives.size(), policy.getNumberOfAssertionSets())); |
|
235 |
} |
|
236 |
||
237 |
LOGGER.exiting(policy); |
|
238 |
return policy; |
|
239 |
} |
|
240 |
||
241 |
/** |
|
242 |
* Method creates policy alternatives according to provided model. The model structure is modified in the process. |
|
243 |
* |
|
244 |
* @return created policy alternatives resulting from policy source model. |
|
245 |
*/ |
|
246 |
private Collection<AssertionSet> createPolicyAlternatives(final PolicySourceModel model) throws PolicyException { |
|
247 |
// creating global method variables |
|
248 |
final ContentDecomposition decomposition = new ContentDecomposition(); |
|
249 |
||
250 |
// creating processing queue and starting the processing iterations |
|
251 |
final Queue<RawPolicy> policyQueue = new LinkedList<RawPolicy>(); |
|
252 |
final Queue<Collection<ModelNode>> contentQueue = new LinkedList<Collection<ModelNode>>(); |
|
253 |
||
254 |
final RawPolicy rootPolicy = new RawPolicy(model.getRootNode(), new LinkedList<RawAlternative>()); |
|
255 |
RawPolicy processedPolicy = rootPolicy; |
|
256 |
do { |
|
257 |
Collection<ModelNode> processedContent = processedPolicy.originalContent; |
|
258 |
do { |
|
259 |
decompose(processedContent, decomposition); |
|
260 |
if (decomposition.exactlyOneContents.isEmpty()) { |
|
261 |
final RawAlternative alternative = new RawAlternative(decomposition.assertions); |
|
262 |
processedPolicy.alternatives.add(alternative); |
|
263 |
if (!alternative.allNestedPolicies.isEmpty()) { |
|
264 |
policyQueue.addAll(alternative.allNestedPolicies); |
|
265 |
} |
|
266 |
} else { // we have a non-empty collection of exactly ones |
|
267 |
final Collection<Collection<ModelNode>> combinations = PolicyUtils.Collections.combine(decomposition.assertions, decomposition.exactlyOneContents, false); |
|
268 |
if (combinations != null && !combinations.isEmpty()) { |
|
269 |
// processed alternative was split into some new alternatives, which we need to process |
|
270 |
contentQueue.addAll(combinations); |
|
271 |
} |
|
272 |
} |
|
273 |
} while ((processedContent = contentQueue.poll()) != null); |
|
274 |
} while ((processedPolicy = policyQueue.poll()) != null); |
|
275 |
||
276 |
// normalize nested policies to contain single alternative only |
|
277 |
final Collection<AssertionSet> assertionSets = new LinkedList<AssertionSet>(); |
|
278 |
for (RawAlternative rootAlternative : rootPolicy.alternatives) { |
|
279 |
final Collection<AssertionSet> normalizedAlternatives = normalizeRawAlternative(rootAlternative); |
|
280 |
assertionSets.addAll(normalizedAlternatives); |
|
281 |
} |
|
282 |
||
283 |
return assertionSets; |
|
284 |
} |
|
285 |
||
286 |
/** |
|
287 |
* Decomposes the unprocessed alternative content into two different collections: |
|
288 |
* <p/> |
|
289 |
* Content of 'EXACTLY_ONE' child nodes is expanded and placed in one list and |
|
290 |
* 'ASSERTION' nodes are placed into other list. Direct 'ALL' and 'POLICY' child nodes are 'dissolved' in the process. |
|
291 |
* |
|
292 |
* Method reuses precreated ContentDecomposition object, which is reset before reuse. |
|
293 |
*/ |
|
294 |
private void decompose(final Collection<ModelNode> content, final ContentDecomposition decomposition) throws PolicyException { |
|
295 |
decomposition.reset(); |
|
296 |
||
297 |
final Queue<ModelNode> allContentQueue = new LinkedList<ModelNode>(content); |
|
298 |
ModelNode node; |
|
299 |
while ((node = allContentQueue.poll()) != null) { |
|
300 |
// dissolving direct 'POLICY', 'POLICY_REFERENCE' and 'ALL' child nodes |
|
301 |
switch (node.getType()) { |
|
302 |
case POLICY : |
|
303 |
case ALL : |
|
304 |
allContentQueue.addAll(node.getChildren()); |
|
305 |
break; |
|
306 |
case POLICY_REFERENCE : |
|
307 |
allContentQueue.addAll(getReferencedModelRootNode(node).getChildren()); |
|
308 |
break; |
|
309 |
case EXACTLY_ONE : |
|
310 |
decomposition.exactlyOneContents.add(expandsExactlyOneContent(node.getChildren())); |
|
311 |
break; |
|
312 |
case ASSERTION : |
|
313 |
decomposition.assertions.add(node); |
|
314 |
break; |
|
315 |
default : |
|
316 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0007_UNEXPECTED_MODEL_NODE_TYPE_FOUND(node.getType()))); |
|
317 |
} |
|
318 |
} |
|
319 |
} |
|
320 |
||
321 |
private static ModelNode getReferencedModelRootNode(final ModelNode policyReferenceNode) throws PolicyException { |
|
322 |
final PolicySourceModel referencedModel = policyReferenceNode.getReferencedModel(); |
|
323 |
if (referencedModel == null) { |
|
324 |
final PolicyReferenceData refData = policyReferenceNode.getPolicyReferenceData(); |
|
325 |
if (refData == null) { |
|
326 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0041_POLICY_REFERENCE_NODE_FOUND_WITH_NO_POLICY_REFERENCE_IN_IT())); |
|
327 |
} else { |
|
328 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0010_UNEXPANDED_POLICY_REFERENCE_NODE_FOUND_REFERENCING(refData.getReferencedModelUri()))); |
|
329 |
} |
|
330 |
} else { |
|
331 |
return referencedModel.getRootNode(); |
|
332 |
} |
|
333 |
} |
|
334 |
||
335 |
/** |
|
336 |
* Expands content of 'EXACTLY_ONE' node. Direct 'EXACTLY_ONE' child nodes are dissolved in the process. |
|
337 |
*/ |
|
338 |
private Collection<ModelNode> expandsExactlyOneContent(final Collection<ModelNode> content) throws PolicyException { |
|
339 |
final Collection<ModelNode> result = new LinkedList<ModelNode>(); |
|
340 |
||
341 |
final Queue<ModelNode> eoContentQueue = new LinkedList<ModelNode>(content); |
|
342 |
ModelNode node; |
|
343 |
while ((node = eoContentQueue.poll()) != null) { |
|
344 |
// dissolving direct 'EXACTLY_ONE' child nodes |
|
345 |
switch (node.getType()) { |
|
346 |
case POLICY : |
|
347 |
case ALL : |
|
348 |
case ASSERTION : |
|
349 |
result.add(node); |
|
350 |
break; |
|
351 |
case POLICY_REFERENCE : |
|
352 |
result.add(getReferencedModelRootNode(node)); |
|
353 |
break; |
|
354 |
case EXACTLY_ONE : |
|
355 |
eoContentQueue.addAll(node.getChildren()); |
|
356 |
break; |
|
357 |
default : |
|
358 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0001_UNSUPPORTED_MODEL_NODE_TYPE(node.getType()))); |
|
359 |
} |
|
360 |
} |
|
361 |
||
362 |
return result; |
|
363 |
} |
|
364 |
||
365 |
private List<AssertionSet> normalizeRawAlternative(final RawAlternative alternative) throws AssertionCreationException, PolicyException { |
|
366 |
final List<PolicyAssertion> normalizedContentBase = new LinkedList<PolicyAssertion>(); |
|
367 |
final Collection<List<PolicyAssertion>> normalizedContentOptions = new LinkedList<List<PolicyAssertion>>(); |
|
368 |
if (!alternative.nestedAssertions.isEmpty()) { |
|
369 |
final Queue<RawAssertion> nestedAssertionsQueue = new LinkedList<RawAssertion>(alternative.nestedAssertions); |
|
370 |
RawAssertion rawAssertion; |
|
371 |
while((rawAssertion = nestedAssertionsQueue.poll()) != null) { |
|
372 |
final List<PolicyAssertion> normalized = normalizeRawAssertion(rawAssertion); |
|
373 |
// if there is only a single result, we can add it direclty to the content base collection |
|
374 |
// more elements in the result indicate that we will have to create combinations |
|
375 |
if (normalized.size() == 1) { |
|
376 |
normalizedContentBase.addAll(normalized); |
|
377 |
} else { |
|
378 |
normalizedContentOptions.add(normalized); |
|
379 |
} |
|
380 |
} |
|
381 |
} |
|
382 |
||
383 |
final List<AssertionSet> options = new LinkedList<AssertionSet>(); |
|
384 |
if (normalizedContentOptions.isEmpty()) { |
|
385 |
// we do not have any options to combine => returning this assertion |
|
386 |
options.add(AssertionSet.createAssertionSet(normalizedContentBase)); |
|
387 |
} else { |
|
388 |
// we have some options to combine => creating assertion options based on content combinations |
|
389 |
final Collection<Collection<PolicyAssertion>> contentCombinations = PolicyUtils.Collections.combine(normalizedContentBase, normalizedContentOptions, true); |
|
390 |
for (Collection<PolicyAssertion> contentOption : contentCombinations) { |
|
391 |
options.add(AssertionSet.createAssertionSet(contentOption)); |
|
392 |
} |
|
393 |
} |
|
394 |
return options; |
|
395 |
} |
|
396 |
||
397 |
private List<PolicyAssertion> normalizeRawAssertion(final RawAssertion assertion) throws AssertionCreationException, PolicyException { |
|
398 |
List<PolicyAssertion> parameters; |
|
399 |
if (assertion.parameters.isEmpty()) { |
|
400 |
parameters = null; |
|
401 |
} else { |
|
402 |
parameters = new ArrayList<PolicyAssertion>(assertion.parameters.size()); |
|
403 |
for (ModelNode parameterNode : assertion.parameters) { |
|
404 |
parameters.add(createPolicyAssertionParameter(parameterNode)); |
|
405 |
} |
|
406 |
} |
|
407 |
||
408 |
final List<AssertionSet> nestedAlternatives = new LinkedList<AssertionSet>(); |
|
409 |
if (assertion.nestedAlternatives != null && !assertion.nestedAlternatives.isEmpty()) { |
|
410 |
final Queue<RawAlternative> nestedAlternativeQueue = new LinkedList<RawAlternative>(assertion.nestedAlternatives); |
|
411 |
RawAlternative rawAlternative; |
|
412 |
while((rawAlternative = nestedAlternativeQueue.poll()) != null) { |
|
413 |
nestedAlternatives.addAll(normalizeRawAlternative(rawAlternative)); |
|
414 |
} |
|
415 |
// if there is only a single result, we can add it direclty to the content base collection |
|
416 |
// more elements in the result indicate that we will have to create combinations |
|
417 |
} |
|
418 |
||
419 |
final List<PolicyAssertion> assertionOptions = new LinkedList<PolicyAssertion>(); |
|
420 |
final boolean nestedAlternativesAvailable = !nestedAlternatives.isEmpty(); |
|
421 |
if (nestedAlternativesAvailable) { |
|
422 |
for (AssertionSet nestedAlternative : nestedAlternatives) { |
|
423 |
assertionOptions.add(createPolicyAssertion(assertion.originalNode.getNodeData(), parameters, nestedAlternative)); |
|
424 |
} |
|
425 |
} else { |
|
426 |
assertionOptions.add(createPolicyAssertion(assertion.originalNode.getNodeData(), parameters, null)); |
|
427 |
} |
|
428 |
return assertionOptions; |
|
429 |
} |
|
430 |
||
431 |
private PolicyAssertion createPolicyAssertionParameter(final ModelNode parameterNode) throws AssertionCreationException, PolicyException { |
|
432 |
if (parameterNode.getType() != ModelNode.Type.ASSERTION_PARAMETER_NODE) { |
|
433 |
throw LOGGER.logSevereException(new PolicyException(LocalizationMessages.WSP_0065_INCONSISTENCY_IN_POLICY_SOURCE_MODEL(parameterNode.getType()))); |
|
434 |
} |
|
435 |
||
436 |
List<PolicyAssertion> childParameters = null; |
|
437 |
if (parameterNode.hasChildren()) { |
|
438 |
childParameters = new ArrayList<PolicyAssertion>(parameterNode.childrenSize()); |
|
439 |
for (ModelNode childParameterNode : parameterNode) { |
|
440 |
childParameters.add(createPolicyAssertionParameter(childParameterNode)); |
|
441 |
} |
|
442 |
} |
|
443 |
||
444 |
return createPolicyAssertion(parameterNode.getNodeData(), childParameters, null /* parameters do not have any nested alternatives */); |
|
445 |
} |
|
446 |
||
447 |
private PolicyAssertion createPolicyAssertion(final AssertionData data, final Collection<PolicyAssertion> assertionParameters, final AssertionSet nestedAlternative) throws AssertionCreationException { |
|
448 |
final String assertionNamespace = data.getName().getNamespaceURI(); |
|
449 |
final PolicyAssertionCreator domainSpecificPAC = assertionCreators.get(assertionNamespace); |
|
450 |
||
451 |
||
452 |
if (domainSpecificPAC == null) { |
|
453 |
return defaultCreator.createAssertion(data, assertionParameters, nestedAlternative, null); |
|
454 |
} else { |
|
455 |
return domainSpecificPAC.createAssertion(data, assertionParameters, nestedAlternative, defaultCreator); |
|
456 |
} |
|
457 |
} |
|
458 |
||
459 |
} |