001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: ResourceResult.java,v 1.5 2009/10/12 17:53:05 dillidorai Exp $ 026 * 027 * Portions Copyrighted 2011-2014 ForgeRock AS. 028 */ 029package com.sun.identity.policy; 030 031import java.util.*; 032 033import org.w3c.dom.*; 034import com.sun.identity.shared.debug.Debug; 035import com.sun.identity.shared.xml.XMLUtils; 036import com.sun.identity.policy.interfaces.ResourceName; 037 038 039/** 040 * Class that encapsulates a tree of resource names, with each node 041 * having an associated policy decision. 042 * @supported.api 043 * @deprecated since 12.0.0 044 */ 045@Deprecated 046public class ResourceResult { 047 048 /** 049 * Constant to indicate subtree level scope for ResourceResult evaluation 050 * 051 * @supported.api 052 */ 053 public static final String SUBTREE_SCOPE = "subtree"; 054 055 /** 056 * Constant to indicate strict subtree level scope for 057 * <code>ResourceResult</code> evaluation 058 * 059 * @supported.api 060 */ 061 public static final String STRICT_SUBTREE_SCOPE = "strict-subtree"; 062 063 /** 064 * Constant to indicate base (self) level scope for 065 * <code>ResourceResult</code> evaluation 066 * 067 * @supported.api 068 */ 069 public static final String SELF_SCOPE = "self"; 070 071 /** 072 * Constant used internally as a place holder for all encompassing root 073 * resoure name. Any resource name is considered to be sub resource of 074 * this resource name. 075 */ 076 static final public String VIRTUAL_ROOT = "-__viRTuAl-rOot--_"; 077 078 static final String RESOURCE_RESULT = "ResourceResult"; 079 static final String RESOURCE_NAME = "name"; 080 static final String POLICY_DEBUG_NAME = "amPolicy"; 081 static final Debug DEBUG = Debug.getInstance(POLICY_DEBUG_NAME); 082 083 private String resourceName = null; 084 private PolicyDecision policyDecision = null; 085 private Set resourceResults = new HashSet(); 086 private long timeToLive = Long.MAX_VALUE; 087 private boolean advicesAreSet = false; 088 private String stringForm = null; 089 private String xmlForm = null; 090 091 //tracks the envMap used to compute ResourceResult 092 private Map envMap = null; 093 094 /** 095 * Used in remote api for result caching 096 */ 097 private boolean stale = false; 098 099 /** 100 * 101 * No argument constructor 102 */ 103 ResourceResult() { 104 } 105 106 /** 107 * Constructs a resource result given the resource name and policy decison 108 * @param resourceName resource name for this resource result 109 * @param policyDecision policy decision associated with the resource name 110 */ 111 public ResourceResult(String resourceName, PolicyDecision 112 policyDecision ) { 113 this.resourceName = resourceName; 114 setPolicyDecision(policyDecision); 115 } 116 117 /** 118 * Returns the resource name of this resource result 119 * @return resource name of this resource result 120 * @supported.api 121 */ 122 public String getResourceName() { 123 return resourceName; 124 } 125 126 127 /** 128 * Sets the resource name of this resource result 129 * @param resourceName resource name for this resource result 130 */ 131 void setResourceName(String resourceName) { 132 this.resourceName = resourceName; 133 this.stringForm = null; 134 this.xmlForm= null; 135 } 136 137 138 /** 139 * Returns the policy decision associated with this resource result 140 * @return policy decision associated with this resource result 141 * @supported.api 142 */ 143 public PolicyDecision getPolicyDecision() { 144 return policyDecision; 145 } 146 147 148 /** 149 * Sets the policy decision for this resource result 150 * @param policyDecision policy decision for this resource result 151 */ 152 public void setPolicyDecision(PolicyDecision policyDecision) { 153 this.policyDecision = policyDecision; 154 long pdTtl = policyDecision.getTimeToLive(); 155 if ( pdTtl < timeToLive ) { 156 timeToLive = pdTtl; 157 } 158 advicesAreSet = advicesAreSet || policyDecision.hasAdvices(); 159 this.stringForm = null; 160 this.xmlForm= null; 161 } 162 163 164 /** 165 * Returns the child resource results of this resource result 166 * @return child resource results of this resource result 167 * @supported.api 168 */ 169 public Set getResourceResults() { 170 return resourceResults; 171 } 172 173 174 /** 175 * Sets the child resource results of this resource result 176 * @param resourceResults child resource results of this resource result 177 */ 178 void setResourceResults(Set resourceResults) { 179 if (resourceResults == null) { 180 this.resourceResults.clear(); 181 } else { 182 this.resourceResults = resourceResults; 183 if (policyDecision != null) { 184 timeToLive = policyDecision.getTimeToLive(); 185 } 186 Iterator iter = resourceResults.iterator(); 187 while (iter.hasNext()) { 188 ResourceResult rr = (ResourceResult)iter.next(); 189 long ttl = rr.getTimeToLive(); 190 if ( ttl < timeToLive) { 191 timeToLive = ttl; 192 } 193 advicesAreSet = advicesAreSet || rr.hasAdvices(); 194 } 195 } 196 197 this.stringForm = null; 198 this.xmlForm= null; 199 } 200 201 /** 202 * Converts an XML representation of resource result to ResourceResult 203 * @param resourceResultNode XML DOM node representing resource result 204 * @return <code>ResourceResult</code> object representation of resource 205 * result 206 * @throws PolicyException if the conversion fails 207 */ 208 public static ResourceResult parseResourceResult(Node resourceResultNode) 209 throws PolicyException { 210 ResourceResult resourceResult = new ResourceResult(); 211 String resourceName = XMLUtils.getNodeAttributeValue(resourceResultNode, 212 RESOURCE_NAME); 213 if (resourceName == null) { 214 DEBUG.error("ResourceResult: missing attribute " + RESOURCE_NAME); 215 Object[] objs = {RESOURCE_NAME}; 216 throw new PolicyException(ResBundleUtils.rbName, 217 "missing_attribute_in_resourceresult", objs, null); 218 } 219 resourceResult.setResourceName(resourceName); 220 221 Node node = XMLUtils.getChildNode(resourceResultNode, 222 PolicyDecision.POLICY_DECISION); 223 if (node == null) { 224 DEBUG.error("ResourceResult: missing element " + 225 PolicyDecision.POLICY_DECISION); 226 Object[] objs = {PolicyDecision.POLICY_DECISION}; 227 throw new PolicyException(ResBundleUtils.rbName, 228 "missing_attribute_in_resourceresult", objs, null); 229 } else { 230 resourceResult.setPolicyDecision( 231 PolicyDecision.parsePolicyDecision(node)); 232 } 233 234 Set nodeSet = XMLUtils.getChildNodes( 235 resourceResultNode, RESOURCE_RESULT); 236 if (nodeSet != null) { 237 Iterator nodes = nodeSet.iterator(); 238 while (nodes.hasNext()) { 239 node = (Node)nodes.next(); 240 ResourceResult rRes = ResourceResult.parseResourceResult(node); 241 resourceResult.resourceResults.add(rRes); 242 } 243 } 244 245 return resourceResult; 246 } 247 248 249 /** 250 * Returns a string representation of this resource result 251 * @return a string representation of this resource result 252 * @supported.api 253 */ 254 public String toString() { 255 if (stringForm == null) { 256 StringBuilder sb = new StringBuilder(200); 257 sb.append("Resource Result for resourceName : ") 258 .append(resourceName) 259 .append(PolicyUtils.CRLF) 260 .append("PolicyDecision : ") 261 .append(policyDecision) 262 .append("Nested ResourceResults : ") 263 .append(resourceResults); 264 stringForm = sb.toString(); 265 } 266 return stringForm; 267 } 268 269 /** 270 * Returns an XML representation of this resource result 271 * @return an XML representation of this resource result 272 * @supported.api 273 */ 274 public String toXML() { 275 if (xmlForm == null) { 276 StringBuilder xmlsb = new StringBuilder(1000); 277 278 xmlsb.append("<") 279 .append(RESOURCE_RESULT) 280 .append(" ").append(RESOURCE_NAME) 281 .append("=\"") 282 .append(XMLUtils.escapeSpecialCharacters(resourceName)) 283 /* 284 .append("\" ").append("timeToLive") 285 .append("=\"").append(timeToLive).append("\"") 286 .append( " ").append("hasAdvices") 287 .append("=\"").append(hasAdvices()) 288 */ 289 .append("\">") 290 .append(PolicyUtils.CRLF); 291 if (policyDecision != null) { 292 xmlsb.append(policyDecision.toXML()); 293 } 294 295 Iterator rrIter = resourceResults.iterator(); 296 while ( rrIter.hasNext() ) { 297 ResourceResult rr = (ResourceResult) rrIter.next(); 298 xmlsb.append(rr.toXML()); 299 } 300 301 xmlsb.append("</") 302 .append(RESOURCE_RESULT) 303 .append( ">") 304 .append(PolicyUtils.CRLF); 305 306 xmlForm = xmlsb.toString(); 307 } 308 return xmlForm; 309 } 310 311 /** 312 * Adds a resource result to the resource result sub tree rooted at 313 * this ResourceResult 314 * @param resourceResult resource result to be added 315 * @param serviceType service type of the resource result being added 316 * @throws PolicyException if the resourceResult could not be added 317 */ 318 public void addResourceResult( ResourceResult resourceResult, 319 ServiceType serviceType) throws PolicyException { 320 addResourceResult(resourceResult, 321 serviceType.getResourceNameComparator()); 322 } 323 324 /** 325 * Adds a resource result to the resource result sub tree rooted at 326 * this ResourceResult 327 * @param resourceResult resource result to be added 328 * @param resourceComparator resource name comparator 329 * @throws PolicyException if the resourceResult could not be added 330 */ 331 public void addResourceResult( ResourceResult resourceResult, 332 ResourceName resourceComparator) throws PolicyException { 333 if (!this.isSuperResourceResultOf(resourceResult, 334 resourceComparator)) { 335 String[] objs = {this.resourceName, resourceResult.resourceName}; 336 throw new PolicyException(ResBundleUtils.rbName, 337 "invalid_sub_resourceresult", objs, null); 338 } else { 339 Iterator resourceResultIter = resourceResults.iterator(); 340 boolean directChild = true; 341 while (resourceResultIter.hasNext()) { 342 ResourceResult rResult = 343 (ResourceResult) resourceResultIter.next(); 344 if (rResult.isSuperResourceResultOf(resourceResult, 345 resourceComparator)) { 346 rResult.addResourceResult(resourceResult, 347 resourceComparator); 348 directChild = false; 349 break; 350 } 351 } 352 if (directChild) { 353 Set childrenToBeMoved = new HashSet(); 354 Iterator rrIter = resourceResults.iterator(); 355 while (rrIter.hasNext()) { 356 ResourceResult rResult = 357 (ResourceResult) rrIter.next(); 358 if (resourceResult.isSuperResourceResultOf(rResult, 359 resourceComparator)) { 360 childrenToBeMoved.add(rResult); 361 } 362 } 363 resourceResults.removeAll(childrenToBeMoved); 364 resourceResult.resourceResults.addAll(childrenToBeMoved); 365 resourceResults.add(resourceResult); 366 } 367 } 368 long rrTtl = resourceResult.getTimeToLive(); 369 if ( rrTtl < timeToLive ) { 370 timeToLive = rrTtl; 371 } 372 advicesAreSet = advicesAreSet || resourceResult.hasAdvices(); 373 this.stringForm = null; 374 this.xmlForm= null; 375 } 376 377 /** 378 * Marks result as stale 379 */ 380 public void markStale() { 381 stale = true; 382 } 383 384 /** 385 * Determines if result is stale 386 * 387 * @return true if result is stale 388 */ 389 public boolean isStale() { 390 return stale; 391 } 392 393 /** 394 * Checks if this resource result is a super resource result of 395 * the argument resource result 396 * @param resourceResult resource result for which we want to check 397 * whether this resource result is a super resource result 398 * @param resourceComparator - resource comparator 399 * @return <code>true</code> if this resource result is a super 400 * resource result of resourceResult, else returns 401 * <code>false</code> 402 * @throws PolicyException if there is any error while comparing the 403 * resourceResult 404 */ 405 private boolean isSuperResourceResultOf(ResourceResult resourceResult, 406 ResourceName resourceComparator) throws PolicyException { 407 boolean isSuperResource = false; 408 if (VIRTUAL_ROOT.equals(resourceName)) { 409 isSuperResource = true; 410 } else if (resourceComparator != null) { 411 boolean interpretWildCard = false; 412 ResourceMatch resourceMatch = 413 resourceComparator.compare(resourceName, 414 resourceResult.resourceName, interpretWildCard); 415 if (resourceMatch.equals(ResourceMatch.SUB_RESOURCE_MATCH)) { 416 isSuperResource = true; 417 } 418 // Results will contain both incoming URL as well as matched policy URL with decision. 419 // The problem is we don't know which order results will come in. 420 // Incoming URL will be missing policyDecision so we need to check resourceResult contains '*' 421 // and if it does, check if resourceResult is parent of incoming URL and use parent's 422 // policyDecision for this object. 423 else if (resourceResult.resourceName.indexOf('*') != -1 ) { 424 String resResultResName = resourceResult.resourceName; 425 String substrResultResName = resResultResName.substring(0, resResultResName.indexOf('*')); 426 if (resourceName.startsWith(substrResultResName)) { 427 //check if policyDecision is null 428 //if null, then copy policyDecision from parents 429 if (policyDecision==null || policyDecision.getActionDecisions().isEmpty()) { 430 policyDecision = resourceResult.policyDecision; 431 } 432 } 433 } 434 } else { 435 isSuperResource = 436 resourceResult.resourceName.startsWith(resourceName); 437 } 438 return isSuperResource; 439 } 440 441 /** 442 * Returns the GMT time in milliseconds since epoch when this object is to 443 * be treated as expired. That is the resource result would 444 * likely be different after that time. 445 * This is computed as a result of time conditions specified in the Policy 446 * definitions. 447 * 448 * @return time to live 449 */ 450 public long getTimeToLive() { 451 return timeToLive; 452 } 453 454 /** 455 * Checks wether advices are set in this object 456 * @return <code>true</code>, if advices are set, else <code>false</code> 457 */ 458 public boolean hasAdvices() { 459 return advicesAreSet; 460 } 461 462 /** 463 * Sets the environment map that was used while computing the 464 * resource result 465 * @param envMap the environment map that was used while computing the 466 * resource result 467 */ 468 void setEnvMap(Map envMap) { 469 this.envMap = envMap; 470 471 } 472 473 /** 474 * Returns the environment map that was used while computing the 475 * resource result 476 * @param the environment map that was used while computing the 477 * resource result 478 */ 479 Map getEnvMap() { 480 return envMap; 481 } 482 483} 484
Copyright © 2010-2017, ForgeRock All Rights Reserved.