src/share/jaxws_classes/com/sun/xml/internal/ws/policy/sourcemodel/PolicyModelTranslator.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

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

mercurial