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