Coverage Report - org.openpermis.policy.bean.basic.BasicPolicy
 
Classes in this File Line Coverage Branch Coverage Complexity
BasicPolicy
41%
97/236
27%
55/202
3.848
 
 1  
 /*
 2  
  * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport
 3  
  *                     (http://www.vbs.admin.ch)
 4  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 5  
  * All rights reserved.
 6  
  *
 7  
  * Licensed under the Open Permis License which accompanies this distribution,
 8  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 9  
  */
 10  
 package org.openpermis.policy.bean.basic;
 11  
 
 12  
 import static org.openpermis.policy.bean.basic.BasicUtilities.getIdentityDetails;
 13  
 import static org.openpermis.policy.bean.basic.BasicUtilities.getShortStringDetails;
 14  
 import static org.openpermis.policy.bean.basic.BasicUtilities.multiHashCode;
 15  
 
 16  
 import java.net.URI;
 17  
 import java.util.ArrayList;
 18  
 import java.util.HashMap;
 19  
 import java.util.HashSet;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 import java.util.Set;
 24  
 
 25  
 import org.joda.time.DateTimeZone;
 26  
 
 27  
 import org.openpermis.Subject;
 28  
 import org.openpermis.policy.AccessDecision;
 29  
 import org.openpermis.policy.AuthorizedRoles;
 30  
 import org.openpermis.policy.PartProblemReporter;
 31  
 import org.openpermis.policy.Role;
 32  
 import org.openpermis.policy.TimeStamp;
 33  
 import org.openpermis.policy.PartProblemReporter.ProblemMessage;
 34  
 import org.openpermis.policy.bean.ActionBean;
 35  
 import org.openpermis.policy.bean.DomainBean;
 36  
 import org.openpermis.policy.bean.ObligationBean;
 37  
 import org.openpermis.policy.bean.PartBean;
 38  
 import org.openpermis.policy.bean.PolicyBean;
 39  
 import org.openpermis.policy.bean.RoleAssignmentRuleBean;
 40  
 import org.openpermis.policy.bean.RoleAssignmentRuleBeanCollection;
 41  
 import org.openpermis.policy.bean.RoleHierarchyBean;
 42  
 import org.openpermis.policy.bean.RoleHierarchyBeanCollection;
 43  
 import org.openpermis.policy.bean.SerialNumber;
 44  
 import org.openpermis.policy.bean.TargetAccessRuleBean;
 45  
 import org.openpermis.policy.bean.TargetAccessRuleBeanCollection;
 46  
 import org.openpermis.policy.bean.TargetBean;
 47  
 
 48  
 /**
 49  
  * Basic implementation of a policy.
 50  
  * @since 0.1.0
 51  
  */
 52  1
 public class BasicPolicy
 53  
         extends BasicPartBean
 54  
         implements PolicyBean
 55  
 {
 56  
 
 57  
         //---- Static
 58  
 
 59  
         /**
 60  
          * @since 0.1.0
 61  
          */
 62  
         private static final long serialVersionUID = -8888013228359169599L;
 63  
 
 64  
         //---- State
 65  
 
 66  
         /**
 67  
          * @since 0.1.0
 68  
          */
 69  
         private DateTimeZone dateTimeZone;
 70  
 
 71  
         /**
 72  
          * @since 0.1.0
 73  
          */
 74  
         private RoleAssignmentRuleBeanCollection roleAssignmentRules;
 75  
 
 76  
         /**
 77  
          * @since 0.1.0
 78  
          */
 79  
         private TargetAccessRuleBeanCollection targetAccessRules;
 80  
 
 81  
         /**
 82  
          * @since 0.1.0
 83  
          */
 84  
         private RoleHierarchyBeanCollection roleHierarchies;
 85  
 
 86  
         //---- Constructors
 87  
 
 88  
         /**
 89  
          * Creates a policy with the specified rules.
 90  
          * @since 0.1.0
 91  
          */
 92  
         protected BasicPolicy (SerialNumber serialNumber) {
 93  264
                 super(PolicyBean.class, serialNumber);
 94  264
                 this.roleAssignmentRules = new BasicRoleAssignmentRuleCollection(serialNumber.next());
 95  264
                 this.targetAccessRules = new BasicTargetAccessRuleCollection(serialNumber.next());
 96  264
                 this.roleHierarchies = new BasicRoleHierarchyCollection(serialNumber.next());
 97  264
         }
 98  
 
 99  
         //---- Methods
 100  
 
 101  
         /**
 102  
          * Check if there is at least one role assignment rule and all is correct.
 103  
          * of the role hierarchy is consistent.
 104  
          * @param reporter the reporter to use.
 105  
          * @return {@code true} if the role assignment rules are valid.
 106  
          * @since 0.1.0
 107  
          */
 108  
         private boolean areRoleAssignmentRulesValid (PartProblemReporter reporter) {
 109  
                 boolean valid;
 110  
 
 111  
                 // init
 112  3
                 valid = true;
 113  
                 
 114  
                 // check for role-assignment-rules
 115  3
                 if (!isChildCollectionValid(
 116  
                         reporter, getRoleAssignmentRules(), true, true, false, true, false)
 117  
                 ) {
 118  1
                         valid = false;
 119  1
                         reportProblem(reporter, ProblemMessage.invalidRoleAssignmentRules);
 120  
                 }
 121  
 
 122  
                 // check topology: references roles vs role-hierarchies
 123  3
                 if (getRoleAssignmentRules() != null) {
 124  3
                         for (RoleAssignmentRuleBean rule : getRoleAssignmentRules()) {
 125  2
                                 if (rule != null && rule.getRoles() != null) {
 126  2
                                         for (Role role : rule.getRoles()) {
 127  2
                                                 if (role != null) {
 128  2
                                                         if (!getRoleHierarchies().toList().contains(role.getRoleHierarchy())) {
 129  2
                                                                 valid = false;
 130  2
                                                                 reportProblem(reporter, ProblemMessage.illegalRoleTree);
 131  
                                                         }
 132  
                                                 }
 133  
                                         }
 134  
                                 }
 135  
                         }
 136  
                 }
 137  
 
 138  
                 // return
 139  3
                 return valid;
 140  
         }
 141  
 
 142  
         /**
 143  
          * Check if there is at least one target access rule and that the containment hierarchy
 144  
          * of the role hierarchy is consistent.
 145  
          * @param reporter the reporter to use.
 146  
          * @return {@code true} if the target access rules are valid.
 147  
          * @since 0.1.0
 148  
          */
 149  
         private boolean areTargetAccessRulesValid (PartProblemReporter reporter) {
 150  
                 boolean valid;
 151  
 
 152  
                 // init
 153  3
                 valid = true;
 154  
 
 155  
                 // check for target-access-rules
 156  3
                 if (!isChildCollectionValid(
 157  
                         reporter, getTargetAccessRules(), true, true, false, true, false)) {
 158  2
                         valid = false;
 159  2
                         reportProblem(reporter, ProblemMessage.invalidTargetAccessRules);
 160  
                 }
 161  
 
 162  
                 // check topology: references roles vs. role-hierarchies
 163  3
                 if (getTargetAccessRules() != null) {
 164  3
                         for (TargetAccessRuleBean rule : getTargetAccessRules()) {
 165  2
                                 if (rule != null && rule.getRoles() != null) {
 166  2
                                         for (Role role : rule.getRoles()) {
 167  1
                                                 if (role != null) {
 168  1
                                                         if (!getRoleHierarchies().toList().contains(role.getRoleHierarchy())) {
 169  1
                                                                 valid = false;
 170  1
                                                                 reportProblem(reporter, ProblemMessage.illegalRoleTree);
 171  
                                                         }
 172  
                                                 }
 173  
                                         }
 174  
                                 }
 175  
                         }
 176  
                 }
 177  
 
 178  
                 // return
 179  3
                 return valid;
 180  
         }
 181  
 
 182  
         /**
 183  
          * Check if there is at least one role-hierarchy,
 184  
          * check if their name are unique,
 185  
          * @param reporter the reporter to use.
 186  
          * @return {@code true} if the role hierarchies are valid.
 187  
          * @since 0.1.0
 188  
          */
 189  
         private boolean areRoleHierarchiesValid (PartProblemReporter reporter) {
 190  
                 boolean valid;
 191  
 
 192  
                 // init
 193  3
                 valid = true;
 194  
 
 195  
                 // check for role-hierarchies
 196  3
                 if (!isChildCollectionValid(
 197  
                         reporter, this.getRoleHierarchies(), true, true, false, false, true)) {
 198  3
                         valid = false;
 199  3
                         reportProblem(reporter, ProblemMessage.invalidRoleHierarchies);
 200  
                 }
 201  
 
 202  
                 // return
 203  3
                 return valid;
 204  
         }
 205  
 
 206  
         private <M extends PartBean> void addPartToMap (
 207  
                 Map<SerialNumber, PartBean> map,
 208  
                 Class<M> type,
 209  
                 PartBean part)
 210  
         {
 211  0
                 if (part != null && type.isAssignableFrom(part.getClass())) {
 212  0
                         map.put(part.getSerialNumber(), part);
 213  
                 }
 214  0
         }
 215  
 
 216  
         /**
 217  
          * Returns all parts of given type, unique by serial number.
 218  
          * @since 0.1.0
 219  
          */
 220  
         private <M extends PartBean> Map<SerialNumber, PartBean> getPartsMap (Class<M> type) {
 221  
 
 222  
                 // init
 223  0
                 Map<SerialNumber, PartBean> map = new HashMap<SerialNumber, PartBean>();
 224  
 
 225  
                 // get policy
 226  0
                 PolicyBean policy = this;
 227  
 
 228  
                 // add PolicyBean
 229  0
                 addPartToMap(map, type, policy);
 230  
 
 231  
                 // loop over RoleHierarchyBean's
 232  0
                 for (final RoleHierarchyBean rolehierarchy : policy.getRoleHierarchies()) {
 233  
 
 234  
                         // add RoleHierarchyBean
 235  0
                         addPartToMap(map, type, rolehierarchy);
 236  
                 }
 237  
                 
 238  0
                 for (final RoleAssignmentRuleBean rule : policy.getRoleAssignmentRules()) {
 239  0
                         addPartToMap(map, type, rule);
 240  0
                         addPartToMap(map, type, rule.getSubjectDomain());
 241  0
                         addPartToMap(map, type, rule.getAuthority());
 242  
                 }
 243  
 
 244  
                 // loop over TargetAccessRuleBean's
 245  0
                 for (final TargetAccessRuleBean rule : policy.getTargetAccessRules()) {
 246  
 
 247  
                         // add TargetAccessRuleBean
 248  0
                         addPartToMap(map, type, rule);
 249  
 
 250  0
                         for (final ObligationBean obligation : rule.getObligations()) {
 251  0
                                 if (obligation != null) {
 252  0
                                         addPartToMap(map, type, obligation);
 253  
                                 }
 254  
                         }
 255  
 
 256  
                         // loop over TargetBean's
 257  0
                         for (final TargetBean target : rule.getTargets()) {
 258  0
                                 if (target != null) {
 259  
                                         // add TargetBean
 260  0
                                         addPartToMap(map, type, target);
 261  
 
 262  
                                         // add resource domain
 263  0
                                         addPartToMap(map, type, target.getResourceDomain());
 264  
 
 265  
                                         // loop over actions
 266  0
                                         for (final ActionBean action : target.getActions()) {
 267  
                                                 // add Action
 268  0
                                                 addPartToMap(map, type, action);
 269  
                                         }
 270  
                                 }
 271  
                         }
 272  
                 }
 273  
 
 274  
                 // return
 275  0
                 return map;
 276  
         }
 277  
 
 278  
         //---- Policy
 279  
 
 280  
         /**
 281  
          * @since 0.1.0
 282  
          */
 283  
         public AccessDecision getAccessDecision (
 284  
                 Subject subject,
 285  
                 URI resourceUri,
 286  
                 String actionName,
 287  
                 List<?> arguments,
 288  
                 TimeStamp timeStamp
 289  
         ) {
 290  15
                 if (subject == null ||
 291  
                         actionName == null ||
 292  
                         resourceUri == null ||
 293  
                         arguments == null ||
 294  
                         timeStamp == null
 295  
                 ) {
 296  0
                         throw new IllegalArgumentException(
 297  
                                 "Subject, actionName, resourceUri, arguments, or time is null."
 298  
                         );
 299  
                 }
 300  
                 // TODO Any Split this function in several small protected methods.
 301  
                 // Find all authorized role sets.
 302  15
                 final List<AuthorizedRoles> permittedRoleSets =
 303  
                         getTargetAccessRules().findAuthorizedRoleSets(
 304  
                                 resourceUri, actionName, arguments, timeStamp
 305  
                         );
 306  
 
 307  
                 // Fail: access not possible.
 308  15
                 if (permittedRoleSets.isEmpty()) {
 309  2
                         return new AccessDecision(false);
 310  
                 }
 311  
 
 312  
                 // Get all considered roles that may be hold by the subject.
 313  13
                 final Set<Role> consideredRoles = new HashSet<Role>();
 314  13
                 for (AuthorizedRoles authorizedRoleSet : permittedRoleSets) {
 315  13
                         consideredRoles.addAll(authorizedRoleSet.getRoles());
 316  
                 }
 317  
 
 318  
                 // Expand the set of explicitly considered roles with their implicitly considered super
 319  
                 // roles.
 320  13
                 final Set<Role> extendedConsideredRoles = new HashSet<Role>();
 321  13
                 for (Role role : consideredRoles) {
 322  18
                         extendedConsideredRoles.addAll(role.getSuperRoles());
 323  
                 }
 324  
 
 325  13
                 final Set<Role> assignedRoleRefs =
 326  
                         subject.getAssignedRoles(timeStamp, extendedConsideredRoles);
 327  
                 
 328  
                 // Fail: subject doesn't hold any role.
 329  13
                 if (assignedRoleRefs.isEmpty()) {
 330  2
                         return new AccessDecision(false);
 331  
                 }
 332  
 
 333  11
                 final Set<Role> verifiedRoles =
 334  
                         getRoleAssignmentRules().verifyRoleAssignments(
 335  
                                 subject, assignedRoleRefs, timeStamp
 336  
                         );
 337  
 
 338  
                 // Fail: subject doesn't hold any valid role.
 339  11
                 if (verifiedRoles.isEmpty()) {
 340  0
                         return new AccessDecision(false);
 341  
                 }
 342  
 
 343  
                 // Expand the set of explicitly verified roles with the implicitly inherited sub-roles.
 344  11
                 final Set<Role> extendedVerifiedRoles = new HashSet<Role>();
 345  11
                 for (Role role : verifiedRoles) {
 346  12
                         extendedVerifiedRoles.addAll(role.getSubRoles());
 347  
                 }
 348  
                 
 349  
                 // Find a role set of a target access rule in which all roles are verified.
 350  11
                 boolean isPositiveAccessDecision = false;
 351  11
                 final List<Set<String>> obligationSets = new ArrayList<Set<String>>();
 352  
                 
 353  11
                 for (AuthorizedRoles authorizedRoles : permittedRoleSets) {
 354  11
                         if (extendedVerifiedRoles.containsAll(authorizedRoles.getRoles())) {
 355  
                                 // Access Granted.
 356  8
                                 isPositiveAccessDecision = true;
 357  8
                                 obligationSets.add(authorizedRoles.getObligations());
 358  
                         }
 359  
                 }
 360  
                 
 361  11
                 if (isPositiveAccessDecision) {
 362  8
                         return new AccessDecision(true, obligationSets);
 363  
                 }
 364  3
                 return new AccessDecision(false);
 365  
                 
 366  
         }
 367  
 
 368  
         //---- PolicyBean
 369  
 
 370  
         /**
 371  
          * @since 0.1.0
 372  
          */
 373  
         public DateTimeZone getDateTimeZone () {
 374  13
                 return this.dateTimeZone;
 375  
         }
 376  
 
 377  
         /**
 378  
          * @since 0.1.0
 379  
          */
 380  
         public void setDateTimeZone (DateTimeZone dateTimeZone) {
 381  235
                 this.dateTimeZone = dateTimeZone;
 382  235
         }
 383  
 
 384  
         /**
 385  
          * @since 0.3.0
 386  
          */
 387  
         public RoleAssignmentRuleBeanCollection getRoleAssignmentRules () {
 388  541
                 return this.roleAssignmentRules;
 389  
         }
 390  
 
 391  
         /**
 392  
          * @since 0.3.0
 393  
          */
 394  
         public void setRoleAssignmentRules (RoleAssignmentRuleBeanCollection roleAssignmentRules) {
 395  238
                 final RoleAssignmentRuleBeanCollection oldRoleAssignmentRules = getRoleAssignmentRules();
 396  238
                 if (roleAssignmentRules == null) {
 397  0
                         this.roleAssignmentRules =
 398  
                                 new BasicRoleAssignmentRuleCollection(getSerialNumber().next());
 399  
                 } else {
 400  238
                         this.roleAssignmentRules = roleAssignmentRules;
 401  
                 }
 402  238
                 firePropertyChange("roleAssignmentRules", oldRoleAssignmentRules, getRoleAssignmentRules());
 403  238
         }
 404  
 
 405  
         /**
 406  
          * @since 0.3.0
 407  
          */
 408  
         public TargetAccessRuleBeanCollection getTargetAccessRules () {
 409  543
                 return this.targetAccessRules;
 410  
         }
 411  
 
 412  
         /**
 413  
          * @since 0.3.0
 414  
          */
 415  
         public void setTargetAccessRules (TargetAccessRuleBeanCollection targetAccessRules) {
 416  238
                 final TargetAccessRuleBeanCollection oldTargetAccessRules = getTargetAccessRules();
 417  238
                 if (targetAccessRules == null) {
 418  0
                         this.targetAccessRules = new BasicTargetAccessRuleCollection(getSerialNumber().next());
 419  
                 } else {
 420  238
                         this.targetAccessRules = targetAccessRules;
 421  
                 }
 422  238
                 firePropertyChange("targetAccessRules", oldTargetAccessRules, getTargetAccessRules());
 423  238
         }
 424  
 
 425  
         /**
 426  
          * @since 0.3.0
 427  
          */
 428  
         public RoleHierarchyBeanCollection getRoleHierarchies () {
 429  523
                 return this.roleHierarchies;
 430  
         }
 431  
 
 432  
         /**
 433  
          * @since 0.3.0
 434  
          */
 435  
         public void setRoleHierarchies (RoleHierarchyBeanCollection roleHierarchies) {
 436  237
                 final RoleHierarchyBeanCollection oldRoleHierarchies = getRoleHierarchies();
 437  237
                 if (roleHierarchies == null) {
 438  0
                         this.roleHierarchies = new BasicRoleHierarchyCollection(getSerialNumber().next());
 439  
                 } else {
 440  237
                         this.roleHierarchies = roleHierarchies;
 441  
                 }
 442  237
                 firePropertyChange("roleHierarchies", oldRoleHierarchies, getRoleHierarchies());
 443  237
         }
 444  
 
 445  
         /**
 446  
          * Returns all parts of given type, unique by serial number.
 447  
          * @since 0.1.0
 448  
          */
 449  
         @SuppressWarnings("unchecked")
 450  
         public <M extends PartBean> List<M> getPartsList (Class<M> type) {
 451  0
                 Map<SerialNumber, PartBean> map = getPartsMap(type);
 452  0
                 List<M> list = new ArrayList<M>();
 453  0
                 Iterator<Map.Entry<SerialNumber, PartBean>> it = map.entrySet().iterator();
 454  0
                 while (it.hasNext()) {
 455  0
                         Map.Entry<SerialNumber, PartBean> pairs = it.next();
 456  0
                         PartBean part = pairs.getValue();
 457  0
                         list.add((M) part);
 458  0
                 }
 459  0
                 return list;
 460  
         }
 461  
 
 462  
         /**
 463  
          * Returns all rolerefs.
 464  
          * @since 0.3.0
 465  
          */
 466  
         public List<Role> getRoleRefList () {
 467  
 
 468  
                 // get policy
 469  0
                 PolicyBean policy = this;
 470  
 
 471  
                 // loop over RoleHierarchyBean's
 472  0
                 List<Role> list = new ArrayList<Role>();
 473  0
                 for (final RoleHierarchyBean rolehierarchy : policy.getRoleHierarchies()) {
 474  0
                         for (String role : rolehierarchy.getRoles()) {
 475  0
                                 list.add(Role.create(rolehierarchy, role));
 476  
                         }
 477  
                 }
 478  
 
 479  
                 // return
 480  0
                 return list;
 481  
         }
 482  
 
 483  
         /**
 484  
          * Returns the PartBean's containing the given part.
 485  
          * @return list of found parts in the policy
 486  
          * @since 0.1.0
 487  
          */
 488  
         public List<TargetAccessRuleBean> getParentTargetAccessRules (TargetBean searchPart) {
 489  0
                 List<TargetAccessRuleBean> list = new ArrayList<TargetAccessRuleBean>();
 490  0
                 for (final TargetAccessRuleBean currRule : getTargetAccessRules()) {
 491  0
                         for (final TargetBean currTarget : currRule.getTargets()) {
 492  0
                                 if (searchPart.equalSerialNumber(currTarget)) {
 493  0
                                         list.add(currRule);
 494  0
                                         break;
 495  
                                 }
 496  
                         }
 497  
                 }
 498  0
                 assert
 499  
                         BasicUtilities.findDuplicateSerialNumberInList(list) ==
 500  
                         BasicUtilities.NOT_FOUND;
 501  0
                 return list;
 502  
         }
 503  
 
 504  
         /**
 505  
          * Returns the PartBean's containing the given part.
 506  
          * @return list of found parts in the policy
 507  
          * @since 0.3.0
 508  
          */
 509  
         public List<TargetAccessRuleBean> getParentTargetAccessRules (ObligationBean searchPart) {
 510  0
                 List<TargetAccessRuleBean> list = new ArrayList<TargetAccessRuleBean>();
 511  0
                 for (final TargetAccessRuleBean currRule : getTargetAccessRules()) {
 512  0
                         for (final ObligationBean currObligation : currRule.getObligations()) {
 513  0
                                 if (searchPart.equalSerialNumber(currObligation)) {
 514  0
                                         list.add(currRule);
 515  0
                                         break;
 516  
                                 }
 517  
                         }
 518  
                 }
 519  0
                 assert
 520  
                         BasicUtilities.findDuplicateSerialNumberInList(list) ==
 521  
                         BasicUtilities.NOT_FOUND;
 522  0
                 return list;
 523  
         }
 524  
 
 525  
         /**
 526  
          * Returns the PartBean's containing the given part.
 527  
          * @return list of found parts in the policy
 528  
          * @since 0.1.0
 529  
          */
 530  
         public List<TargetAccessRuleBean> getParentTargetAccessRules (Role searchRule) {
 531  0
                 List<TargetAccessRuleBean> list = new ArrayList<TargetAccessRuleBean>();
 532  0
                 for (final TargetAccessRuleBean currRule : getTargetAccessRules()) {
 533  0
                         for (final Role currRole : currRule.getRoles()) {
 534  0
                                 if (searchRule.equals(currRole)) {
 535  0
                                         list.add(currRule);
 536  0
                                         break;
 537  
                                 }
 538  
                         }
 539  
                 }
 540  0
                 assert
 541  
                         BasicUtilities.findDuplicateSerialNumberInList(list) ==
 542  
                                 BasicUtilities.NOT_FOUND;
 543  0
                 return list;
 544  
         }
 545  
 
 546  
         /**
 547  
          * Returns the PartBean's containing the given part.
 548  
          * @return list of found parts in the policy
 549  
          * @since 0.3.0
 550  
          */
 551  
         public List<RoleHierarchyBean> getParentRoleHierarchies (Role role) {
 552  0
                 List<RoleHierarchyBean> list = new ArrayList<RoleHierarchyBean>();
 553  0
                 for (final RoleHierarchyBean currHierarchy : getRoleHierarchies()) {
 554  0
                         for (final String currRole : currHierarchy.getRoles()) {
 555  0
                                 if (role.getName().equals(currRole)) {
 556  0
                                         list.add(currHierarchy);
 557  0
                                         break;
 558  
                                 }
 559  
                         }
 560  
                 }
 561  0
                 assert
 562  
                         BasicUtilities.findDuplicateSerialNumberInList(list) ==
 563  
                                 BasicUtilities.NOT_FOUND;
 564  0
                 return list;
 565  
         }
 566  
 
 567  
         /**
 568  
          * Returns the PartBean's containing the given part.
 569  
          * @return list of found parts in the policy
 570  
          * @since 0.1.0
 571  
          */
 572  
         public List<TargetBean> getParentTargets (ActionBean searchPart) {
 573  0
                 List<TargetBean> parentsPossible = getPartsList(TargetBean.class);
 574  0
                 List<TargetBean> parentsFound = new ArrayList<TargetBean>();
 575  0
                 for (final TargetBean currTarget : parentsPossible) {
 576  0
                         for (final ActionBean currAction : currTarget.getActions()) {
 577  0
                                 if (searchPart.equalSerialNumber(currAction)) {
 578  0
                                         parentsFound.add(currTarget);
 579  0
                                         break;
 580  
                                 }
 581  
                         }
 582  
                 }
 583  0
                 assert
 584  
                         BasicUtilities.findDuplicateSerialNumberInList(parentsFound) ==
 585  
                         BasicUtilities.NOT_FOUND;
 586  0
                 return parentsFound;
 587  
         }        
 588  
 
 589  
         /**
 590  
          * Returns the PartBean's containing the given part.
 591  
          * @return list of found parts in the policy
 592  
          * @since 0.1.0
 593  
          */
 594  
         public List<TargetBean> getParentTargets (DomainBean searchPart) {
 595  0
                 List<TargetBean> parentsPossible = getPartsList(TargetBean.class);
 596  0
                 List<TargetBean> parentsFound = new ArrayList<TargetBean>();
 597  0
                 for (final TargetBean currTarget : parentsPossible) {
 598  0
                         if (
 599  
                                 currTarget.getResourceDomain() != null &&
 600  
                                 searchPart.equalSerialNumber(currTarget.getResourceDomain())
 601  
                         ) {
 602  0
                                 parentsFound.add(currTarget);
 603  
                         }
 604  
                 }
 605  0
                 assert
 606  
                         BasicUtilities.findDuplicateSerialNumberInList(parentsFound) ==
 607  
                         BasicUtilities.NOT_FOUND;
 608  0
                 return parentsFound;
 609  
         }
 610  
 
 611  
         /**
 612  
          * Returns all resource domains.
 613  
          * @return all resource domains.
 614  
          * @since 0.3.0
 615  
          */
 616  
         public List<DomainBean> getResourceDomains () {
 617  0
                 final Set<SerialNumber> serials = new HashSet<SerialNumber>();
 618  0
                 final List<DomainBean> result = new ArrayList<DomainBean>();
 619  0
                 for (TargetAccessRuleBean rule : getTargetAccessRules()) {
 620  0
                         for (TargetBean target : rule.getTargets()) {
 621  0
                                 final DomainBean domain = target.getResourceDomain();
 622  0
                                 if (domain != null && 
 623  
                                         !serials.contains(domain.getSerialNumber())
 624  
                                 ) {
 625  0
                                         serials.add(domain.getSerialNumber());
 626  0
                                         result.add(domain);
 627  
                                 }
 628  0
                         }
 629  
                 }
 630  0
                 return result;
 631  
         }
 632  
 
 633  
         /**
 634  
          * Returns all subject domains.
 635  
          * @return all subject domains.
 636  
          * @since 0.3.0
 637  
          */
 638  
         public List<DomainBean> getSubjectDomains () {
 639  0
                 final Set<SerialNumber> serials = new HashSet<SerialNumber>();
 640  0
                 final List<DomainBean> result = new ArrayList<DomainBean>();
 641  0
                 for (RoleAssignmentRuleBean rule : getRoleAssignmentRules()) {
 642  0
                         final DomainBean domain = rule.getSubjectDomain();
 643  0
                         if (domain != null && 
 644  
                                 !serials.contains(domain.getSerialNumber())
 645  
                         ) {
 646  0
                                 serials.add(domain.getSerialNumber());
 647  0
                                 result.add(domain);
 648  
                         }        
 649  0
                 }
 650  0
                 return result;
 651  
         }
 652  
 
 653  
         /**
 654  
          * Returns the PartBean's containing the given part.
 655  
          * @return list of found parts in the policy
 656  
          * @since 0.3.0
 657  
          */
 658  
         public List<RoleAssignmentRuleBean> getParentRoleAssignmentRules (DomainBean searchPart) {
 659  0
                 List<RoleAssignmentRuleBean> parentsPossible = getPartsList(RoleAssignmentRuleBean.class);
 660  0
                 List<RoleAssignmentRuleBean> parentsFound = new ArrayList<RoleAssignmentRuleBean>();
 661  0
                 for (final RoleAssignmentRuleBean currRule : parentsPossible) {
 662  0
                         if ((currRule.getSubjectDomain() != null) &&
 663  
                                 searchPart.equalSerialNumber(currRule.getSubjectDomain())) {
 664  0
                                 parentsFound.add(currRule);
 665  
                         }
 666  
                 }
 667  0
                 assert
 668  
                         BasicUtilities.findDuplicateSerialNumberInList(parentsFound) ==
 669  
                         BasicUtilities.NOT_FOUND;
 670  0
                 return parentsFound;
 671  
         }
 672  
 
 673  
         //---- BasicPart
 674  
 
 675  
         /**
 676  
          * @since 0.1.0
 677  
          */
 678  
         @Override
 679  
         public boolean isPartValid (PartProblemReporter reporter) {
 680  
                 boolean valid;
 681  
 
 682  
                 // init
 683  3
                 valid = true;
 684  
 
 685  
                 // check role-assignment-rules
 686  3
                 if (!areRoleAssignmentRulesValid(reporter)) {
 687  3
                         valid = false;
 688  
                 }
 689  
 
 690  
                 // check target-access-rules
 691  3
                 if (!areTargetAccessRulesValid(reporter)) {
 692  3
                         valid = false;
 693  
                 }
 694  
 
 695  
                 // check role-hierarchies
 696  3
                 if (!areRoleHierarchiesValid(reporter)) {
 697  3
                         valid = false;
 698  
                 }
 699  
 
 700  
                 // return
 701  3
                 return valid;
 702  
         }
 703  
 
 704  
         /**
 705  
          * @since 0.1.0
 706  
          */
 707  
         @Override
 708  
         protected boolean comparablePart (BasicPart part) {
 709  28
                 return part instanceof PolicyBean;
 710  
         }
 711  
 
 712  
         /**
 713  
          * @since 0.1.0
 714  
          */
 715  
         @Override
 716  
         protected boolean equalPart (BasicPart part) {
 717  14
                 final PolicyBean policy = (PolicyBean) part;
 718  14
                 return
 719  
                         getRoleAssignmentRules().equals(policy.getRoleAssignmentRules()) &&
 720  
                         getTargetAccessRules().equals(policy.getTargetAccessRules()) &&
 721  
                         getRoleHierarchies().equals(policy.getRoleHierarchies());
 722  
         }
 723  
 
 724  
         /**
 725  
          * @since 0.1.0
 726  
          */
 727  
         @Override
 728  
         protected int partHashCode () {
 729  4
                 return multiHashCode(
 730  
                         getRoleAssignmentRules().hashCode(),
 731  
                         getTargetAccessRules().hashCode(),
 732  
                         getRoleHierarchies().hashCode()
 733  
                 );
 734  
         }
 735  
 
 736  
         /**
 737  
          * @since 0.1.0
 738  
          */
 739  
         @Override
 740  
         protected String getSimpleClassName () {
 741  0
                 return PolicyBean.class.getSimpleName();
 742  
         }
 743  
 
 744  
         /**
 745  
          * @since 0.1.0
 746  
          */
 747  
         @Override
 748  
         protected void appendPartDetails (StringBuilder sb) {
 749  0
                 appendDetails(sb, "roleAssignmentRules", getShortStringDetails(getRoleAssignmentRules()));
 750  0
                 appendDetails(sb, "targetAccessRules", getShortStringDetails(getTargetAccessRules()));
 751  0
                 appendDetails(sb, "roleHierarchies", getIdentityDetails(getRoleHierarchies()));
 752  0
         }
 753  
 
 754  
         //---- BasicPartBean
 755  
 
 756  
         /**
 757  
          * @since 0.1.0
 758  
          */
 759  
         @Override
 760  
         public PartBean findBySerialNumber (SerialNumber partSerialNumber) {
 761  0
                 for (final RoleAssignmentRuleBean rule : getRoleAssignmentRules()) {
 762  0
                         final PartBean bean = rule.findBySerialNumber(partSerialNumber);
 763  0
                         if (bean != null) {
 764  0
                                 return bean;
 765  
                         }
 766  0
                 }
 767  
 
 768  0
                 for (final TargetAccessRuleBean rule : getTargetAccessRules()) {
 769  0
                         final PartBean bean = rule.findBySerialNumber(partSerialNumber);
 770  0
                         if (bean != null) {
 771  0
                                 return bean;
 772  
                         }
 773  0
                 }
 774  
 
 775  0
                 for (final RoleHierarchyBean hierarchy : getRoleHierarchies()) {
 776  0
                         final PartBean bean = hierarchy.findBySerialNumber(partSerialNumber);
 777  0
                         if (bean != null) {
 778  0
                                 return bean;
 779  
                         }
 780  0
                 }
 781  
 
 782  0
                 return super.findBySerialNumber(partSerialNumber);
 783  
         }
 784  
 
 785  
 }