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