Format ONAP-XACML and add JUnit
[policy/engine.git] / ONAP-XACML / src / main / java / org / onap / policy / xacml / util / XACMLPolicyScanner.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-XACML
4  * ================================================================================
5  * Copyright (C) 2017-2019 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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.policy.xacml.util;
22
23 import com.att.research.xacml.api.AttributeAssignment;
24 import com.att.research.xacml.std.IdentifierImpl;
25 import com.att.research.xacml.std.StdAttribute;
26 import com.att.research.xacml.std.StdAttributeAssignment;
27 import com.att.research.xacml.std.StdAttributeValue;
28 import com.att.research.xacml.std.StdMutableAdvice;
29 import com.att.research.xacml.std.StdMutableObligation;
30 import com.att.research.xacml.util.XACMLPolicyScanner.Callback;
31 import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult;
32
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.util.Arrays;
38 import java.util.Iterator;
39 import java.util.List;
40
41 import javax.xml.bind.JAXBContext;
42 import javax.xml.bind.JAXBElement;
43 import javax.xml.bind.Unmarshaller;
44 import javax.xml.parsers.DocumentBuilder;
45 import javax.xml.parsers.DocumentBuilderFactory;
46
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
52 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
53 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
54 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
55 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
58 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
59 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
60 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
61 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
62 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
63 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
64
65 import org.apache.commons.logging.Log;
66 import org.apache.commons.logging.LogFactory;
67 import org.onap.policy.common.logging.eelf.MessageCodes;
68 import org.onap.policy.common.logging.eelf.PolicyLogger;
69 import org.w3c.dom.Document;
70 import org.w3c.dom.Element;
71
72 /**
73  * class XACMLPolicyScanner.
74  *
75  * <p>This class traverses the hierarchy of a XACML 3.0 policy. You can optionally pass a Callback class
76  * and override any desired methods to retrieve information from a policy.
77  *
78  *
79  */
80 public class XACMLPolicyScanner {
81
82     private static final Log logger = LogFactory.getLog(XACMLPolicyScanner.class);
83     private Object policyObject = null;
84     private Callback callback = null;
85
86     /**
87      * constructor.
88      *
89      * @param filename Path
90      * @param callback Callback
91      */
92     public XACMLPolicyScanner(Path filename, Callback callback) {
93         try (InputStream is = Files.newInputStream(filename)) {
94             this.policyObject = XACMLPolicyScanner.readPolicy(is);
95         } catch (IOException e) {
96             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
97         }
98         this.callback = callback;
99     }
100
101     /**
102      * Constructor.
103      *
104      * @param filename InputStream
105      * @param callback Callback
106      */
107     public XACMLPolicyScanner(InputStream filename, Callback callback) {
108         try (InputStream is = filename) {
109             this.policyObject = XACMLPolicyScanner.readPolicy(is);
110         } catch (IOException e) {
111             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
112         }
113         this.callback = callback;
114     }
115
116     public XACMLPolicyScanner(PolicySetType policySet, Callback callback) {
117         this.policyObject = policySet;
118         this.callback = callback;
119     }
120
121     public XACMLPolicyScanner(PolicySetType policySet) {
122         this(policySet, null);
123     }
124
125     public XACMLPolicyScanner(PolicyType policy, Callback callback) {
126         this.policyObject = policy;
127         this.callback = callback;
128     }
129
130     public XACMLPolicyScanner(PolicyType policy) {
131         this(policy, null);
132     }
133
134     /**
135      * Sets the callback interface to be used.
136      *
137      * @param cb Callback object
138      */
139     public void setCallback(Callback cb) {
140         this.callback = cb;
141     }
142
143     /**
144      * Saves the given callback object then calls the scan() method.
145      *
146      * @param cb Callback object
147      * @return
148      */
149     public Object scan(Callback cb) {
150         this.callback = cb;
151         return this.scan();
152     }
153
154     /**
155      * This begins the scanning of the contained object.
156      *
157      * @return - The PolicySet/Policy that was scanned.
158      */
159     public Object scan() {
160         if (this.policyObject == null) {
161             return null;
162         }
163         if (this.callback != null && this.callback.onBeginScan(this.policyObject) == CallbackResult.STOP) {
164             return this.policyObject;
165         }
166         if (this.policyObject instanceof PolicyType) {
167             this.scanPolicy(null, (PolicyType) this.policyObject);
168         } else if (this.policyObject instanceof PolicySetType) {
169             this.scanPolicySet(null, (PolicySetType) this.policyObject);
170         } else {
171             PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + "Unknown class type: "
172                     + this.policyObject.getClass().getCanonicalName());
173         }
174         if (this.callback != null) {
175             this.callback.onFinishScan(this.policyObject);
176         }
177         return this.policyObject;
178     }
179
180     /**
181      * This performs the scan of a PolicySet.
182      *
183      * @param parent - Its parent PolicySet. Can be null if this is the root.
184      * @param policySet - The PolicySet object.
185      * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
186      */
187     protected CallbackResult scanPolicySet(PolicySetType parent, PolicySetType policySet) {
188         if (logger.isTraceEnabled()) {
189             logger.trace("scanning policy set: " + policySet.getPolicySetId() + " " + policySet.getDescription());
190         }
191         if (this.callback != null && this.callback.onPreVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
192             return CallbackResult.STOP;
193         }
194         //
195         // Scan its info
196         //
197         if (this.scanTarget(policySet, policySet.getTarget()) == CallbackResult.STOP) {
198             return CallbackResult.STOP;
199         }
200         if (this.scanObligations(policySet, policySet.getObligationExpressions()) == CallbackResult.STOP) {
201             return CallbackResult.STOP;
202         }
203         if (this.scanAdvice(policySet, policySet.getAdviceExpressions()) == CallbackResult.STOP) {
204             return CallbackResult.STOP;
205         }
206         //
207         // Iterate the policy sets and/or policies
208         //
209         List<JAXBElement<?>> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference();
210         for (JAXBElement<?> element : list) {
211             if ("PolicySet".equals(element.getName().getLocalPart())
212                     && this.scanPolicySet(policySet, (PolicySetType) element.getValue()) == CallbackResult.STOP) {
213                 return CallbackResult.STOP;
214             } else if ("Policy".equals(element.getName().getLocalPart())
215                     && this.scanPolicy(policySet, (PolicyType) element.getValue()) == CallbackResult.STOP) {
216                 return CallbackResult.STOP;
217             } else {
218                 logger.warn("generating policy sets found unsupported element: " + element.getName().getNamespaceURI());
219             }
220         }
221         if (this.callback != null && this.callback.onPostVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
222             return CallbackResult.STOP;
223         }
224         return CallbackResult.CONTINUE;
225     }
226
227     /**
228      * This performs scanning of the Policy object.
229      *
230      * @param parent - The parent PolicySet of the policy. This can be null if this is a root Policy.
231      * @param policy - The policy being scanned.
232      * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
233      */
234     protected CallbackResult scanPolicy(PolicySetType parent, PolicyType policy) {
235         if (logger.isTraceEnabled()) {
236             logger.trace("scanning policy: " + policy.getPolicyId() + " " + policy.getDescription());
237         }
238         if (this.callback != null && this.callback.onPreVisitPolicy(parent, policy) == CallbackResult.STOP) {
239             return CallbackResult.STOP;
240         }
241         //
242         // Scan its info
243         //
244         if (this.scanTarget(policy, policy.getTarget()) == CallbackResult.STOP) {
245             return CallbackResult.STOP;
246         }
247         if (this.scanVariables(policy,
248                 policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) == CallbackResult.STOP) {
249             return CallbackResult.STOP;
250         }
251         if (this.scanObligations(policy, policy.getObligationExpressions()) == CallbackResult.STOP) {
252             return CallbackResult.STOP;
253         }
254         if (this.scanAdvice(policy, policy.getAdviceExpressions()) == CallbackResult.STOP) {
255             return CallbackResult.STOP;
256         }
257         //
258         // Iterate the rules
259         //
260         List<Object> list = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
261         for (Object o : list) {
262             if (o instanceof RuleType) {
263                 RuleType rule = (RuleType) o;
264                 if (logger.isTraceEnabled()) {
265                     logger.trace("scanning rule: " + rule.getRuleId() + " " + rule.getDescription());
266                 }
267                 if (this.callback != null && this.callback.onPreVisitRule(policy, rule) == CallbackResult.STOP) {
268                     return CallbackResult.STOP;
269                 }
270                 if (this.scanTarget(rule, rule.getTarget()) == CallbackResult.STOP) {
271                     return CallbackResult.STOP;
272                 }
273                 if (this.scanConditions(rule, rule.getCondition()) == CallbackResult.STOP) {
274                     return CallbackResult.STOP;
275                 }
276                 if (this.scanObligations(rule, rule.getObligationExpressions()) == CallbackResult.STOP) {
277                     return CallbackResult.STOP;
278                 }
279                 if (this.scanAdvice(rule, rule.getAdviceExpressions()) == CallbackResult.STOP) {
280                     return CallbackResult.STOP;
281                 }
282                 if (this.callback != null && this.callback.onPostVisitRule(policy, rule) == CallbackResult.STOP) {
283                     return CallbackResult.STOP;
284                 }
285             } else if (o instanceof VariableDefinitionType) {
286                 if (this.callback != null
287                         && this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) {
288                     return CallbackResult.STOP;
289                 }
290             } else {
291                 if (logger.isDebugEnabled()) {
292                     logger.debug("scanning policy rules found unsupported object:" + o.toString());
293                 }
294             }
295         }
296         if (this.callback != null && this.callback.onPostVisitPolicy(parent, policy) == CallbackResult.STOP) {
297             return CallbackResult.STOP;
298         }
299         return CallbackResult.CONTINUE;
300     }
301
302     /**
303      * Scans the given target for attributes. Its sole purpose is to return attributes found.
304      *
305      * @param parent - The parent PolicySet/Policy/Rule for the target.
306      * @param target - The target.
307      * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
308      */
309     protected CallbackResult scanTarget(Object parent, TargetType target) {
310         if (target == null) {
311             return CallbackResult.CONTINUE;
312         }
313         for (AnyOfType anyOf : target.getAnyOf()) {
314             for (AllOfType allOf : anyOf.getAllOf()) {
315                 for (MatchType match : allOf.getMatch()) {
316                     //
317                     // Finally down to the actual attribute
318                     //
319                     StdAttribute attribute = null;
320                     AttributeValueType value = match.getAttributeValue();
321                     if (match.getAttributeDesignator() != null && value != null) {
322                         AttributeDesignatorType designator = match.getAttributeDesignator();
323                         //
324                         // The content may be tricky
325                         //
326                         attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()),
327                                 new IdentifierImpl(designator.getAttributeId()),
328                                 new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()),
329                                         value.getContent()),
330                                 designator.getIssuer(), false);
331                     } else if (match.getAttributeSelector() != null && value != null) {
332                         AttributeSelectorType selector = match.getAttributeSelector();
333                         attribute = new StdAttribute(new IdentifierImpl(selector.getCategory()),
334                                 new IdentifierImpl(selector.getContextSelectorId()),
335                                 new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()),
336                                         value.getContent()),
337                                 null, false);
338                     } else {
339                         logger.warn("NULL designator/selector or value for match.");
340                     }
341                     if (attribute != null && this.callback != null && this.callback.onAttribute(parent,
342                             target, attribute) == CallbackResult.STOP) {
343                         return CallbackResult.STOP;
344                     }
345                 }
346             }
347         }
348         return CallbackResult.CONTINUE;
349     }
350
351     /**
352      * Scan the list of obligations.
353      *
354      * @param parent - The parent PolicySet/Policy/Rule for the obligation.
355      * @param obligationExpressionsType - All the obligation expressions.
356      * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
357      */
358     protected CallbackResult scanObligations(Object parent, ObligationExpressionsType obligationExpressionsType) {
359         if (obligationExpressionsType == null) {
360             return CallbackResult.CONTINUE;
361         }
362         List<ObligationExpressionType> expressions = obligationExpressionsType.getObligationExpression();
363         for (ObligationExpressionType expression : expressions) {
364             StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(expression.getObligationId()));
365             for (AttributeAssignmentExpressionType assignment : expression.getAttributeAssignmentExpression()) {
366                 // category is optional and may be null
367                 IdentifierImpl categoryId = null;
368                 if (assignment.getCategory() != null) {
369                     categoryId = new IdentifierImpl(assignment.getCategory());
370                 }
371                 AttributeAssignment attribute =
372                         new StdAttributeAssignment(categoryId, new IdentifierImpl(assignment.getAttributeId()),
373                                 assignment.getIssuer(), new StdAttributeValue<Object>(null, null));
374                 ob.addAttributeAssignment(attribute);
375             }
376             if (this.callback != null && this.callback.onObligation(parent, expression, ob) == CallbackResult.STOP) {
377                 return CallbackResult.STOP;
378             }
379         }
380         return CallbackResult.CONTINUE;
381     }
382
383     /**
384      * Scans the list of advice expressions returning each individually.
385      *
386      * @param parent - The parent PolicySet/Policy/Rule for the advice.
387      * @param adviceExpressionstype - The list of advice expressions.
388      * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
389      */
390     protected CallbackResult scanAdvice(Object parent, AdviceExpressionsType adviceExpressionstype) {
391         if (adviceExpressionstype == null) {
392             return CallbackResult.CONTINUE;
393         }
394         List<AdviceExpressionType> expressions = adviceExpressionstype.getAdviceExpression();
395         for (AdviceExpressionType expression : expressions) {
396             StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId()));
397             for (AttributeAssignmentExpressionType assignment : expression.getAttributeAssignmentExpression()) {
398                 IdentifierImpl categoryId = null;
399                 if (assignment.getCategory() != null) {
400                     categoryId = new IdentifierImpl(assignment.getCategory());
401                 }
402                 AttributeAssignment attribute =
403                         new StdAttributeAssignment(categoryId, new IdentifierImpl(assignment.getAttributeId()),
404                                 assignment.getIssuer(), new StdAttributeValue<Object>(null, null));
405                 ob.addAttributeAssignment(attribute);
406             }
407             if (this.callback != null && this.callback.onAdvice(parent, expression, ob) == CallbackResult.STOP) {
408                 return CallbackResult.STOP;
409             }
410         }
411         return CallbackResult.CONTINUE;
412     }
413
414     /**
415      * Scans the list of variable definitions.
416      *
417      * @param policy - Policy object containing the variable definition.
418      * @param list - List of variable definitions.
419      * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
420      */
421     protected CallbackResult scanVariables(PolicyType policy, List<Object> list) {
422         if (list == null) {
423             return CallbackResult.CONTINUE;
424         }
425         for (Object o : list) {
426             if (o instanceof VariableDefinitionType && this.callback != null
427                     && this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) {
428                 return CallbackResult.STOP;
429             }
430         }
431
432         return CallbackResult.CONTINUE;
433     }
434
435     /**
436      * Scans the list of conditions.
437      *
438      * @param rule RuleType
439      * @param condition ConditionType
440      * @return CallbackResult
441      */
442     protected CallbackResult scanConditions(RuleType rule, ConditionType condition) {
443         if (condition != null && this.callback != null
444                 && this.callback.onCondition(rule, condition) == CallbackResult.STOP) {
445             return CallbackResult.STOP;
446         }
447         return CallbackResult.CONTINUE;
448     }
449
450     /**
451      * Reads the XACML XML policy file in and returns the version contained in the root Policy/PolicySet element.
452      *
453      * @param policy - The policy file.
454      * @return - The version string from the file (uninterpreted)
455      * @throws IOException IOException
456      */
457     public static String getVersion(Path policy) throws IOException {
458         Object data = null;
459         try (InputStream is = Files.newInputStream(policy)) {
460             data = XACMLPolicyScanner.readPolicy(is);
461         } catch (IOException e) {
462             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
463             throw e;
464         }
465         if (data == null) {
466             logger.warn("Version is null.");
467             return null;
468         }
469         return getVersion(data);
470     }
471
472     /**
473      * Reads the Policy/PolicySet element object and returns its current version.
474      *
475      * @param data - Either a PolicySet or Policy XACML type object.
476      * @return - The integer version value. -1 if it doesn't exist or was un-parsable.
477      */
478     public static String getVersion(Object data) {
479         String version = null;
480         if (data instanceof PolicySetType) {
481             version = ((PolicySetType) data).getVersion();
482         } else if (data instanceof PolicyType) {
483             version = ((PolicyType) data).getVersion();
484         } else {
485             if (data != null) {
486                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: "
487                         + data.getClass().getCanonicalName());
488             }
489             return null;
490         }
491         if (version != null && version.length() > 0) {
492             return version;
493         }
494         logger.warn("No version set in policy");
495         return null;
496     }
497
498     /**
499      * Returns the Policy or PolicySet ID.
500      *
501      * @param data - A XACML 3.0 Policy or PolicySet element object.
502      * @return The policy/policyset's policy ID
503      */
504     public static String getID(Object data) {
505         if (data instanceof PolicySetType) {
506             return ((PolicySetType) data).getPolicySetId();
507         } else if (data instanceof PolicyType) {
508             return ((PolicyType) data).getPolicyId();
509         } else {
510             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: "
511                     + data.getClass().getCanonicalName());
512             return null;
513         }
514     }
515
516     /**
517      * getCreatedByModifiedBy.
518      *
519      * @param policyPath Path
520      * @return List of String
521      * @throws IOException IOException
522      */
523     public static List<String> getCreatedByModifiedBy(Path policyPath) throws IOException {
524         String createdBy = "";
525         String modifiedBy = "";
526         String createdValue = "@CreatedBy:";
527         String modifiedValue = "@ModifiedBy:";
528         for (String line : Files.readAllLines(policyPath)) {
529             line = line.replaceAll("\\s+", "");
530             if (line.isEmpty()) {
531                 continue;
532             }
533             if (line.contains("<Description>") && line.contains(createdValue) && line.contains(modifiedValue)) {
534                 createdBy = line.substring(line.indexOf(createdValue) + createdValue.length(),
535                         line.lastIndexOf(createdValue));
536                 modifiedBy = line.substring(line.indexOf(modifiedValue) + modifiedValue.length(),
537                         line.lastIndexOf(modifiedValue));
538                 break;
539             }
540         }
541         return Arrays.asList(createdBy, modifiedBy);
542     }
543
544     // get the Created Name of the User on reading the Xml file
545     /**
546      * getCreatedBy.
547      *
548      * @param policyPath Path
549      * @return String
550      * @throws IOException IOException
551      */
552     public static String getCreatedBy(Path policyPath) throws IOException {
553         String userId = "";
554         String value = "@CreatedBy:";
555         for (String line : Files.readAllLines(policyPath)) {
556             line = line.replaceAll("\\s+", "");
557             if (line.isEmpty()) {
558                 continue;
559             }
560             if (line.contains("<Description>") && line.contains(value)) {
561                 userId = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value));
562                 break;
563             }
564         }
565         return userId;
566     }
567
568     // get the Modified Name of the User on reading the Xml file
569     /**
570      * getModifiedBy.
571      *
572      * @param policyPath Path
573      * @return String
574      * @throws IOException IOException
575      */
576     public static String getModifiedBy(Path policyPath) throws IOException {
577         String modifiedBy = "";
578         String value = "@ModifiedBy:";
579         for (String line : Files.readAllLines(policyPath)) {
580             line = line.replaceAll("\\s+", "");
581             if (line.isEmpty()) {
582                 continue;
583             }
584             if (line.contains("<Description>") && line.contains(value)) {
585                 modifiedBy = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value));
586                 break;
587             }
588         }
589         return modifiedBy;
590     }
591
592     /**
593      * readPolicy - does the work to read in policy data from a file.
594      *
595      * @param is - The path to the policy file.
596      * @return - The policy data object. This *should* be either a PolicySet or a Policy.
597      */
598     public static Object readPolicy(InputStream is) {
599         try {
600             //
601             // Create a DOM parser
602             //
603             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
604             dbf.setNamespaceAware(true);
605             DocumentBuilder db = dbf.newDocumentBuilder();
606             //
607             // Parse the policy file
608             //
609             Document doc = db.parse(is);
610             Element element = doc.getDocumentElement();
611             //
612             // Is it a 3.0 policy?
613             //
614             if ("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17".equals(element.getNamespaceURI())) {
615                 //
616                 // A policyset or policy could be the root
617                 //
618                 if (element.getNodeName().endsWith("Policy")) {
619                     //
620                     // Now we can create the context for the policy set
621                     // and unmarshall the policy into a class.
622                     //
623                     JAXBContext context = JAXBContext.newInstance(PolicyType.class);
624                     Unmarshaller um = context.createUnmarshaller();
625                     JAXBElement<PolicyType> root = um.unmarshal(element, PolicyType.class);
626                     //
627                     // Here is our policy set class
628                     //
629                     return root.getValue();
630                 } else if (element.getNodeName().endsWith("PolicySet")) {
631                     //
632                     // Now we can create the context for the policy set
633                     // and unmarshall the policy into a class.
634                     //
635                     JAXBContext context = JAXBContext.newInstance(PolicySetType.class);
636                     Unmarshaller um = context.createUnmarshaller();
637                     JAXBElement<PolicySetType> root = um.unmarshal(element, PolicySetType.class);
638                     //
639                     // Here is our policy set class
640                     //
641                     return root.getValue();
642                 } else {
643                     if (logger.isDebugEnabled()) {
644                         logger.debug("Not supported yet: " + element.getNodeName());
645                     }
646                 }
647             } else {
648                 logger.warn("unsupported namespace: " + element.getNamespaceURI());
649             }
650         } catch (Exception e) {
651             PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPolicyScanner", "Exception in readPolicy");
652         }
653         return null;
654     }
655
656     /**
657      * getPolicyObject.
658      *
659      * @return the policyObject
660      */
661     public Object getPolicyObject() {
662         return policyObject;
663     }
664 }