5e87f226368b3da3575edbce2cfcbea7168c3b0a
[policy/xacml-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2020 Nordix Foundation.
7  * Modifications Copyright (C) 2024 Deutsche Telekom AG.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * SPDX-License-Identifier: Apache-2.0
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.policy.xacml.pdp.application.nativ;
26
27 import com.att.research.xacml.api.Identifier;
28 import com.att.research.xacml.api.Request;
29 import com.att.research.xacml.api.Response;
30 import com.att.research.xacml.api.XACML3;
31 import com.att.research.xacml.util.XACMLPolicyScanner;
32 import java.io.ByteArrayInputStream;
33 import java.io.IOException;
34 import java.nio.charset.StandardCharsets;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Base64;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.UUID;
42 import lombok.Getter;
43 import lombok.NoArgsConstructor;
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
45 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
52 import oasis.names.tc.xacml._3_0.core.schema.wd_17.DefaultsType;
53 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
54 import oasis.names.tc.xacml._3_0.core.schema.wd_17.FunctionType;
55 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
58 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
59 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
60 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
61 import org.onap.policy.common.parameters.annotations.NotBlank;
62 import org.onap.policy.common.parameters.annotations.NotNull;
63 import org.onap.policy.models.decisions.concepts.DecisionRequest;
64 import org.onap.policy.models.decisions.concepts.DecisionResponse;
65 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
66 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
67 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
68 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72 /**
73  * This class implements one translator that interprets TOSCA policy and decision API request/response payload.
74  *
75  * @author Chenfei Gao (cgao@research.att.com)
76  *
77  */
78 @NoArgsConstructor
79 public class NativePdpApplicationTranslator implements ToscaPolicyTranslator {
80
81     private static final Logger LOGGER = LoggerFactory.getLogger(NativePdpApplicationTranslator.class);
82
83     private static final String TOSCA_XACML_POLICY_TYPE = "onap.policies.native.ToscaXacml";
84
85     private static final String DESCRIPTION = "description";
86
87     private static final String TARGET = "target";
88
89     private static final String VALUE = "value";
90
91     private static final String APPLY = "apply";
92
93     private static final String ONE_AND_ONLY = "-one-and-only";
94
95     private static final String DOUBLE = "double";
96
97     private Map<String, Identifier> identifierMap;
98
99     @Override
100     public Object convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
101         if (TOSCA_XACML_POLICY_TYPE.equals(toscaPolicy.getType())) {
102             setIdentifierMap();
103             return setPolicySetType(toscaPolicy);
104         } else {
105             //
106             // Extract the Base64 encoded policy xml string and decode it
107             //
108             String encodedXacmlPolicy = getNativeXacmlPolicy(toscaPolicy);
109             String decodedXacmlPolicy;
110             try {
111                 decodedXacmlPolicy = new String(Base64.getDecoder().decode(encodedXacmlPolicy), StandardCharsets.UTF_8);
112             } catch (IllegalArgumentException exc) {
113                 throw new ToscaPolicyConversionException("error on Base64 decoding the native policy", exc);
114             }
115             LOGGER.debug("Decoded xacml policy {}", decodedXacmlPolicy);
116             //
117             // Scan the string and convert to xacml PolicyType
118             //
119             try (var is = new ByteArrayInputStream(decodedXacmlPolicy.getBytes(StandardCharsets.UTF_8))) {
120                 //
121                 // Read the Policy In
122                 //
123                 Object policy = XACMLPolicyScanner.readPolicy(is);
124                 if (policy == null) {
125                     throw new ToscaPolicyConversionException("Invalid XACML Policy");
126                 }
127                 return policy;
128             } catch (IOException exc) {
129                 throw new ToscaPolicyConversionException("Failed to read policy", exc);
130             }
131         }
132     }
133
134     protected String getNativeXacmlPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
135
136         var nativeDefinition = ToscaPolicyTranslatorUtils.decodeProperties(toscaPolicy.getProperties(),
137                 NativeDefinition.class);
138
139         LOGGER.debug("Base64 encoded native xacml policy {}", nativeDefinition.getPolicy());
140         return nativeDefinition.getPolicy();
141     }
142
143     @Override
144     public Request convertRequest(DecisionRequest request) throws ToscaPolicyConversionException {
145         throw new ToscaPolicyConversionException("Do not call native convertRequest");
146     }
147
148     @Override
149     public DecisionResponse convertResponse(Response xacmlResponse) {
150         //
151         // We do nothing to DecisionResponse for native xacml application
152         //
153         return null;
154     }
155
156     @Getter
157     public static class NativeDefinition {
158         @NotNull
159         @NotBlank
160         private String policy;
161     }
162
163     private PolicySetType setPolicySetType(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
164         PolicySetType policySetType = new PolicySetType();
165         policySetType.setPolicySetId(String.valueOf(toscaPolicy.getMetadata().get("policy-id")));
166         policySetType.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue());
167         policySetType.setVersion(String.valueOf(toscaPolicy.getMetadata().get("policy-version")));
168         policySetType.setDescription(String.valueOf(toscaPolicy.getMetadata().get(DESCRIPTION)));
169         policySetType.setTarget(setPolicySetTarget(toscaPolicy.getMetadata().get("action")));
170         for (Map<String, Object> type: (List<Map<String, Object>>) toscaPolicy.getProperties().get("policies")) {
171             ToscaPolicy policy = new ToscaPolicy();
172             policy.setMetadata((Map<String, Object>) type.get("metadata"));
173             policy.setProperties((Map<String, Object>) type.get("properties"));
174             ObjectFactory objectFactory = new ObjectFactory();
175             policySetType.getPolicySetOrPolicyOrPolicySetIdReference()
176                     .add(objectFactory.createPolicy(convertPolicyXacml(policy)));
177         }
178         return policySetType;
179     }
180
181     /**
182      * Generate Xacml rule implementing specified CoordinationDirective.
183      *
184      * @param toscaPolicy Incoming Tosca Policy object
185      * @return the generated Xacml policy type
186      * @throws ToscaPolicyConversionException if check xacml identifier is not present
187      */
188     private PolicyType convertPolicyXacml(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
189         var policyType = new PolicyType();
190         Map<String, Object> properties = toscaPolicy.getProperties();
191         setPolicyType(toscaPolicy, policyType);
192         try {
193             List<Map<String, Object>> rules = (List<Map<String, Object>>) properties.get("rules");
194             for (Map<String, Object> rule : rules) {
195                 var ruleType = new RuleType();
196                 if (rule.get(DESCRIPTION) != null) {
197                     ruleType.setDescription((String) rule.get(DESCRIPTION));
198                 }
199                 ruleType.setRuleId(UUID.randomUUID().toString());
200                 if (rule.get(TARGET) != null) {
201                     ruleType.setTarget(setTargetType((Map<String, Object>) rule.get(TARGET)));
202                 }
203                 if (rule.get("condition") != null) {
204                     ruleType.setCondition(setConditionType((Map<String, Object>) rule.get("condition")));
205                 }
206                 if (rule.get("decision") == null) {
207                     throw new ToscaPolicyConversionException("decision is mandatory in a rule");
208                 }
209                 setAdviceExpression(ruleType, rule);
210                 policyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(ruleType);
211             }
212         } catch (ToscaPolicyConversionException ex) {
213             throw new ToscaPolicyConversionException("Invalid rule format");
214         }
215         if (properties.get("default") != null) {
216             setDefaultRule((String) properties.get("default"), policyType);
217         }
218         return policyType;
219     }
220
221     private void setPolicyType(ToscaPolicy toscaPolicy, PolicyType policyType) throws ToscaPolicyConversionException {
222         policyType.setPolicyId(String.valueOf(toscaPolicy.getMetadata().get("policy-id")));
223         policyType.setVersion(String.valueOf(toscaPolicy.getMetadata().get("policy-version")));
224         policyType.setDescription(String.valueOf(toscaPolicy.getMetadata().get(DESCRIPTION)));
225         DefaultsType defaultsType = new DefaultsType();
226         defaultsType.setXPathVersion("http://www.w3.org/TR/2007/REC-xpath20-20070123");
227         policyType.setPolicyDefaults(defaultsType);
228         Map<String, Object> properties = toscaPolicy.getProperties();
229         if (properties.get("combiningAlgo") != null) {
230             policyType.setRuleCombiningAlgId(validateFilterPropertyFunction((String)
231                     properties.get("combiningAlgo")).stringValue());
232         } else {
233             policyType.setRuleCombiningAlgId(XACML3.ID_RULE_FIRST_APPLICABLE.stringValue());
234         }
235         if (properties.get(TARGET) != null) {
236             policyType.setTarget(setTargetType((Map<String, Object>) properties.get(TARGET)));
237         } else {
238             policyType.setTarget(new TargetType());
239         }
240     }
241
242     private void setAdviceExpression(RuleType ruleType, Map<String, Object> rule)
243             throws ToscaPolicyConversionException {
244         String decision = (String) rule.get("decision");
245         if ("Deny".equalsIgnoreCase(decision)) {
246             ruleType.setEffect(EffectType.DENY);
247         } else {
248             ruleType.setEffect(EffectType.PERMIT);
249         }
250         if (rule.get("advice") != null) {
251             ruleType.setAdviceExpressions(setAdvice((Map<String, Object>) rule.get("advice"), decision));
252         }
253     }
254
255     private void setDefaultRule(String defaultDecision, PolicyType policyType) {
256         var defaultRule = new RuleType();
257         defaultRule.setDescription("Default Rule if none of the rules evaluate to True");
258         defaultRule.setRuleId(UUID.randomUUID().toString());
259         if ("Deny".equalsIgnoreCase(defaultDecision)) {
260             defaultRule.setEffect(EffectType.DENY);
261         } else {
262             defaultRule.setEffect(EffectType.PERMIT);
263         }
264         policyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(defaultRule);
265     }
266
267     private TargetType setTargetType(Map<String, Object> appliesTo) throws ToscaPolicyConversionException {
268         List<MatchType> listMatch = new ArrayList<>();
269         try {
270             List<Map<String, Object>> allOffList = (List<Map<String, Object>>) appliesTo.get("anyOne");
271             for (Map<String, Object> allOff : allOffList) {
272                 for (Map<String, Object> match : (List<Map<String, Object>>) allOff.get("allOf")) {
273                     var matchType = new MatchType();
274                     String operator = (String) match.get("operator");
275                     String datatype = getDatatype(operator);
276                     matchType.setMatchId(validateFilterPropertyFunction(operator).stringValue());
277                     var valueType = setAttributeValueType(match.get(VALUE),
278                             validateFilterPropertyFunction(datatype).stringValue());
279                     matchType.setAttributeValue(valueType);
280                     String attribute = "";
281                     String category = "";
282                     if (((String) match.get("key")).contains("action")) {
283                         attribute = validateFilterPropertyFunction((String) match
284                                 .get("key")).stringValue();
285                         category = XACML3.ID_ATTRIBUTE_CATEGORY_ACTION.stringValue();
286                     } else {
287                         attribute = (String) match.get("key");
288                         category = XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue();
289                     }
290                     var designator = setAttributeDesignatorType(attribute, category,
291                             validateFilterPropertyFunction(datatype).stringValue(), false);
292                     matchType.setAttributeDesignator(designator);
293                     listMatch.add(matchType);
294                 }
295             }
296         } catch (NullPointerException ex) {
297             throw new ToscaPolicyConversionException("Invalid target format");
298         }
299         var anyOfType = new AnyOfType();
300         MatchType[] matchTypes = new MatchType[listMatch.size()];
301         anyOfType.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(listMatch.toArray(matchTypes)));
302         var target = new TargetType();
303         target.getAnyOf().add(anyOfType);
304         return target;
305     }
306
307     private TargetType setPolicySetTarget(Object value) {
308         var matchType = new MatchType();
309         matchType.setMatchId(XACML3.ID_FUNCTION_STRING_EQUAL.stringValue());
310         var valueType = setAttributeValueType(value, XACML3.ID_DATATYPE_STRING.stringValue());
311         matchType.setAttributeValue(valueType);
312         var designator = setAttributeDesignatorType(XACML3.ID_ACTION_ACTION_ID.stringValue(),
313                 XACML3.ID_ATTRIBUTE_CATEGORY_ACTION.stringValue(),
314                 XACML3.ID_DATATYPE_STRING.stringValue(), false);
315         matchType.setAttributeDesignator(designator);
316         var anyOfType = new AnyOfType();
317         anyOfType.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchType));
318         var target = new TargetType();
319         target.getAnyOf().add(anyOfType);
320         return target;
321     }
322
323     private ConditionType setConditionType(Map<String, Object> conditionMap) throws ToscaPolicyConversionException {
324         var condition = new ConditionType();
325         try {
326             Map<String, Object> applyMap = (Map<String, Object>) conditionMap.get(APPLY);
327             ApplyType parentApply = setApply(applyMap);
328             condition.setExpression(new ObjectFactory().createApply(parentApply));
329         } catch (NullPointerException ex) {
330             throw new ToscaPolicyConversionException("Invalid condition format");
331         }
332         return condition;
333     }
334
335     private ApplyType setApply(Map<String, Object> applies) throws ToscaPolicyConversionException {
336         var apply = new ApplyType();
337         try {
338             List<Object> keys = (List<Object>) applies.get("keys");
339             String operator = (String) applies.get("operator");
340             String datatype = getDatatype(operator);
341             apply.setFunctionId(validateFilterPropertyFunction(operator).stringValue());
342             var factory = new ObjectFactory();
343             List<Object> keyList = new ArrayList<>();
344             setApplyKeys(keyList, keys, datatype, factory, apply);
345             setAttributeAndDesignator(keyList, apply, factory);
346             boolean data = switch (operator) {
347                 case "or", "and", "n-of", "not", "all-of", "any-of", "any-of-any", "all-of-any", "all-of-all",
348                      "any-of-all" -> false;
349                 default -> true;
350             };
351             if (data && applies.get("compareWith") != null) {
352                 setCompareWith(applies, apply, factory, getDatatype(operator));
353             }
354         } catch (NullPointerException ex) {
355             throw new ToscaPolicyConversionException("Invalid apply format");
356         }
357         return apply;
358     }
359
360     private void setApplyKeys(List<Object> keyList, List<Object> keys, String datatype,
361                               ObjectFactory factory, ApplyType apply) throws ToscaPolicyConversionException {
362         for (Object keyObject : keys) {
363             if (keyObject instanceof Map<?, ?>) {
364                 if (((Map<?, ?>) keyObject).get("list") != null) {
365                     setBagApply(apply, (List<Object>) ((Map<?, ?>) keyObject).get("list"), datatype, factory);
366                 } else if (((Map<?, ?>) keyObject).get("function") != null) {
367                     setFunctionType(apply, ((Map<String, String>) keyObject).get("function"), factory);
368                 } else if (((Map<?, ?>) keyObject).get(APPLY) != null) {
369                     keyList.add(setApply((Map<String, Object>) ((Map<?, ?>) keyObject).get(APPLY)));
370                 } else {
371                     throw new ToscaPolicyConversionException(
372                             "Invalid key entry, object does not contain list, function or apply");
373                 }
374             } else {
375                 setAttributes(keyObject, keyList, datatype, factory);
376             }
377         }
378     }
379
380     private void setAttributeAndDesignator(List<Object> keyList, ApplyType apply, ObjectFactory factory) {
381         keyList.stream()
382                 .sorted((firstKey, secondKey) -> {
383                     if (firstKey instanceof AttributeValueType) {
384                         return -1;
385                     } else if (firstKey instanceof ApplyType) {
386                         return 1;
387                     }
388                     return 0;
389                 })
390                 .forEach(key -> {
391                     if (key instanceof AttributeValueType) {
392                         apply.getExpression().add(factory.createAttributeValue((AttributeValueType) key));
393                     }
394                     if (key instanceof ApplyType) {
395                         apply.getExpression().add(factory.createApply((ApplyType) key));
396                     }
397                 });
398     }
399
400     private void setAttributes(Object key, List<Object> keyList, String datatype, ObjectFactory factory)
401             throws ToscaPolicyConversionException {
402         try {
403             if (key instanceof String) {
404                 String value = (String) key;
405                 if (value.startsWith("'") && value.endsWith("'")) {
406                     AttributeValueType attributeValue = setAttributeValueType(value.substring(1, value.length() - 1),
407                             validateFilterPropertyFunction(datatype).stringValue());
408                     keyList.add(attributeValue);
409                 } else {
410                     var keyDesignator = setAttributeDesignatorType(value,
411                             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(),
412                             validateFilterPropertyFunction(datatype).stringValue(), false);
413                     ApplyType keyApply = new ApplyType();
414                     keyApply.setFunctionId(validateFilterPropertyFunction(datatype + ONE_AND_ONLY).stringValue());
415                     keyApply.getExpression().add(factory.createAttributeDesignator(keyDesignator));
416                     keyList.add(keyApply);
417                 }
418             } else {
419                 AttributeValueType attributeValue = setAttributeValueType(key,
420                         validateFilterPropertyFunction(datatype).stringValue());
421                 keyList.add(attributeValue);
422             }
423         } catch (NullPointerException ex) {
424             throw new ToscaPolicyConversionException("Invalid string value format in keys");
425         }
426     }
427
428     private void setBagApply(ApplyType apply, List<Object> list, String datatype, ObjectFactory factory)
429             throws ToscaPolicyConversionException {
430         try {
431             var bagApply = new ApplyType();
432             bagApply.setFunctionId(validateFilterPropertyFunction(datatype + "-bag").stringValue());
433             for (Object attribute : list) {
434                 if (attribute instanceof String && !(((String) attribute).startsWith("'")
435                         && ((String) attribute).endsWith("'"))) {
436                     var applyDesignator = new ApplyType();
437                     applyDesignator.setFunctionId(
438                             validateFilterPropertyFunction(datatype + ONE_AND_ONLY).stringValue());
439                     var designator = setAttributeDesignatorType((String) attribute,
440                             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(),
441                             validateFilterPropertyFunction(datatype).stringValue(), false);
442                     applyDesignator.getExpression().add(factory.createAttributeDesignator(designator));
443                     bagApply.getExpression().add(factory.createApply(applyDesignator));
444                 }
445             }
446             for (Object attribute : list) {
447                 if (attribute instanceof String) {
448                     String value = (String) attribute;
449                     if (value.startsWith("'") && value.endsWith("'")) {
450                         var attributeValue = setAttributeValueType(value.substring(1, value.length() - 1),
451                                 validateFilterPropertyFunction(datatype).stringValue());
452                         bagApply.getExpression().add(factory.createAttributeValue(attributeValue));
453                     }
454                 } else {
455                     var attributeValue = setAttributeValueType(attribute,
456                             validateFilterPropertyFunction(datatype).stringValue());
457                     bagApply.getExpression().add(factory.createAttributeValue(attributeValue));
458                 }
459             }
460             apply.getExpression().add(factory.createApply(bagApply));
461         } catch (NullPointerException ex) {
462             throw new ToscaPolicyConversionException("Invalid list format in keys");
463         }
464     }
465
466     private void setFunctionType(ApplyType apply, String function, ObjectFactory factory)
467             throws ToscaPolicyConversionException {
468         try {
469             var functionType = new FunctionType();
470             functionType.setFunctionId(validateFilterPropertyFunction(function).stringValue());
471             apply.getExpression().add(factory.createFunction(functionType));
472         } catch (NullPointerException ex) {
473             throw new ToscaPolicyConversionException("Invalid function format in keys");
474         }
475     }
476
477     private void setCompareWith(Map<String, Object> compareWithMap, ApplyType apply, ObjectFactory factory,
478                                 String datatype) throws ToscaPolicyConversionException {
479         try {
480             Map<String, Object> compareWith = (Map<String, Object>) compareWithMap.get("compareWith");
481             if (compareWith.get(APPLY) != null) {
482                 ApplyType compareApply = setApply((Map<String, Object>) compareWith.get(APPLY));
483                 apply.getExpression().add(factory.createApply(compareApply));
484             } else if (compareWith.get(VALUE) != null) {
485                 var attributeValue = setAttributeValueType(compareWith.get(VALUE),
486                         validateFilterPropertyFunction(datatype).stringValue());
487                 apply.getExpression().add(factory.createAttributeValue(attributeValue));
488             } else if (compareWith.get("key") != null) {
489                 var keyDesignator = setAttributeDesignatorType((String) compareWith.get("key"),
490                         XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE.stringValue(),
491                         validateFilterPropertyFunction(datatype).stringValue(), false);
492                 var keyApply = new ApplyType();
493                 keyApply.setFunctionId(validateFilterPropertyFunction(datatype + ONE_AND_ONLY).stringValue());
494                 keyApply.getExpression().add(factory.createAttributeDesignator(keyDesignator));
495                 apply.getExpression().add(factory.createApply(keyApply));
496             } else {
497                 throw new ToscaPolicyConversionException("compareWith does not contain apply, value or key");
498             }
499         } catch (NullPointerException ex) {
500             throw new ToscaPolicyConversionException("Invalid compareWith format");
501         }
502     }
503
504     private AdviceExpressionsType setAdvice(Map<String, Object> advice, String decision)
505             throws ToscaPolicyConversionException {
506         var adviceExpressions = new AdviceExpressionsType();
507         try {
508             var adviceExpression = new AdviceExpressionType();
509             adviceExpression.setAdviceId(UUID.randomUUID().toString());
510             var value = setAttributeValueType(advice.get(VALUE), XACML3.ID_DATATYPE_STRING.stringValue());
511             var assignment = new AttributeAssignmentExpressionType();
512             assignment.setAttributeId("urn:oasis:names:tc:xacml:2.0:example:attribute:text");
513             assignment.setCategory(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT.stringValue());
514             assignment.setExpression(new ObjectFactory().createAttributeValue(value));
515             adviceExpression.getAttributeAssignmentExpression().add(assignment);
516             if ("Deny".equalsIgnoreCase(decision)) {
517                 adviceExpression.setAppliesTo(EffectType.DENY);
518             } else {
519                 adviceExpression.setAppliesTo(EffectType.PERMIT);
520             }
521             adviceExpressions.getAdviceExpression().add(adviceExpression);
522         } catch (NullPointerException ex) {
523             throw new ToscaPolicyConversionException("Invalid advice format");
524         }
525         return adviceExpressions;
526     }
527
528     private AttributeDesignatorType setAttributeDesignatorType(String attributeId, String category,
529                                                                String dataType, Boolean mustBe) {
530         var keyDesignator = new AttributeDesignatorType();
531         keyDesignator.setAttributeId(attributeId);
532         keyDesignator.setCategory(category);
533         keyDesignator.setDataType(dataType);
534         keyDesignator.setMustBePresent(mustBe);
535         return keyDesignator;
536     }
537
538     private AttributeValueType setAttributeValueType(Object value, String dataType) {
539         var attributeValue = new AttributeValueType();
540         attributeValue.setDataType(dataType);
541         attributeValue.getContent().add(value.toString());
542         return attributeValue;
543     }
544
545     private String getDatatype(String operator) throws ToscaPolicyConversionException {
546         try {
547             if (operator.contains("-to-")) {
548                 return operator.split("-")[0];
549             }
550             if (operator.contains("-from-")) {
551                 return operator.split("-")[2];
552             }
553             if (operator.equals("round") || operator.equals("floor")) {
554                 return DOUBLE;
555             }
556             List<String> datatypes = Arrays.asList("string", "boolean", "integer", DOUBLE, "time", "date", "dateTime",
557                     "dayTimeDuration", "yearMonthDuration", "anyURI", "hexBinary", "rfc822Name", "base64Binary",
558                     "x500Name", "ipAddress", "dnsName");
559             if (datatypes.stream().anyMatch(operator::contains)) {
560                 return operator.split("-")[0];
561             }
562         } catch (NullPointerException ex) {
563             throw new ToscaPolicyConversionException("Invalid operator");
564         }
565         return operator;
566     }
567
568     private void setIdentifierMap() {
569         identifierMap = new HashMap<>();
570         identifierMap.put("string-equal", XACML3.ID_FUNCTION_STRING_EQUAL);
571         identifierMap.put("integer-equal", XACML3.ID_FUNCTION_INTEGER_EQUAL);
572         identifierMap.put("string-equal-ignore-case", XACML3.ID_FUNCTION_STRING_EQUAL_IGNORE_CASE);
573         identifierMap.put("string-regexp-match", XACML3.ID_FUNCTION_STRING_REGEXP_MATCH);
574         identifierMap.put("string-contains", XACML3.ID_FUNCTION_STRING_CONTAINS);
575         identifierMap.put("string-greater-than", XACML3.ID_FUNCTION_STRING_GREATER_THAN);
576         identifierMap.put("string-greater-than-or-equal", XACML3.ID_FUNCTION_STRING_GREATER_THAN_OR_EQUAL);
577         identifierMap.put("string-less-than", XACML3.ID_FUNCTION_STRING_LESS_THAN);
578         identifierMap.put("string-less-than-or-equal", XACML3.ID_FUNCTION_STRING_LESS_THAN_OR_EQUAL);
579         identifierMap.put("string-starts-with", XACML3.ID_FUNCTION_STRING_STARTS_WITH);
580         identifierMap.put("string-ends-with", XACML3.ID_FUNCTION_STRING_ENDS_WITH);
581         identifierMap.put("integer-greater-than", XACML3.ID_FUNCTION_INTEGER_GREATER_THAN);
582         identifierMap.put("integer-greater-than-or-equal", XACML3.ID_FUNCTION_INTEGER_GREATER_THAN_OR_EQUAL);
583         identifierMap.put("integer-less-than", XACML3.ID_FUNCTION_INTEGER_LESS_THAN);
584         identifierMap.put("integer-less-than-or-equal", XACML3.ID_FUNCTION_INTEGER_LESS_THAN_OR_EQUAL);
585         identifierMap.put("double-greater-than", XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN);
586         identifierMap.put("double-greater-than-or-equal", XACML3.ID_FUNCTION_DOUBLE_GREATER_THAN_OR_EQUAL);
587         identifierMap.put("double-less-than", XACML3.ID_FUNCTION_DOUBLE_LESS_THAN);
588         identifierMap.put("double-less-than-or-equal", XACML3.ID_FUNCTION_DOUBLE_LESS_THAN_OR_EQUAL);
589         identifierMap.put("datetime-add-daytimeduration", XACML3.ID_FUNCTION_DATETIME_ADD_DAYTIMEDURATION);
590         identifierMap.put("datetime-add-yearmonthduration", XACML3.ID_FUNCTION_DATETIME_ADD_YEARMONTHDURATION);
591         identifierMap.put("datetime-subtract-daytimeturation", XACML3.ID_FUNCTION_DATETIME_SUBTRACT_DAYTIMEDURATION);
592         identifierMap.put("datetime-subtract-yearmonthduration",
593                 XACML3.ID_FUNCTION_DATETIME_SUBTRACT_YEARMONTHDURATION);
594         identifierMap.put("date-add-yearmonthduration", XACML3.ID_FUNCTION_DATE_ADD_YEARMONTHDURATION);
595         identifierMap.put("date-subtract-yearmonthduration", XACML3.ID_FUNCTION_DATE_SUBTRACT_YEARMONTHDURATION);
596         identifierMap.put("time-greater-than", XACML3.ID_FUNCTION_TIME_GREATER_THAN);
597         identifierMap.put("time-greater-than-or-equal", XACML3.ID_FUNCTION_TIME_GREATER_THAN_OR_EQUAL);
598         identifierMap.put("time-less-than", XACML3.ID_FUNCTION_TIME_LESS_THAN);
599         identifierMap.put("time-less-than-or-equal", XACML3.ID_FUNCTION_TIME_LESS_THAN_OR_EQUAL);
600         identifierMap.put("datetime-greater-than", XACML3.ID_FUNCTION_DATETIME_GREATER_THAN);
601         identifierMap.put("datetime-greater-than-or-equal", XACML3.ID_FUNCTION_DATETIME_GREATER_THAN_OR_EQUAL);
602         identifierMap.put("datetime-less-than", XACML3.ID_FUNCTION_DATETIME_LESS_THAN);
603         identifierMap.put("datetime-less-than-or-equal", XACML3.ID_FUNCTION_DATETIME_LESS_THAN_OR_EQUAL);
604         identifierMap.put("date-greater-than", XACML3.ID_FUNCTION_DATE_GREATER_THAN);
605         identifierMap.put("date-greater-than-or-equal", XACML3.ID_FUNCTION_DATE_GREATER_THAN_OR_EQUAL);
606         identifierMap.put("date-less-than", XACML3.ID_FUNCTION_DATE_LESS_THAN);
607         identifierMap.put("date-less-than-or-equal", XACML3.ID_FUNCTION_DATE_LESS_THAN_OR_EQUAL);
608         identifierMap.put("boolean-one-and-only", XACML3.ID_FUNCTION_BOOLEAN_ONE_AND_ONLY);
609         identifierMap.put("string-is-in", XACML3.ID_FUNCTION_STRING_IS_IN);
610         identifierMap.put("integer-is-in", XACML3.ID_FUNCTION_INTEGER_IS_IN);
611         identifierMap.put("boolean-is-in", XACML3.ID_FUNCTION_BOOLEAN_IS_IN);
612         identifierMap.put("double-is-in", XACML3.ID_FUNCTION_DOUBLE_IS_IN);
613         identifierMap.put("integer-add", XACML3.ID_FUNCTION_INTEGER_ADD);
614         identifierMap.put("double-add", XACML3.ID_FUNCTION_DOUBLE_ADD);
615         identifierMap.put("integer-subtract", XACML3.ID_FUNCTION_INTEGER_SUBTRACT);
616         identifierMap.put("double-subtract", XACML3.ID_FUNCTION_DOUBLE_SUBTRACT);
617         identifierMap.put("integer-multiply", XACML3.ID_FUNCTION_INTEGER_MULTIPLY);
618         identifierMap.put("double-multiply", XACML3.ID_FUNCTION_DOUBLE_MULTIPLY);
619         identifierMap.put("integer-divide", XACML3.ID_FUNCTION_INTEGER_DIVIDE);
620         identifierMap.put("double-divide", XACML3.ID_FUNCTION_DOUBLE_DIVIDE);
621         identifierMap.put("integer-mod", XACML3.ID_FUNCTION_INTEGER_MOD);
622         identifierMap.put("integer-abs", XACML3.ID_FUNCTION_INTEGER_ABS);
623         identifierMap.put("double-abs", XACML3.ID_FUNCTION_DOUBLE_ABS);
624         identifierMap.put("integer-to-double", XACML3.ID_FUNCTION_INTEGER_TO_DOUBLE);
625         identifierMap.put("yearmonthduration-equal", XACML3.ID_FUNCTION_YEARMONTHDURATION_EQUAL);
626         identifierMap.put("anyuri-equal", XACML3.ID_FUNCTION_ANYURI_EQUAL);
627         identifierMap.put("hexbinary-equal", XACML3.ID_FUNCTION_HEXBINARY_EQUAL);
628         identifierMap.put("rfc822name-equal", XACML3.ID_FUNCTION_RFC822NAME_EQUAL);
629         identifierMap.put("x500name-equal", XACML3.ID_FUNCTION_X500NAME_EQUAL);
630         identifierMap.put("string-from-ipaddress", XACML3.ID_FUNCTION_STRING_FROM_IPADDRESS);
631         identifierMap.put("string-from-dnsname", XACML3.ID_FUNCTION_STRING_FROM_DNSNAME);
632
633         identifierMap.put("boolean-equal", XACML3.ID_FUNCTION_BOOLEAN_EQUAL);
634         identifierMap.put("double-equal", XACML3.ID_FUNCTION_DOUBLE_EQUAL);
635         identifierMap.put("date-equal", XACML3.ID_FUNCTION_DATE_EQUAL);
636         identifierMap.put("time-equal", XACML3.ID_FUNCTION_TIME_EQUAL);
637         identifierMap.put("datetime-equal", XACML3.ID_FUNCTION_DATETIME_EQUAL);
638         identifierMap.put("daytimeduration-equal", XACML3.ID_FUNCTION_DAYTIMEDURATION_EQUAL);
639         identifierMap.put("base64binary-equal", XACML3.ID_FUNCTION_BASE64BINARY_EQUAL);
640         identifierMap.put("round", XACML3.ID_FUNCTION_ROUND);
641         identifierMap.put("floor", XACML3.ID_FUNCTION_FLOOR);
642         identifierMap.put("string-normalize-space", XACML3.ID_FUNCTION_STRING_NORMALIZE_SPACE);
643         identifierMap.put("string-normalize-to-lower-case", XACML3.ID_FUNCTION_STRING_NORMALIZE_TO_LOWER_CASE);
644         identifierMap.put("double-to-integer", XACML3.ID_FUNCTION_DOUBLE_TO_INTEGER);
645         identifierMap.put("present", XACML3.ID_FUNCTION_PRESENT);
646         identifierMap.put("time-in-range", XACML3.ID_FUNCTION_TIME_IN_RANGE);
647         identifierMap.put("string-bag-size", XACML3.ID_FUNCTION_STRING_BAG_SIZE);
648         identifierMap.put("boolean-bag-size", XACML3.ID_FUNCTION_BOOLEAN_BAG_SIZE);
649         identifierMap.put("integer-bag-size", XACML3.ID_FUNCTION_INTEGER_BAG_SIZE);
650         identifierMap.put("double-bag-size", XACML3.ID_FUNCTION_DOUBLE_BAG_SIZE);
651         identifierMap.put("time-bag-size", XACML3.ID_FUNCTION_TIME_BAG_SIZE);
652         identifierMap.put("time-is-in", XACML3.ID_FUNCTION_TIME_IS_IN);
653         identifierMap.put("time-bag", XACML3.ID_FUNCTION_TIME_BAG);
654         identifierMap.put("date-bag-size", XACML3.ID_FUNCTION_DATE_BAG_SIZE);
655         identifierMap.put("date-is-in", XACML3.ID_FUNCTION_DATE_IS_IN);
656         identifierMap.put("date-bag", XACML3.ID_FUNCTION_DATE_BAG);
657         identifierMap.put("datetime-bag-size", XACML3.ID_FUNCTION_DATETIME_BAG_SIZE);
658         identifierMap.put("datetime-is-in", XACML3.ID_FUNCTION_DATETIME_IS_IN);
659         identifierMap.put("datetime-bag", XACML3.ID_FUNCTION_DATETIME_BAG);
660         identifierMap.put("anyuri-bag-size", XACML3.ID_FUNCTION_ANYURI_BAG_SIZE);
661         identifierMap.put("anyuri-is-in", XACML3.ID_FUNCTION_ANYURI_IS_IN);
662         identifierMap.put("anyuri-bag", XACML3.ID_FUNCTION_ANYURI_BAG);
663         identifierMap.put("hexbinary-bag-size", XACML3.ID_FUNCTION_HEXBINARY_BAG_SIZE);
664         identifierMap.put("hexbinary-is-in", XACML3.ID_FUNCTION_HEXBINARY_IS_IN);
665         identifierMap.put("hexbinary-bag", XACML3.ID_FUNCTION_HEXBINARY_BAG);
666         identifierMap.put("base64binary-bag-size", XACML3.ID_FUNCTION_BASE64BINARY_BAG_SIZE);
667         identifierMap.put("base64binary-is-in", XACML3.ID_FUNCTION_BASE64BINARY_IS_IN);
668         identifierMap.put("base64binary-bag", XACML3.ID_FUNCTION_BASE64BINARY_BAG);
669         identifierMap.put("daytimeduration-bag-size", XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG_SIZE);
670         identifierMap.put("daytimeduration-is-in", XACML3.ID_FUNCTION_DAYTIMEDURATION_IS_IN);
671         identifierMap.put("daytimeduration-bag", XACML3.ID_FUNCTION_DAYTIMEDURATION_BAG);
672         identifierMap.put("yearmonthduration-bag-size", XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG_SIZE);
673         identifierMap.put("yearmonthduration-is-in", XACML3.ID_FUNCTION_YEARMONTHDURATION_IS_IN);
674         identifierMap.put("yearmonthduration-bag", XACML3.ID_FUNCTION_YEARMONTHDURATION_BAG);
675         identifierMap.put("x500name-one-and-only", XACML3.ID_FUNCTION_X500NAME_ONE_AND_ONLY);
676         identifierMap.put("x500name-bag-size", XACML3.ID_FUNCTION_X500NAME_BAG_SIZE);
677         identifierMap.put("x500name-is-in", XACML3.ID_FUNCTION_X500NAME_IS_IN);
678         identifierMap.put("x500name-bag", XACML3.ID_FUNCTION_X500NAME_BAG);
679         identifierMap.put("rfc822name-one-and-only", XACML3.ID_FUNCTION_RFC822NAME_ONE_AND_ONLY);
680         identifierMap.put("rfc822name-bag-size", XACML3.ID_FUNCTION_RFC822NAME_BAG_SIZE);
681         identifierMap.put("rfc822name-is-in", XACML3.ID_FUNCTION_RFC822NAME_IS_IN);
682         identifierMap.put("rfc822name-bag", XACML3.ID_FUNCTION_RFC822NAME_BAG);
683         identifierMap.put("ipaddress-one-and-only", XACML3.ID_FUNCTION_IPADDRESS_ONE_AND_ONLY);
684         identifierMap.put("ipaddress-bag-size", XACML3.ID_FUNCTION_IPADDRESS_BAG_SIZE);
685         identifierMap.put("ipaddress-is-in", XACML3.ID_FUNCTION_IPADDRESS_IS_IN);
686         identifierMap.put("ipaddress-bag", XACML3.ID_FUNCTION_IPADDRESS_BAG);
687         identifierMap.put("dnsname-one-and-only", XACML3.ID_FUNCTION_DNSNAME_ONE_AND_ONLY);
688         identifierMap.put("dnsname-bag-size", XACML3.ID_FUNCTION_DNSNAME_BAG_SIZE);
689         identifierMap.put("dnsname-is-in", XACML3.ID_FUNCTION_DNSNAME_IS_IN);
690         identifierMap.put("dnsname-bag", XACML3.ID_FUNCTION_DNSNAME_BAG);
691         identifierMap.put("string-concatenate", XACML3.ID_FUNCTION_STRING_CONCATENATE);
692         identifierMap.put("boolean-from-string", XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING);
693         identifierMap.put("string-from-boolean", XACML3.ID_FUNCTION_STRING_FROM_BOOLEAN);
694         identifierMap.put("integer-from-string", XACML3.ID_FUNCTION_INTEGER_FROM_STRING);
695         identifierMap.put("string-from-integer", XACML3.ID_FUNCTION_STRING_FROM_INTEGER);
696         identifierMap.put("double-from-string", XACML3.ID_FUNCTION_DOUBLE_FROM_STRING);
697         identifierMap.put("string-from-double", XACML3.ID_FUNCTION_STRING_FROM_DOUBLE);
698         identifierMap.put("time-from-string", XACML3.ID_FUNCTION_TIME_FROM_STRING);
699         identifierMap.put("string-from-time", XACML3.ID_FUNCTION_STRING_FROM_TIME);
700         identifierMap.put("date-from-string", XACML3.ID_FUNCTION_DATE_FROM_STRING);
701         identifierMap.put("string-from-date", XACML3.ID_FUNCTION_STRING_FROM_DATE);
702         identifierMap.put("datetime-from-string", XACML3.ID_FUNCTION_DATETIME_FROM_STRING);
703         identifierMap.put("string-from-datetime", XACML3.ID_FUNCTION_STRING_FROM_DATETIME);
704         identifierMap.put("anyuri-from-string", XACML3.ID_FUNCTION_ANYURI_FROM_STRING);
705         identifierMap.put("string-from-anyuri", XACML3.ID_FUNCTION_STRING_FROM_ANYURI);
706         identifierMap.put("daytimeduration-from-string", XACML3.ID_FUNCTION_DAYTIMEDURATION_FROM_STRING);
707         identifierMap.put("string-from-daytimeturation", XACML3.ID_FUNCTION_STRING_FROM_DAYTIMEDURATION);
708         identifierMap.put("yearmonthduration-from-string", XACML3.ID_FUNCTION_YEARMONTHDURATION_FROM_STRING);
709         identifierMap.put("string-from-yearmonthduration", XACML3.ID_FUNCTION_STRING_FROM_YEARMONTHDURATION);
710         identifierMap.put("x500name-from-string", XACML3.ID_FUNCTION_X500NAME_FROM_STRING);
711         identifierMap.put("string-from-x500name", XACML3.ID_FUNCTION_STRING_FROM_X500NAME);
712         identifierMap.put("rfc822name-from-string", XACML3.ID_FUNCTION_RFC822NAME_FROM_STRING);
713         identifierMap.put("string-from-rfc822name", XACML3.ID_FUNCTION_STRING_FROM_RFC822NAME);
714         identifierMap.put("ipaddress-from-string", XACML3.ID_FUNCTION_IPADDRESS_FROM_STRING);
715         identifierMap.put("dnsname-from-string", XACML3.ID_FUNCTION_DNSNAME_FROM_STRING);
716         identifierMap.put("anyuri-starts-with", XACML3.ID_FUNCTION_ANYURI_STARTS_WITH);
717         identifierMap.put("anyuri-ends-with", XACML3.ID_FUNCTION_ANYURI_ENDS_WITH);
718         identifierMap.put("anyuri-contains", XACML3.ID_FUNCTION_ANYURI_CONTAINS);
719         identifierMap.put("string-substring", XACML3.ID_FUNCTION_STRING_SUBSTRING);
720         identifierMap.put("anyuri-substring", XACML3.ID_FUNCTION_ANYURI_SUBSTRING);
721         identifierMap.put("map", XACML3.ID_FUNCTION_MAP);
722         identifierMap.put("x500name-match", XACML3.ID_FUNCTION_X500NAME_MATCH);
723         identifierMap.put("rfc822name-match", XACML3.ID_FUNCTION_RFC822NAME_MATCH);
724         identifierMap.put("anyuri-regexp-match", XACML3.ID_FUNCTION_ANYURI_REGEXP_MATCH);
725         identifierMap.put("ipaddress-regexp-match", XACML3.ID_FUNCTION_IPADDRESS_REGEXP_MATCH);
726         identifierMap.put("dnsname-regexp-match", XACML3.ID_FUNCTION_DNSNAME_REGEXP_MATCH);
727         identifierMap.put("rfc822name-regexp-match", XACML3.ID_FUNCTION_RFC822NAME_REGEXP_MATCH);
728         identifierMap.put("x500name-regexp-match", XACML3.ID_FUNCTION_X500NAME_REGEXP_MATCH);
729         identifierMap.put("xpath-node-count", XACML3.ID_FUNCTION_XPATH_NODE_COUNT);
730         identifierMap.put("xpath-node-equal", XACML3.ID_FUNCTION_XPATH_NODE_EQUAL);
731         identifierMap.put("xpath-node-match", XACML3.ID_FUNCTION_XPATH_NODE_MATCH);
732         identifierMap.put("string-intersection", XACML3.ID_FUNCTION_STRING_INTERSECTION);
733         identifierMap.put("string-at-least-one-member-of", XACML3.ID_FUNCTION_STRING_AT_LEAST_ONE_MEMBER_OF);
734         identifierMap.put("string-union", XACML3.ID_FUNCTION_STRING_UNION);
735         identifierMap.put("string-subset", XACML3.ID_FUNCTION_STRING_SUBSET);
736         identifierMap.put("string-set-equals", XACML3.ID_FUNCTION_STRING_SET_EQUALS);
737         identifierMap.put("boolean-intersection", XACML3.ID_FUNCTION_BOOLEAN_INTERSECTION);
738         identifierMap.put("boolean-at-least-one-member-of", XACML3.ID_FUNCTION_BOOLEAN_AT_LEAST_ONE_MEMBER_OF);
739         identifierMap.put("boolean-union", XACML3.ID_FUNCTION_BOOLEAN_UNION);
740         identifierMap.put("boolean-subset", XACML3.ID_FUNCTION_BOOLEAN_SUBSET);
741         identifierMap.put("boolean-set-equals", XACML3.ID_FUNCTION_BOOLEAN_SET_EQUALS);
742         identifierMap.put("integer-intersection", XACML3.ID_FUNCTION_INTEGER_INTERSECTION);
743         identifierMap.put("integer-at-least-one-member-of", XACML3.ID_FUNCTION_INTEGER_AT_LEAST_ONE_MEMBER_OF);
744         identifierMap.put("integer-union", XACML3.ID_FUNCTION_INTEGER_UNION);
745         identifierMap.put("integer-subset", XACML3.ID_FUNCTION_INTEGER_SUBSET);
746         identifierMap.put("integer-set-equals", XACML3.ID_FUNCTION_INTEGER_SET_EQUALS);
747         identifierMap.put("double-intersection", XACML3.ID_FUNCTION_DOUBLE_INTERSECTION);
748         identifierMap.put("double-at-least-one-member-of", XACML3.ID_FUNCTION_DOUBLE_AT_LEAST_ONE_MEMBER_OF);
749         identifierMap.put("double-union", XACML3.ID_FUNCTION_DOUBLE_UNION);
750         identifierMap.put("double-subset", XACML3.ID_FUNCTION_DOUBLE_SUBSET);
751         identifierMap.put("double-set-equals", XACML3.ID_FUNCTION_DOUBLE_SET_EQUALS);
752         identifierMap.put("time-intersection", XACML3.ID_FUNCTION_TIME_INTERSECTION);
753         identifierMap.put("time-at-least-one-member-of", XACML3.ID_FUNCTION_TIME_AT_LEAST_ONE_MEMBER_OF);
754         identifierMap.put("time-union", XACML3.ID_FUNCTION_TIME_UNION);
755         identifierMap.put("time-subset", XACML3.ID_FUNCTION_TIME_SUBSET);
756         identifierMap.put("time-set-equals", XACML3.ID_FUNCTION_TIME_SET_EQUALS);
757         identifierMap.put("date-intersection", XACML3.ID_FUNCTION_DATE_INTERSECTION);
758         identifierMap.put("date-at-least-one-member-of", XACML3.ID_FUNCTION_DATE_AT_LEAST_ONE_MEMBER_OF);
759         identifierMap.put("date-union", XACML3.ID_FUNCTION_DATE_UNION);
760         identifierMap.put("date-subset", XACML3.ID_FUNCTION_DATE_SUBSET);
761         identifierMap.put("date-set-equals", XACML3.ID_FUNCTION_DATE_SET_EQUALS);
762         identifierMap.put("datetime-intersection", XACML3.ID_FUNCTION_DATETIME_INTERSECTION);
763         identifierMap.put("datetime-at-least-one-member-of", XACML3.ID_FUNCTION_DATETIME_AT_LEAST_ONE_MEMBER_OF);
764         identifierMap.put("datetime-union", XACML3.ID_FUNCTION_DATETIME_UNION);
765         identifierMap.put("datetime-subset", XACML3.ID_FUNCTION_DATETIME_SUBSET);
766         identifierMap.put("datetime-set-equals", XACML3.ID_FUNCTION_DATETIME_SET_EQUALS);
767
768         identifierMap.put("anyuri-intersection", XACML3.ID_FUNCTION_ANYURI_INTERSECTION);
769         identifierMap.put("anyuri-at-least-one-member-of", XACML3.ID_FUNCTION_ANYURI_AT_LEAST_ONE_MEMBER_OF);
770         identifierMap.put("anyuri-union", XACML3.ID_FUNCTION_ANYURI_UNION);
771         identifierMap.put("anyuri-subset", XACML3.ID_FUNCTION_ANYURI_SUBSET);
772         identifierMap.put("anyuri-set-equals", XACML3.ID_FUNCTION_ANYURI_SET_EQUALS);
773         identifierMap.put("hexbinary-intersection", XACML3.ID_FUNCTION_HEXBINARY_INTERSECTION);
774         identifierMap.put("hexbinary-at-least-one-member-of", XACML3.ID_FUNCTION_HEXBINARY_AT_LEAST_ONE_MEMBER_OF);
775         identifierMap.put("hexbinary-union", XACML3.ID_FUNCTION_HEXBINARY_UNION);
776         identifierMap.put("hexbinary-subset", XACML3.ID_FUNCTION_HEXBINARY_SUBSET);
777         identifierMap.put("hexbinary-set-equals", XACML3.ID_FUNCTION_HEXBINARY_SET_EQUALS);
778         identifierMap.put("base64binary-intersection", XACML3.ID_FUNCTION_BASE64BINARY_INTERSECTION);
779         identifierMap.put("base64binary-at-least-one-member-of",
780                 XACML3.ID_FUNCTION_BASE64BINARY_AT_LEAST_ONE_MEMBER_OF);
781         identifierMap.put("base64binary-union", XACML3.ID_FUNCTION_BASE64BINARY_UNION);
782         identifierMap.put("base64binary-subset", XACML3.ID_FUNCTION_BASE64BINARY_SUBSET);
783         identifierMap.put("base64binary-set-equals", XACML3.ID_FUNCTION_BASE64BINARY_SET_EQUALS);
784         identifierMap.put("daytimeduration-intersection", XACML3.ID_FUNCTION_DAYTIMEDURATION_INTERSECTION);
785         identifierMap.put("daytimeduration-at-least-one-member-of",
786                 XACML3.ID_FUNCTION_DAYTIMEDURATION_AT_LEAST_ONE_MEMBER_OF);
787         identifierMap.put("daytimeduration-union", XACML3.ID_FUNCTION_DAYTIMEDURATION_UNION);
788         identifierMap.put("daytimeduration-subset", XACML3.ID_FUNCTION_DAYTIMEDURATION_SUBSET);
789         identifierMap.put("daytimeduration-set-equals", XACML3.ID_FUNCTION_DAYTIMEDURATION_SET_EQUALS);
790         identifierMap.put("yearmonthduration-intersection", XACML3.ID_FUNCTION_YEARMONTHDURATION_INTERSECTION);
791         identifierMap.put("yearmonthduration-at-least-one-member-of",
792                 XACML3.ID_FUNCTION_YEARMONTHDURATION_AT_LEAST_ONE_MEMBER_OF);
793         identifierMap.put("yearmonthduration-union", XACML3.ID_FUNCTION_YEARMONTHDURATION_UNION);
794         identifierMap.put("yearmonthduration-subset", XACML3.ID_FUNCTION_YEARMONTHDURATION_SUBSET);
795         identifierMap.put("yearmonthduration-set-equals", XACML3.ID_FUNCTION_YEARMONTHDURATION_SET_EQUALS);
796         identifierMap.put("x500name-intersection", XACML3.ID_FUNCTION_X500NAME_INTERSECTION);
797         identifierMap.put("x500name-at-least-one-member-of", XACML3.ID_FUNCTION_X500NAME_AT_LEAST_ONE_MEMBER_OF);
798         identifierMap.put("x500name-union", XACML3.ID_FUNCTION_X500NAME_UNION);
799         identifierMap.put("x500name-subset", XACML3.ID_FUNCTION_X500NAME_SUBSET);
800         identifierMap.put("x500name-set-equals", XACML3.ID_FUNCTION_X500NAME_SET_EQUALS);
801         identifierMap.put("rfc822name-intersection", XACML3.ID_FUNCTION_RFC822NAME_INTERSECTION);
802         identifierMap.put("rfc822name-at-least-one-member-of", XACML3.ID_FUNCTION_RFC822NAME_AT_LEAST_ONE_MEMBER_OF);
803         identifierMap.put("rfc822name-union", XACML3.ID_FUNCTION_RFC822NAME_UNION);
804         identifierMap.put("rfc822name-subset", XACML3.ID_FUNCTION_RFC822NAME_SUBSET);
805         identifierMap.put("rfc822name-set-equals", XACML3.ID_FUNCTION_RFC822NAME_SET_EQUALS);
806         identifierMap.put("ipaddress-intersection", XACML3.ID_FUNCTION_IPADDRESS_INTERSECTION);
807         identifierMap.put("ipaddress-at-least-one-member-of", XACML3.ID_FUNCTION_IPADDRESS_AT_LEAST_ONE_MEMBER_OF);
808         identifierMap.put("ipaddress-union", XACML3.ID_FUNCTION_IPADDRESS_UNION);
809         identifierMap.put("ipaddress-subset", XACML3.ID_FUNCTION_IPADDRESS_SUBSET);
810         identifierMap.put("ipaddress-set-equals", XACML3.ID_FUNCTION_IPADDRESS_SET_EQUALS);
811         identifierMap.put("dnsname-intersection", XACML3.ID_FUNCTION_DNSNAME_INTERSECTION);
812         identifierMap.put("dnsname-at-least-one-member-of", XACML3.ID_FUNCTION_DNSNAME_AT_LEAST_ONE_MEMBER_OF);
813         identifierMap.put("dnsname-union", XACML3.ID_FUNCTION_DNSNAME_UNION);
814         identifierMap.put("dnsname-subset", XACML3.ID_FUNCTION_DNSNAME_SUBSET);
815         identifierMap.put("dnsname-set-equals", XACML3.ID_FUNCTION_DNSNAME_SET_EQUALS);
816         identifierMap.put("access-permitted", XACML3.ID_FUNCTION_ACCESS_PERMITTED);
817
818         // function condition
819         identifierMap.put("or", XACML3.ID_FUNCTION_OR);
820         identifierMap.put("and", XACML3.ID_FUNCTION_AND);
821         identifierMap.put("n-of", XACML3.ID_FUNCTION_N_OF);
822         identifierMap.put("not", XACML3.ID_FUNCTION_NOT);
823         identifierMap.put("any-of", XACML3.ID_FUNCTION_ANY_OF);
824         identifierMap.put("all-of", XACML3.ID_FUNCTION_ALL_OF);
825         identifierMap.put("any-of-any", XACML3.ID_FUNCTION_ANY_OF_ANY);
826         identifierMap.put("all-of-any", XACML3.ID_FUNCTION_ALL_OF_ANY);
827         identifierMap.put("any-of-all", XACML3.ID_FUNCTION_ANY_OF_ALL);
828         identifierMap.put("all-of-all", XACML3.ID_FUNCTION_ALL_OF_ALL);
829
830         // function ids
831         identifierMap.put("string-one-and-only", XACML3.ID_FUNCTION_STRING_ONE_AND_ONLY);
832         identifierMap.put("integer-one-and-only", XACML3.ID_FUNCTION_INTEGER_ONE_AND_ONLY);
833         identifierMap.put("double-one-and-only", XACML3.ID_FUNCTION_DOUBLE_ONE_AND_ONLY);
834         identifierMap.put("time-one-and-only", XACML3.ID_FUNCTION_TIME_ONE_AND_ONLY);
835         identifierMap.put("date-one-and-only", XACML3.ID_FUNCTION_DATE_ONE_AND_ONLY);
836         identifierMap.put("datetime-one-and-only", XACML3.ID_FUNCTION_DATETIME_ONE_AND_ONLY);
837         identifierMap.put("anyuri-one-and-only", XACML3.ID_FUNCTION_ANYURI_ONE_AND_ONLY);
838         identifierMap.put("hexbinary-one-and-only", XACML3.ID_FUNCTION_HEXBINARY_ONE_AND_ONLY);
839         identifierMap.put("base64binary-one-and-only", XACML3.ID_FUNCTION_BASE64BINARY_ONE_AND_ONLY);
840         identifierMap.put("daytimeduration-one-and-only", XACML3.ID_FUNCTION_DAYTIMEDURATION_ONE_AND_ONLY);
841         identifierMap.put("yearmonthduration-one-and-only", XACML3.ID_FUNCTION_YEARMONTHDURATION_ONE_AND_ONLY);
842
843         //attribute ids
844         identifierMap.put("action-id", XACML3.ID_ACTION_ACTION_ID);
845
846         // algorithm
847         identifierMap.put("first-applicable", XACML3.ID_RULE_FIRST_APPLICABLE);
848         identifierMap.put("deny-overrides", XACML3.ID_RULE_DENY_UNLESS_PERMIT);
849         identifierMap.put("permit-overrides", XACML3.ID_RULE_PERMIT_UNLESS_DENY);
850         identifierMap.put("only-one-applicable", XACML3.ID_RULE_ONLY_ONE_APPLICABLE);
851
852         // data types
853         identifierMap.put("string", XACML3.ID_DATATYPE_STRING);
854         identifierMap.put("boolean", XACML3.ID_DATATYPE_BOOLEAN);
855         identifierMap.put("integer", XACML3.ID_DATATYPE_INTEGER);
856         identifierMap.put(DOUBLE, XACML3.ID_DATATYPE_DOUBLE);
857         identifierMap.put("time", XACML3.ID_DATATYPE_TIME);
858         identifierMap.put("date", XACML3.ID_DATATYPE_DATE);
859         identifierMap.put("datetime", XACML3.ID_DATATYPE_DATETIME);
860         identifierMap.put("daytimeduration", XACML3.ID_DATATYPE_DAYTIMEDURATION);
861         identifierMap.put("yearmonthduration", XACML3.ID_DATATYPE_YEARMONTHDURATION);
862         identifierMap.put("anyuri", XACML3.ID_DATATYPE_ANYURI);
863         identifierMap.put("hexbinary", XACML3.ID_DATATYPE_HEXBINARY);
864         identifierMap.put("base64binary", XACML3.ID_DATATYPE_BASE64BINARY);
865         identifierMap.put("rfc822name", XACML3.ID_DATATYPE_RFC822NAME);
866         identifierMap.put("x500name", XACML3.ID_DATATYPE_X500NAME);
867         identifierMap.put("ipaddress", XACML3.ID_DATATYPE_IPADDRESS);
868         identifierMap.put("dnsname", XACML3.ID_DATATYPE_DNSNAME);
869
870         identifierMap.put("string-bag", XACML3.ID_FUNCTION_STRING_BAG);
871         identifierMap.put("boolean-bag", XACML3.ID_FUNCTION_BOOLEAN_BAG);
872         identifierMap.put("integer-bag", XACML3.ID_FUNCTION_INTEGER_BAG);
873         identifierMap.put("double-bag", XACML3.ID_FUNCTION_DOUBLE_BAG);
874     }
875
876     private Identifier validateFilterPropertyFunction(String operator) throws ToscaPolicyConversionException {
877         if (identifierMap.containsKey(operator.toLowerCase())) {
878             return identifierMap.get(operator.toLowerCase());
879         } else {
880             throw new ToscaPolicyConversionException("Unexpected value " + operator);
881         }
882     }
883 }