2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.policy.components;
24 import java.io.ByteArrayOutputStream;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.PrintWriter;
29 import java.io.StringWriter;
30 import java.nio.file.FileSystems;
31 import java.nio.file.Path;
32 import java.util.Collection;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
38 import javax.xml.bind.JAXBElement;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
45 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
52 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
53 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
54 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
55 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
58 import org.apache.commons.io.FilenameUtils;
59 import org.json.JSONObject;
60 import org.openecomp.policy.controller.PolicyController;
61 import org.openecomp.policy.rest.jpa.FunctionDefinition;
62 import org.openecomp.policy.utils.XACMLPolicyWriterWithPapNotify;
64 import com.att.research.xacml.api.AttributeValue;
65 import org.openecomp.policy.xacml.api.XACMLErrorConstants;
66 import com.att.research.xacml.std.IdentifierImpl;
67 import com.att.research.xacml.std.StdAttribute;
68 import com.att.research.xacml.std.StdAttributeValue;
69 import org.openecomp.policy.xacml.util.XACMLPolicyScanner;
70 import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult;
71 import com.att.research.xacml.util.XACMLPolicyScanner.SimpleCallback;
73 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
74 import org.openecomp.policy.common.logging.flexlogger.Logger;
78 public class HumanPolicyComponent{
80 private static final Logger LOGGER = FlexLogger.getLogger(HumanPolicyComponent.class);
82 // Constants Used in XML Creation
83 public static final String CATEGORY_RECIPIENT_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
84 public static final String CATEGORY_RESOURCE = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource";
85 public static final String CATEGORY_ACTION = "urn:oasis:names:tc:xacml:3.0:attribute-category:action";
86 public static final String CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
87 public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
88 public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
89 public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
90 public static final String FUNTION_INTEGER_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only";
91 public static final String FUNCTION_STRING_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only";
92 public static final String FUNCTION_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
93 public static final String FUNCTION_STRING_REGEX_MATCH = "org.openecomp.function.regex-match";
94 public static final String FUNCTION_STRING_EQUAL_IGNORE = "urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case";
95 public static final String INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer";
96 public static final String BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean";
97 public static final String STRING_DATATYPE = "http://www.w3.org/2001/XMLSchema#string";
98 public static final String URI_DATATYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
99 public static final String RULE_VARIABLE = "var:";
100 public static final String EMPTY_STRING = "";
102 private static HtmlProcessor htmlProcessor;
104 private static File policyFile;
106 public static JSONObject DescribePolicy(final File policyFile) {
107 if (LOGGER.isTraceEnabled())
108 LOGGER.trace("ENTER");
110 HumanPolicyComponent.policyFile = policyFile;
111 return humanPolicyLayout();
115 private static JSONObject humanPolicyLayout() {
116 if (LOGGER.isTraceEnabled())
117 LOGGER.trace("ENTER");
120 String html = processPolicy();
121 JSONObject result = new JSONObject();
122 result.put("html", html);
125 } catch (IllegalArgumentException e) {
126 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "cannot build html area por policy", e);
131 private static String processPolicy() throws IllegalArgumentException {
132 if (LOGGER.isTraceEnabled())
133 LOGGER.trace("ENTER");
135 FileInputStream pIS = null;
137 pIS = new FileInputStream(policyFile);
138 Object policy = XACMLPolicyScanner.readPolicy(pIS);
140 throw new IllegalArgumentException("Policy File " + policyFile.getName() +
141 " cannot be unmarshalled");
143 HumanPolicyComponent.htmlProcessor =
144 new HtmlProcessor(HumanPolicyComponent.policyFile, policy);
146 Path policyPath = FileSystems.getDefault().getPath(policyFile.getAbsolutePath());
147 XACMLPolicyScanner xacmlScanner = new XACMLPolicyScanner(policyPath, htmlProcessor);
149 String html = htmlProcessor.html();
150 if (LOGGER.isDebugEnabled())
151 LOGGER.debug(policyPath + System.lineSeparator() + html);
155 } catch (Exception e) {
156 String msg = "Exception reading policy: " + policyFile.getAbsolutePath() +
157 ": " + e.getMessage();
158 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + msg, e);
159 throw new IllegalArgumentException(msg);
164 } catch (IOException e) {
165 LOGGER.warn(e.getMessage(), e);
173 class HtmlProcessor extends SimpleCallback {
175 private static final Logger LOGGER = FlexLogger.getLogger(HtmlProcessor.class);
177 private static Map<String, String> function2human;
179 function2human = new HashMap<>();
180 function2human.put(HumanPolicyComponent.FUNCTION_STRING_EQUAL, "equal");
181 function2human.put(HumanPolicyComponent.FUNCTION_STRING_EQUAL_IGNORE, "equal");
182 function2human.put(HumanPolicyComponent.FUNCTION_STRING_ONE_AND_ONLY, "one-and-only");
183 function2human.put(HumanPolicyComponent.FUNCTION_STRING_REGEX_MATCH, "matching regular expression");
184 function2human.put(HumanPolicyComponent.FUNTION_INTEGER_ONE_AND_ONLY, "one-and-only");
187 private static Map<String, String> combiningAlgo2human;
189 combiningAlgo2human = new HashMap<>();
190 combiningAlgo2human.put("deny-overrides", "to deny if any $placeholder$ below evaluates to <i>deny</i>");
191 combiningAlgo2human.put("permit-overrides", "to permit if any $placeholder$ below evaluates to <i>permit</i>");
193 combiningAlgo2human.put("ordered-deny-overrides", "to deny if any $placeholder$ below evaluates to <i>deny</i>");
194 combiningAlgo2human.put("ordered-permit-overrides", "to permit if any $placeholder$ below evaluates to <i>permit</i>");
195 combiningAlgo2human.put("deny-unless-permit", "to permit if any $placeholder$ below evaluates to <i>deny</i> and not <i>indeterminate</i>");
197 combiningAlgo2human.put("permit-unless-deny", "to deny if any $placeholder$ below evaluates to is <i>permit</i> and not <i>indeterminate</i>");
198 combiningAlgo2human.put("first-applicable", "to honour the result of the first successfully evaluated $placeholder$ in order");
199 combiningAlgo2human.put("only-one-applicable", "to honour the result of the first successfully evaluated $placeholder$ in order");
202 private Map<String, AttributeIdentifiers> attributeIdentifiersMap = new HashMap<String, AttributeIdentifiers>();
204 private final StringWriter stringWriter = new StringWriter();
205 private final PrintWriter htmlOut = new PrintWriter(stringWriter);
206 private final String policyName;
207 private final Object rootPolicyObject;
209 public HtmlProcessor(File policyFile, Object policyObject)
210 throws IllegalArgumentException {
211 if (LOGGER.isTraceEnabled())
212 LOGGER.trace("ENTER");
214 if (policyFile == null) {
215 LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Null Policy File");
216 throw new IllegalArgumentException("Null Policy File");
219 if (!policyFile.exists() || !policyFile.canRead()) {
220 String msg = "Can't access " + policyFile.getAbsolutePath();
221 LOGGER.error(XACMLErrorConstants.ERROR_PERMISSIONS + msg);
222 throw new IllegalArgumentException(msg);
225 if (policyObject == null ||
226 (!(policyObject instanceof PolicySetType) && !(policyObject instanceof PolicyType))) {
227 String msg = "Invalid unmarshalled object: " + policyObject;
228 LOGGER.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + msg);
229 throw new IllegalArgumentException(msg);
232 this.policyName = FilenameUtils.removeExtension(policyFile.getName());
233 this.rootPolicyObject = policyObject;
235 String version = "-";
236 if (policyObject instanceof PolicyType) {
237 PolicyType policy = (PolicyType) policyObject;
238 version = policy.getVersion();
239 htmlOut.println("<h1>Policy: " + policyName +
240 " (version " + version + ") </h1>");
243 PolicySetType policySet = (PolicySetType) policyObject;
244 version = policySet.getVersion();
245 htmlOut.println("<h1>Policy Set: " + policyName +
246 " (v" + version + ") </h1>");
249 htmlOut.println("<h3><b>Location: </b>" + policyFile.getPath() + "</h3>");
250 htmlOut.println("<hr>");
252 if (rootPolicyObject instanceof PolicySetType) {
253 if (policyName.startsWith("Config_")) {
254 htmlOut.println("<p>This is a <b>config</b> policy set.</p>");
255 } else if (policyName.startsWith("Action_")) {
256 htmlOut.println("<p>This is an <b>action</b> policy set.</p>");
258 htmlOut.println("<dl>");
260 if (policyName.startsWith("Config_")) {
261 htmlOut.println("<p>This is a <b>config</b> policy.</p>");
262 } else if (policyName.startsWith("Action_")) {
263 htmlOut.println("<p>This is an <b>action</b> policy.</p>");
265 htmlOut.println("<ol>");
270 * @return the attributeIdentifiersMap
272 public Map<String, AttributeIdentifiers> getAttributeIdentifiersMap() {
273 return attributeIdentifiersMap;
277 public void onFinishScan(Object root) {
278 if (LOGGER.isTraceEnabled())
279 LOGGER.trace("ENTER");
281 if (rootPolicyObject instanceof PolicySetType) {
282 htmlOut.println("</dl>");
284 htmlOut.println("</ol>");
287 htmlOut.println("<hr>");
289 htmlOut.println("<h3>Attribute Table:</h3>");
291 htmlOut.println("<table border=\"3\" style=\"width:100%\">");
292 htmlOut.println("<tr>");
293 htmlOut.print("<th>Category</th>");
294 htmlOut.print("<th>Type</th>");
295 htmlOut.print("<th>Identifier</th>");
296 htmlOut.println("</tr>");
297 for(Map.Entry<String, AttributeIdentifiers> entry : this.attributeIdentifiersMap.entrySet()){
298 AttributeIdentifiers value = entry.getValue();
299 htmlOut.println("<tr>");
300 htmlOut.print("<td><a name=\"" + entry.getKey() + "\"></a>" + value.category + "</td>");
301 htmlOut.print("<td>" + value.type + "</td>");
302 htmlOut.print("<td>" + value.id + "</td>");
303 htmlOut.println("</tr>");
305 htmlOut.println("</table>");
307 htmlOut.println("<p></p>");
309 // Not necessary for the user, uncomment if desired at some point
312 super.onFinishScan(root);
315 @SuppressWarnings("unused")
316 private void writeRawXACML() {
317 if (LOGGER.isTraceEnabled())
318 LOGGER.trace("ENTER");
320 htmlOut.println("<hr>");
321 htmlOut.println("<h3>Raw XACML:</h3>");
323 ByteArrayOutputStream bos = new ByteArrayOutputStream();
324 if (rootPolicyObject instanceof PolicySetType) {
325 XACMLPolicyWriterWithPapNotify.writePolicyFile(bos, (PolicySetType) rootPolicyObject);
326 } else if (rootPolicyObject instanceof PolicyType) {
327 XACMLPolicyWriterWithPapNotify.writePolicyFile(bos, (PolicyType) rootPolicyObject);
330 String xacml = bos.toString();
331 xacml = xacml.replaceAll("<", "<");
332 xacml = xacml.replaceAll(">", ">");
333 htmlOut.println("<pre>");
334 htmlOut.println(xacml);
335 htmlOut.println("</pre>");
339 public CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
340 if (LOGGER.isTraceEnabled())
341 LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Version: " + policySet.getVersion());
343 if (parent != null && LOGGER.isTraceEnabled())
344 LOGGER.trace("PolicySet: " + policySet.getPolicySetId() +
345 "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
347 String description = policySet.getDescription();
348 if (description != null && LOGGER.isTraceEnabled())
349 LOGGER.trace("PolicySet: " + policySet.getPolicySetId() +
350 " Description: " + policySet.getDescription());
352 if (parent == null) // root
353 policySet(policySet, "dl");
355 policySet(policySet, "li");
357 if (policySet.getPolicySetOrPolicyOrPolicySetIdReference().size() > 0)
358 htmlOut.println("<ol>");
360 return super.onPreVisitPolicySet(parent, policySet);
364 public CallbackResult onPostVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
365 if (LOGGER.isTraceEnabled())
366 LOGGER.trace("PolicySet: " + policySet.getPolicySetId() + " Version: " + policySet.getVersion());
368 if (parent != null && LOGGER.isTraceEnabled())
369 LOGGER.trace("PolicySet: " + policySet.getPolicySetId() +
370 "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
372 String description = policySet.getDescription();
373 if (description != null && LOGGER.isTraceEnabled())
374 LOGGER.trace("PolicySet: " + policySet.getPolicySetId() +
375 " Description: " + policySet.getDescription());
377 if (policySet.getPolicySetOrPolicyOrPolicySetIdReference().size() > 0)
378 htmlOut.println("</ol>");
380 htmlOut.println("<p></p>");
382 return super.onPostVisitPolicySet(parent, policySet);
385 public void policySet(PolicySetType policySet, String htmlListElement) {
386 if (LOGGER.isTraceEnabled())
387 LOGGER.trace("PolicySet: " + policySet.getPolicySetId());
389 String combiningAlgorithm = "-";
391 String version = "-";
394 if (policySet.getPolicyCombiningAlgId() != null)
395 combiningAlgorithm = extractLastIdentifier(policySet.getPolicyCombiningAlgId(), ":");
397 if (policySet.getPolicySetId() != null)
398 id = extractLastIdentifier(policySet.getPolicySetId(), ":");
400 if (policySet.getVersion() != null)
401 version = policySet.getVersion();
404 htmlOut.println("<" + htmlListElement + "><b>Policy Set ID</b>: <i>" + id +
405 "</i> (v" + version + ") " + "</" + htmlListElement + ">");
407 if (policySet.getTarget() == null ||
408 policySet.getTarget().getAnyOf() == null ||
409 policySet.getTarget().getAnyOf().size() <= 0) {
410 htmlOut.println("<p>This policy set applies to all requests.</p>");
412 htmlOut.print("<p>");
413 htmlOut.print("This policy set applies to requests with attributes ");
415 List<AnyOfType> anyOf_s = policySet.getTarget().getAnyOf();
417 htmlOut.println(".</p>");
420 if (policySet.getPolicySetOrPolicyOrPolicySetIdReference() != null &&
421 policySet.getPolicySetOrPolicyOrPolicySetIdReference().size() > 0) {
422 String algoDesc = combiningAlgo2human.get(combiningAlgorithm);
423 if (algoDesc != null) {
424 algoDesc = algoDesc.replace("$placeholder$", "policy") + " (" + "<i>" + combiningAlgorithm + "</i>)";
426 algoDesc = combiningAlgorithm;
429 htmlOut.println("<p>The result is " + algoDesc + ": </p>");
434 public CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy) {
435 if (LOGGER.isTraceEnabled())
436 LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Version: " + policy.getVersion());
438 if (parent != null && LOGGER.isTraceEnabled())
439 LOGGER.trace("PolicySet: " + policy.getPolicyId() +
440 "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
442 String description = policy.getDescription();
443 if (description != null && LOGGER.isTraceEnabled())
444 LOGGER.trace("PolicySet: " + policy.getPolicyId() +
445 " Description: " + policy.getDescription());
449 if (policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().size() > 0)
450 htmlOut.println("<ol type=\"i\">");
452 return super.onPreVisitPolicy(parent, policy);
456 public CallbackResult onPostVisitPolicy(PolicySetType parent, PolicyType policy) {
457 if (LOGGER.isTraceEnabled())
458 LOGGER.trace("PolicySet: " + policy.getPolicyId() + " Version: " + policy.getVersion());
460 if (parent != null && LOGGER.isTraceEnabled())
461 LOGGER.trace("PolicySet: " + policy.getPolicyId() +
462 "Parent PolicySet: " + parent.getPolicySetId() + " Version: " + parent.getVersion());
464 if (policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().size() > 0)
465 htmlOut.println("</ol>");
467 htmlOut.println("<p></p>");
468 return super.onPostVisitPolicy(parent, policy);
471 public void policy(PolicyType policy) {
472 if (LOGGER.isTraceEnabled())
473 LOGGER.trace("Policy: " + policy.getPolicyId());
475 String combiningAlgorithm = "-";
477 String version = "-";
480 if (policy.getRuleCombiningAlgId() != null)
481 combiningAlgorithm = extractLastIdentifier(policy.getRuleCombiningAlgId(), ":");
483 if (policy.getPolicyId() != null)
484 id = extractLastIdentifier(policy.getPolicyId(), ":");
486 if (policy.getVersion() != null)
487 version = policy.getVersion();
489 htmlOut.println("<li><b>Policy ID</b>: <i>" + id +
490 "</i> (v" + version + ") " + "</li>");
492 if (policy.getTarget() == null ||
493 policy.getTarget().getAnyOf() == null ||
494 policy.getTarget().getAnyOf().size() <= 0) {
495 htmlOut.println("<p>This policy applies to all requests.</p>");
497 htmlOut.print("<p>");
498 htmlOut.print("This policy applies to requests with attributes ");
500 List<AnyOfType> anyOf_s = policy.getTarget().getAnyOf();
502 htmlOut.println(".</p>");
505 if (policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition() != null &&
506 policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().size() > 0) {
507 String algoDesc = combiningAlgo2human.get(combiningAlgorithm);
508 if (algoDesc != null) {
509 algoDesc = algoDesc.replace("$placeholder$", "rule") + " (<i>" + combiningAlgorithm + "</i>)";
511 algoDesc = combiningAlgorithm;
513 htmlOut.println("<p>The result is " + algoDesc + ": </p>");
519 public CallbackResult onPreVisitRule(PolicyType parent, RuleType rule) {
520 if (LOGGER.isTraceEnabled())
521 LOGGER.trace("Rule: " + rule.getRuleId());
523 if (parent != null && LOGGER.isTraceEnabled())
524 LOGGER.trace("Parent Policy: " + parent.getPolicyId() + " Version: " + parent.getVersion());
526 String description = rule.getDescription();
527 if (description != null && LOGGER.isTraceEnabled()) {
528 LOGGER.trace("Rule: " + rule.getRuleId() +
529 " Description: " + rule.getDescription());
534 return super.onPreVisitRule(parent, rule);
538 public CallbackResult onPostVisitRule(PolicyType parent, RuleType rule) {
539 if (LOGGER.isTraceEnabled())
540 LOGGER.trace("Rule: " + rule.getRuleId());
542 if (parent != null && LOGGER.isTraceEnabled())
543 LOGGER.trace("Parent Policy: " + parent.getPolicyId() + " Version: " + parent.getVersion());
545 return super.onPostVisitRule(parent, rule);
548 public void rule(RuleType rule) {
549 if (LOGGER.isTraceEnabled())
550 LOGGER.trace("Rule: " + rule.getRuleId());
554 if (rule.getRuleId() != null)
555 id = extractLastIdentifier(rule.getRuleId(), ":");
557 htmlOut.println("<li><b>Rule ID</b>: <i>" + id + "</i></li>");
559 htmlOut.println("<dl>");
561 htmlOut.print("<p>");
562 htmlOut.print(rule.getEffect().value());
564 if (rule.getTarget() == null ||
565 rule.getTarget().getAnyOf() == null ||
566 rule.getTarget().getAnyOf().size() <= 0) {
567 htmlOut.print(" for all requests");
569 List<AnyOfType> anyOf_s = rule.getTarget().getAnyOf();
570 htmlOut.print(" for requests with attributes ");
574 if (rule.getCondition() != null) {
575 htmlOut.print(" when ");
576 htmlOut.println(this.stringifyCondition(rule.getCondition()) + " ");
578 htmlOut.print(" with no conditions ");
581 if (rule.getAdviceExpressions() != null) {
582 advice(rule.getAdviceExpressions());
583 if (rule.getObligationExpressions() != null)
584 htmlOut.println(" and ");
587 if (rule.getObligationExpressions() != null) {
588 obligation(rule.getObligationExpressions());
591 htmlOut.println("</p>");
594 private void advice(AdviceExpressionsType adviceExpressions) {
595 if (LOGGER.isTraceEnabled())
596 LOGGER.trace("ENTER");
598 List<AdviceExpressionType> ae = adviceExpressions.getAdviceExpression();
599 for (AdviceExpressionType expression : ae) {
600 htmlOut.println(" with <b>advice</b> (<i>" + expression.getAdviceId() + "</i>) on <i>" +
601 expression.getAppliesTo().value() + "</i>:" );
602 htmlOut.println("<ol type=\"a\">");
603 List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
604 if (assignments != null) {
605 processAttributeAssignments(assignments);
607 htmlOut.println("</ol>");
611 private void obligation(ObligationExpressionsType obligationExpressions) {
612 if (LOGGER.isTraceEnabled())
613 LOGGER.trace("ENTER");
615 List<ObligationExpressionType> oe = obligationExpressions.getObligationExpression();
616 for (ObligationExpressionType expression : oe) {
617 htmlOut.println(" with <b>obligations</b> (<i>" + expression.getObligationId() + "</i>) to be fullfilled on <i>" +
618 expression.getFulfillOn().value() + "</i>:" );
619 htmlOut.println("<ol type=\"a\">");
620 List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
621 if (assignments != null) {
622 processAttributeAssignments(assignments);
624 htmlOut.println("</ol>");
631 private void processAttributeAssignments(List<AttributeAssignmentExpressionType> assignments) {
632 if (LOGGER.isTraceEnabled())
633 LOGGER.trace("ENTER");
635 for (AttributeAssignmentExpressionType assignment : assignments) {
636 String succintIdentifier = extractLastIdentifier(assignment.getCategory(), ":") +
637 ":" + extractLastIdentifier(assignment.getAttributeId(), ":");
638 AttributeIdentifiers attributeIdentifiers = null;
639 if (!this.attributeIdentifiersMap.containsKey(succintIdentifier)) {
640 // Note Attribute Assignments do not have an Attribute Type, assume string
641 // but note this case is unlikely since attributeMap should have been populated
642 // during parsing of target and conditions, and not in this case for Advice and
644 attributeIdentifiers = new AttributeIdentifiers(assignment.getCategory(),
646 assignment.getAttributeId());
647 this.attributeIdentifiersMap.put(succintIdentifier, attributeIdentifiers);
650 htmlOut.print("<li><i><a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a></i> is ");
651 // AttributeValueType
652 JAXBElement<?> jaxbExp = assignment.getExpression();
653 Object assignmentObject = jaxbExp.getValue();
654 if (assignmentObject instanceof AttributeValueType) {
655 AttributeValueType avt = (AttributeValueType) assignmentObject;
656 if (attributeIdentifiers != null) {
657 attributeIdentifiers.type = avt.getDataType();
659 int numContent = avt.getContent().size();
660 int countContent = 0;
661 for (Object c: avt.getContent()) {
663 htmlOut.print("<i>" + c + "</i>");
664 if (countContent < numContent)
665 htmlOut.print(" or ");
667 htmlOut.println("</li>");
668 } else if (assignmentObject instanceof AttributeDesignatorType) {
669 htmlOut.println("NA");
670 } else if (assignmentObject instanceof AttributeSelectorType) {
671 htmlOut.println("NA");
672 } else if (assignmentObject instanceof ApplyType) {
673 htmlOut.println("NA");
675 htmlOut.println("Unexpected");
684 public void target(List<AnyOfType> anyOfList) {
685 if (LOGGER.isTraceEnabled())
686 LOGGER.trace("ENTER");
688 if (anyOfList != null) {
689 Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
690 String targetInHuman = "";
691 while (iterAnyOf.hasNext()) {
692 AnyOfType anyOf = iterAnyOf.next();
693 List<AllOfType> allOfList = anyOf.getAllOf();
694 if (allOfList != null) {
695 Iterator<AllOfType> iterAllOf = allOfList.iterator();
696 while (iterAllOf.hasNext()) {
697 AllOfType allOf = iterAllOf.next();
698 List<MatchType> matchList = allOf.getMatch();
699 if (matchList != null) {
700 Iterator<MatchType> iterMatch = matchList.iterator();
701 if (matchList.size() > 1)
702 targetInHuman += "(";
703 while (iterMatch.hasNext()) {
704 MatchType match = iterMatch.next();
706 // Finally down to the actual attribute
708 StdAttribute attribute = null;
709 AttributeValueType value = match.getAttributeValue();
710 String attributeDataType = null;
711 if (match.getAttributeDesignator() != null && value != null) {
712 AttributeDesignatorType designator = match.getAttributeDesignator();
713 attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()),
714 new IdentifierImpl(designator.getAttributeId()),
715 new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
716 designator.getIssuer(),
718 attributeDataType = designator.getDataType();
719 } else if (match.getAttributeSelector() != null && value != null) {
720 AttributeSelectorType selector = match.getAttributeSelector();
721 attribute = new StdAttribute(new IdentifierImpl(selector.getCategory()),
722 new IdentifierImpl(selector.getContextSelectorId()),
723 new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
726 attributeDataType = selector.getDataType();
728 LOGGER.warn("NULL designator/selector or value for match.");
729 attributeDataType = "NA";
732 String functionName = getHumanFunction(match.getMatchId());
734 String succintIdentifier = extractLastIdentifier(attribute.getCategory().stringValue(), ":") +
735 ":" + extractLastIdentifier(attribute.getAttributeId().stringValue(), ":");
736 AttributeIdentifiers ai = new AttributeIdentifiers(attribute.getCategory().stringValue(),
738 attribute.getAttributeId().stringValue());
739 this.attributeIdentifiersMap.put(succintIdentifier,ai);
741 targetInHuman += "<i><a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a></i> " + functionName + " ";
743 int numAttributes = attribute.getValues().size();
745 for (AttributeValue<?> v: attribute.getValues()) {
747 if (v.getValue() instanceof Collection<?>) {
748 Collection<?> value_s = (Collection<?>) v.getValue();
749 int numValues = value_s.size();
751 for (Object o : value_s) {
753 targetInHuman += " <I>" + o + "</I>";
754 if (countValues < numValues) {
755 targetInHuman += ", or";
759 targetInHuman += " <I>" + v.getValue() + "</I>";
760 if (count < numAttributes) {
761 targetInHuman += ", or ";
766 if (iterMatch.hasNext()) {
767 targetInHuman += " and ";
770 if (matchList.size() > 1) {
771 targetInHuman += ")";
774 if (iterAllOf.hasNext()) {
775 targetInHuman += " or ";
779 if (iterAnyOf.hasNext()) {
780 targetInHuman = "(" + targetInHuman + ")" + " or ";
782 if (anyOfList.size() > 1) {
783 targetInHuman += ")";
787 htmlOut.println(targetInHuman);
791 private String getHumanFunction(String matchId) {
792 if (HtmlProcessor.function2human.containsKey(matchId)) {
793 return HtmlProcessor.function2human.get(matchId);
796 FunctionDefinition function = PolicyController.getFunctionIDMap().get(matchId);
797 String functionName = function.getShortname();
799 if (LOGGER.isDebugEnabled()) {
800 LOGGER.debug(functionName +
801 ": #args[" + function.getArgLb() + "," + function.getArgUb() +"]");
804 return extractLastIdentifier(removePrimitives(functionName), ":");
807 public String html() {
808 this.htmlOut.flush();
809 return this.stringWriter.toString();
812 private String extractLastIdentifier(String in, String separator) {
813 int lastIndex = in.lastIndexOf(separator);
817 return in.substring(lastIndex+1);
820 private String removePrimitives(String in) {
821 in = in.replace("string-", "");
822 in = in.replace("integer-", "");
823 in = in.replace("double-", "");
824 in = in.replace("boolean-", "");
828 private String stringifyCondition(ConditionType condition) {
829 if (condition.getExpression() == null) {
833 return stringifyExpression(condition.getExpression().getValue());
836 private String stringifyExpression(Object expression) {
837 if (expression instanceof ApplyType) {
838 ApplyType apply = (ApplyType) expression;
839 FunctionDefinition function = PolicyController.getFunctionIDMap().get(apply.getFunctionId());
840 String functionName = function.getShortname();
842 if (LOGGER.isDebugEnabled()) {
843 LOGGER.debug(functionName +
844 ": #args[" + function.getArgLb() + "," + function.getArgUb() +"]");
847 if (functionName.contains("one-and-only")) {
848 if (LOGGER.isDebugEnabled()) {
849 LOGGER.debug("one-and-only found: " + functionName);
852 List<JAXBElement<?>> exps = apply.getExpression();
853 if (exps == null || exps.size() == 0)
856 String forResult = "";
857 for (JAXBElement<?> e : exps) {
858 Object v = e.getValue();
859 if (LOGGER.isDebugEnabled()) {
860 LOGGER.debug("one-and-only children: " + v);
863 // C: return stringifyExpression(v, result);
864 forResult += stringifyExpression(v);
871 final int numExpr = (apply.getExpression() == null) ? -1 : apply.getExpression().size();
873 if (LOGGER.isDebugEnabled()) {
874 LOGGER.debug(functionName + " 0 expressions: " + numExpr);
877 } else if (numExpr == 1) {
879 if (LOGGER.isDebugEnabled()) {
880 LOGGER.debug(functionName + " 1 expression: " + numExpr);
882 String applySubresult = "";
883 for (JAXBElement<?> e : apply.getExpression()) {
884 Object v = e.getValue();
886 applySubresult += this.stringifyExpression(e.getValue());
889 return " " + removePrimitives(functionName) + " (" + applySubresult + ")";
892 if (LOGGER.isDebugEnabled()) {
893 LOGGER.debug(functionName + " > 1 expressions: " + numExpr);
895 String applySubresult = "";
897 for (JAXBElement<?> e : apply.getExpression()) {
899 Object ev = e.getValue();
901 if (ev instanceof ApplyType) {
902 if (((ApplyType) ev).getFunctionId().contains("one-and-only")) {
903 applySubresult += this.stringifyExpression(e.getValue());
905 applySubresult += "(" + this.stringifyExpression(e.getValue()) + ")";
908 applySubresult += this.stringifyExpression(e.getValue());
911 if (exprCount < numExpr) {
912 applySubresult += " " + removePrimitives(functionName) + " ";
916 return applySubresult;
919 if (expression instanceof AttributeDesignatorType) {
920 AttributeDesignatorType adt = (AttributeDesignatorType) expression;
922 String succintIdentifier = extractLastIdentifier(adt.getCategory(), ":") +
923 ":" + extractLastIdentifier(adt.getAttributeId(), ":");
924 AttributeIdentifiers ai = new AttributeIdentifiers(adt.getCategory(),
926 adt.getAttributeId());
927 this.attributeIdentifiersMap.put(succintIdentifier,ai);
929 return "<a href=\"#" + succintIdentifier + "\">" + succintIdentifier + "</a>";
931 if (expression instanceof AttributeSelectorType) {
932 AttributeSelectorType ast = (AttributeSelectorType) expression;
934 String attrName = ast.getPath();
935 if (attrName == null || (attrName.length() == 0)) {
939 String textSelector = "/text()";
940 if (attrName.endsWith(textSelector)) {
941 attrName = attrName.substring(0, attrName.length() - textSelector.length());
944 attrName = extractLastIdentifier(attrName, "/");
945 attrName = extractLastIdentifier(attrName, ":");
946 return " " + attrName;
948 if (expression instanceof AttributeValueType) {
949 AttributeValueType avt = (AttributeValueType) expression;
950 List<Object> content = avt.getContent();
952 for (Object o: content) {
953 value_s += " " + o.toString();
955 return " " + value_s;
957 if (expression instanceof VariableReferenceType) {
959 // Really unknown - the variable may or may not have been defined
961 return " VARIABLEREF-NOT-HANDLED";
963 throw new IllegalArgumentException("Unexpected input expression");
969 class AttributeIdentifiers {
970 public final String category;
972 public final String id;
974 public AttributeIdentifiers(String category, String type, String id) {
975 this.category = category;