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: ActionDecision.java,v 1.5 2008/06/25 05:43:43 qcheng Exp $ 026 * 027 * Portions Copyrighted 2011-2014 ForgeRock AS. 028 */ 029package com.sun.identity.policy; 030 031import com.sun.identity.shared.debug.Debug; 032import com.sun.identity.shared.xml.XMLUtils; 033import java.util.Map; 034import java.util.HashMap; 035import java.util.Set; 036import java.util.HashSet; 037import java.util.Iterator; 038import org.w3c.dom.*; 039 040 041/** 042 * The <code>ActionDecision</code> class represents the action results of a 043 * policy evaluation. It has action values for a given <code>action</code> and 044 * <code>advice</code>. 045 * 046 * @supported.api 047 * @deprecated since 12.0.0 048 */ 049@Deprecated 050public class ActionDecision { 051 052 static final String ACTION_DECISION = "ActionDecision"; 053 static final String ADVICES = "Advices"; 054 static final String VALUES = "Values"; 055 static final String TIME_TO_LIVE = "timeToLive"; 056 static Debug debug = Debug.getInstance("amPolicy"); 057 058 private String actionName; 059 private Set values; 060 private long timeToLive = Long.MAX_VALUE; 061 private Map advices; 062 063 /** 064 * Difference of system clock on the client machine compared to 065 * policy server machine. Valid life of policy decisions are extended 066 * by this skew on the client side. 067 * Value for this is set by reading property 068 * com.sun.identity.policy.client.clockSkew 069 * from SystemProperties 070 * If the value is not defined in AMConfig.properties, 071 * this would default to 0. 072 */ 073 private static long clientClockSkew = 0; 074 075 /** 076 * No argument constructor 077 * @deprecated No replacement API provided. 078 * There should be no need to invoke this constructor. 079 */ 080 public ActionDecision() { 081 } 082 083 /** 084 * Constructor 085 * @param actionName name of the action. 086 * @param values a <code>Set></code> of <code>String</code> values for the 087 * action 088 * @supported.api 089 */ 090 public ActionDecision(String actionName, Set values) { 091 this.actionName = actionName; 092 this.values = values; 093 } 094 095 /** 096 * Constructor 097 * @param actionName action name 098 * @param values a <code>Set</code> of <code>String</code> values for the 099 * action 100 * @param advices <code>advices</code> associated with this action 101 * decision. The advice name is the key to the Map. The 102 * value is a set of advice message Strings corresponding 103 * to the advice name. 104 * @param timeToLive the GMT time in milliseconds since epoch 105 * when this object is to be treated as expired. 106 * That is the action values would likely be different 107 * after that time. 108 * @supported.api 109 */ 110 public ActionDecision(String actionName, Set values, Map advices, 111 long timeToLive 112 ) { 113 this.actionName = actionName; 114 this.values = values; 115 this.advices = advices; 116 this.timeToLive = timeToLive; 117 } 118 119 /** 120 * Gets the name of the action 121 * 122 * @return name of the action 123 * @supported.api 124 */ 125 public String getActionName() { 126 return actionName; 127 } 128 129 /** 130 * Sets the action values for the action. 131 * 132 * @param values a <code>Set</code> of String values 133 * @supported.api 134 */ 135 public void setValues(Set values) { 136 this.values = values; 137 } 138 139 /** 140 * Gets the action values for the action. 141 * 142 * @return a <code>Set>/code> of String values 143 * @supported.api 144 */ 145 public Set getValues() { 146 return values; 147 } 148 149 /** 150 * Gets the GMT time in milliseconds since epoch when this object is to 151 * be treated as expired. That is the action values would likely be 152 * different after that time. 153 * This is computed as a result of <code>SimpleTimeCondition(s)</code> 154 * specified in the Policy definition. 155 * 156 * @return long represeting the time to live for this object. 157 * @supported.api 158 */ 159 public long getTimeToLive() { 160 return timeToLive; 161 } 162 163 /** 164 * Sets the GMT time in milliseconds since epoch when this object is to 165 * be treated as expired. That is the action values would likely be 166 * different after that time. 167 * This is computed as a result of <code>SimpleTimeCondition(s)</code> 168 * specified in the Policy definition. 169 * 170 * @param timeToLive time to live 171 * @supported.api 172 */ 173 public void setTimeToLive(long timeToLive) { 174 this.timeToLive = timeToLive; 175 } 176 177 /** 178 * Sets <code>advices</code> associated with this <code>ActionDecision 179 * </code>. 180 * The advice name is the key to the <code>Map</code>. The 181 * value is a <code>Set</code> of advice message Strings corresponding to 182 * the advice name. The two possible advices are authentication 183 * level(<code>AuthLevel</code>) and authentication modules 184 * (<code>AuthSchemes</code>). The advice message Strings for 185 * <code>AuthLevel</code> are integer valued. 186 * 187 * @param advices map of advices 188 * @supported.api 189 */ 190 public void setAdvices(Map advices) { 191 this.advices = advices; 192 } 193 194 /** 195 * Returns a <code>Map</code> of <code>advices</code> associated with this 196 * object. 197 * The advice name is the key to the <code>Map</code>. The 198 * value is a <code>Set</code> of advice message Strings corresponding to 199 * the advice name. The two possible advices are authentication 200 * level(<code>AuthLevel</code>) and authentication modules 201 * (<code>AuthSchemes</code>). The advice message Strings for 202 * <code>AuthLevel</code> are integer valued. 203 * 204 * @return advices associated with this <code>ActionDecision</code>. 205 * @supported.api 206 */ 207 public Map getAdvices() { 208 return advices; 209 } 210 211 /** 212 * Gets a String representation of this object 213 * 214 * @return a String representation of this object 215 * @supported.api 216 */ 217 public String toString() { 218 return actionName + "=" + values; 219 } 220 221 /** 222 * Gets an XML representation of this object 223 * 224 * @return XML representation of this object 225 * @supported.api 226 */ 227 public String toXML() { 228 StringBuilder sb = new StringBuilder(300); 229 sb.append("<").append(ACTION_DECISION).append(" "); 230 sb.append(TIME_TO_LIVE).append("=").append( 231 PolicyUtils.quote(timeToLive)).append(">"); 232 sb.append(PolicyUtils.CRLF); 233 sb.append(PolicyUtils.attributeValuePairToXMLString(getActionName(), 234 values)); 235 sb.append("<").append(ADVICES).append(">").append(PolicyUtils.CRLF); 236 if (advices != null) { 237 sb.append(PolicyUtils.mapToXMLString(advices)); 238 } 239 sb.append("</").append(ADVICES).append(">").append(PolicyUtils.CRLF); 240 sb.append("</").append(ACTION_DECISION).append(">").append( 241 PolicyUtils.CRLF); 242 return sb.toString(); 243 } 244 245 /** 246 * Creates an ActionDecisions object given a w3c DOM node 247 * @param actionDecisionNode w3c DOM node for action decision 248 * 249 * @return ActionDecisions object created using the w3c DOM node 250 * @throws PolicyException if any error occurs during parsing. 251 */ 252 public static ActionDecision parseActionDecision(Node actionDecisionNode) 253 throws PolicyException { 254 ActionDecision actionDecision = null; 255 //process action name and values 256 Set nodeSet = XMLUtils.getChildNodes(actionDecisionNode, 257 PolicyUtils.ATTRIBUTE_VALUE_PAIR); 258 if ( (nodeSet == null) || (nodeSet.isEmpty()) ) { 259 debug.error("parseActionDecision: missing element " 260 + PolicyUtils.ATTRIBUTE_VALUE_PAIR); 261 return null; 262 } 263 Iterator nodes = nodeSet.iterator(); 264 Node node = (Node)nodes.next(); 265 String actionName = PolicyUtils.getAttributeName(node); 266 Set actionValues = PolicyUtils.getAttributeValues(node); 267 actionDecision = new ActionDecision(actionName, 268 actionValues); 269 270 //process timeToLive 271 long timeToLive = Long.MAX_VALUE; 272 String ttlString = XMLUtils.getNodeAttributeValue(actionDecisionNode, 273 ActionDecision.TIME_TO_LIVE) ; 274 if ( ttlString != null ) { 275 try { 276 timeToLive = Long.parseLong(ttlString); 277 if (timeToLive != Long.MAX_VALUE) { 278 timeToLive += clientClockSkew; 279 } 280 } catch (Exception e) { 281 debug.error("Error while parsing timeToLive in " 282 + " ActionDecision:" + ttlString); 283 Object [] args = { new Long(timeToLive) }; 284 throw new PolicyException(ResBundleUtils.rbName, 285 "invalid_time_to_live", 286 args,e); 287 } 288 } 289 actionDecision.setTimeToLive(timeToLive); 290 291 //process advices 292 Map advices = new HashMap(); 293 nodeSet = XMLUtils.getChildNodes(actionDecisionNode, 294 ActionDecision.ADVICES); 295 if (nodeSet != null) { 296 nodes = nodeSet.iterator(); 297 node = (Node) nodes.next(); 298 nodeSet = XMLUtils.getChildNodes(node, 299 PolicyUtils.ATTRIBUTE_VALUE_PAIR); 300 if ( nodeSet != null ) { 301 nodes = nodeSet.iterator(); 302 while ( nodes.hasNext() ) { 303 node = (Node) nodes.next(); 304 String adviceName = PolicyUtils.getAttributeName(node); 305 if ( adviceName != null ) { 306 Set adviceMessages = PolicyUtils. 307 getAttributeValues(node); 308 advices.put(adviceName, adviceMessages); 309 } 310 } 311 } 312 } 313 actionDecision.setAdvices(advices); 314 315 return actionDecision; 316 } 317 318 /** 319 * Creates and returns a copy of this object. 320 * 321 * @return a copy of this object 322 */ 323 public Object clone() { 324 ActionDecision clone = new ActionDecision(); 325 clone.actionName = actionName; 326 clone.timeToLive = timeToLive; 327 328 if (values != null) { 329 Iterator valuesIter = values.iterator(); 330 clone.values = new HashSet(values.size()); 331 while (valuesIter.hasNext()) { 332 clone.values.add(valuesIter.next()); 333 } 334 } 335 336 if (advices != null) { 337 Iterator adviceIter = advices.keySet().iterator(); 338 clone.advices = new HashMap(advices.size()); 339 340 while (adviceIter.hasNext()) { 341 String key = (String) adviceIter.next(); 342 clone.advices.put(key, advices.get(key)); 343 } 344 } 345 346 return clone; 347 } 348 349 /** 350 * Sets the client clock skew 351 * @param skew the time skew in milliseconds, serverTime - clientTime 352 */ 353 public static void setClientClockSkew(long skew) { 354 clientClockSkew = skew; 355 } 356 357}