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: PolicyDecision.java,v 1.3 2008/06/25 05:43:44 qcheng Exp $
026 *
027 * Portions Copyrighted 2011-2014 ForgeRock AS.
028 */
029package com.sun.identity.policy;
030
031import java.util.Map;
032import java.util.HashMap;
033import java.util.Set;
034import java.util.Iterator;
035import java.util.Collections;
036import com.sun.identity.shared.xml.XMLUtils;
037import com.sun.identity.sm.AttributeSchema;
038import org.w3c.dom.*;
039
040
041/**
042 * The <code>PolicyDecision</code> class represents the result of a policy
043 * evaluation. 
044 *
045 * @supported.api
046 * @deprecated since 12.0.0
047 */
048@Deprecated
049public class PolicyDecision {
050
051    static final String POLICY_DECISION = "PolicyDecision";
052    static final String RESPONSE_DECISIONS = "ResponseDecisions";
053    
054    //added in 7.0 for attributes provided by policy response providers
055    static final String RESPONSE_ATTRIBUTES = "ResponseAttributes"; 
056
057    Map actionDecisions = new HashMap();
058    private Map responseDecisions;
059    private Map responseAttributes;
060    private long timeToLive = Long.MAX_VALUE;
061    private boolean advicesAreSet = false;
062
063    /**
064     * Default constructor.
065     * @supported.api
066     */
067    public PolicyDecision() {
068    }
069
070    /**
071     * Gets the  <code>Map</code> of action decisions associated 
072     * with this policy decision. The 
073     * action name is the key to the Map. The value for each key is an 
074     * <code>ActionDecision</code>.
075     *
076     * @return  the  <code>Map</code> of action decisions associated 
077     *         with this policy decision. The 
078     *         action name is the key to the Map. The value for each key is an 
079     *         <code>ActionDecision</code>.
080     * @supported.api
081     */
082    public Map getActionDecisions() {
083        return actionDecisions;
084    }
085
086    /**
087     * Add an <code>ActionDecision</code> to the <code>PolicyDecision</code>
088     * These are the rules followed to add action decision:
089     * If the action schema has boolean syntax, boolean false value
090     * overrides boolean true value. The time to live of boolean false 
091     * value overrides the time to live of boolean true value.
092     * Otherwise, action values are simply  aggregated. Time to live
093     * is set to the minimum of time to live(s) of all values of the
094     * action.
095     *
096     * @param newActionDecision an <code>ActionDecision</code> to be added.
097     * @param resourceType <code>ServiceType</code> representing the
098     * service which provides the schema for the action.
099     * 
100     */
101
102    void addActionDecision(ActionDecision newActionDecision, ServiceType
103            resourceType) {
104        String action = newActionDecision.getActionName();
105        ActionDecision oldActionDecision 
106                = (ActionDecision) actionDecisions.get(action);
107        if ( oldActionDecision == null ) {
108            addActionDecision(newActionDecision);
109        } else {
110            ActionSchema actionSchema = null;
111            AttributeSchema.Syntax actionSyntax = null;
112            try {
113              actionSchema = resourceType.getActionSchema(action);
114              actionSyntax = actionSchema.getSyntax();
115            } catch(InvalidNameException e) {
116              PolicyManager.debug.error(
117                    "can not find action schmea for action = " 
118                     + action, e );
119            }
120            if (!AttributeSchema.Syntax.BOOLEAN.equals(
121                    actionSyntax)) {
122              addActionDecision(newActionDecision);
123            } else { //boolean valued action
124              String falseValue = actionSchema.getFalseValue();
125              String trueValue = actionSchema.getTrueValue();
126              addActionDecision(newActionDecision, trueValue, falseValue);
127            }
128        }
129    }
130
131    /**
132     * Add an <code>ActionDecision</code> to the <code>PolicyDecision</code>
133     * using the provided <code>trueValue</code> and <code>falseValue</code>
134     * These are the rules followed to add action decision:
135     * Boolean false value overrides boolean true value. The time to live 
136     * of boolean false value overrides the time to live of boolean true value.
137     * Otherwise, action values are simply  aggregated. Time to live
138     * is set to the minimum of time to live(s) of all values of the
139     * action.
140     *
141     * @param newActionDecision an <code>ActionDecision</code> to be added.
142     * @param trueValue <code>String</code> representing the </code>true</code>
143     * value in the action schema.
144     * @param falseValue <code>String</code> representing the 
145     * </code>false</code> value in the action schema.
146     * 
147     */
148    public void addActionDecision(ActionDecision newActionDecision, 
149            String trueValue, String falseValue) {
150        String action = newActionDecision.getActionName();
151        ActionDecision oldActionDecision 
152                = (ActionDecision) actionDecisions.get(action);
153        if ( (oldActionDecision == null) 
154                || (trueValue == null) || (falseValue == null)) {
155            addActionDecision(newActionDecision);
156        } else { //boolean valued action
157            long newTtl = newActionDecision.getTimeToLive();
158            long oldTtl = oldActionDecision.getTimeToLive();
159            Set oldActionValues = oldActionDecision.getValues();
160            Set newActionValues = newActionDecision.getValues();
161            Map advices = null;
162            Map oldAdvices = oldActionDecision.getAdvices();
163            Map newAdvices = newActionDecision.getAdvices();
164            advices = PolicyUtils.addMapToMap(oldAdvices, newAdvices);
165            if ( (oldActionValues != null) 
166                    && (oldActionValues.contains(falseValue)) ) {
167              if ( (newActionValues != null) 
168                        && newActionValues.contains(falseValue) ) {
169                  //both old and new values are false
170                  //get the ttl to max of newTtl and oldTtl
171                  oldActionDecision.setTimeToLive(Math.max(newTtl, oldTtl));
172              }
173
174              /* else block not required here since
175                 oldActionDecision does not need to change as it is false
176                 and newActionDecision is null or true
177              */
178            } else if ( (oldActionValues != null)
179                    && oldActionValues.contains(trueValue) ) {
180              if ( (newActionValues != null)
181                        && newActionValues.contains(falseValue) ) {
182                  actionDecisions.put(action, newActionDecision);
183              } else if ( newActionDecision.getValues().contains(trueValue) ) {
184                  //get the ttl to max of newTtl and oldTtl
185                  oldActionDecision.setTimeToLive(Math.max(newTtl, oldTtl));
186              }
187            } else {
188                  actionDecisions.put(action, newActionDecision);
189            }
190            ActionDecision ad = (ActionDecision) actionDecisions.get(action);
191            ad.setAdvices(advices);
192            setTimeToLive();
193        }
194    }
195
196    /**
197     * Adds an action decision to this object
198     * if there is already an existing actionDecision associated with the
199     * action name in the param <code>actionDecision</code>, merges
200     * the values of the new decision with the existing one,
201     * changing the time to live for the decision appropriately.
202     *
203     * @param actionDecision action decision to be added
204     * @supported.api
205     */
206    public void addActionDecision(ActionDecision actionDecision) {
207        ActionDecision oldDecision =
208                (ActionDecision) actionDecisions.get(
209                actionDecision.getActionName());
210        if ( oldDecision == null ) {
211            actionDecisions.put(actionDecision.getActionName(), 
212                    actionDecision);
213        } else {
214            Set oldValues = oldDecision.getValues();
215            if ( (oldValues == Collections.EMPTY_SET)
216                    || ( oldValues == null) ) {
217                    oldDecision.setValues(actionDecision.getValues());
218            } else {
219                oldValues.addAll(actionDecision.getValues());
220            }
221            if ( actionDecision.getTimeToLive() 
222                    < oldDecision.getTimeToLive() ) {
223                oldDecision.setTimeToLive(actionDecision.getTimeToLive());
224            }
225            PolicyUtils.appendMapToMap(actionDecision.getAdvices(),
226                    oldDecision.getAdvices());
227        }
228        setTimeToLive();
229    }
230
231    /**
232     * Gets a String representation of this <code>PolicyDecision</code>
233     * @return a String representation of this <code>PolicyDecision</code>
234     *
235     * @supported.api
236     */
237     public String toString() {
238        StringBuilder sb = new StringBuilder();
239        if ((responseAttributes != null) && 
240            (responseAttributes != Collections.EMPTY_MAP)) {
241             Iterator attrNames = responseAttributes.keySet().iterator();
242             while ( attrNames.hasNext() ) {
243                 String attrName = (String) attrNames.next();
244                 Set attrValues = (Set) responseAttributes.get(attrName);
245                 sb.append(attrName).append("=").append(attrValues).append("\n");
246             }
247        }
248        Iterator actionNames = actionDecisions.keySet().iterator();
249        while ( actionNames.hasNext() ) {
250            String actionName = (String) actionNames.next();
251            ActionDecision actionDecision = 
252                (ActionDecision) actionDecisions.get(actionName);
253            Set actionValues = (Set) actionDecision.getValues();
254            sb.append(actionName).append("=").append(actionValues).append("\n");
255        }
256        return sb.toString();
257     }
258
259
260    /**
261     * Gets an XML representation of this object
262     * @return an XML representation of this object
263     *
264     * @supported.api
265     */
266     public String toXML() {
267        StringBuilder sb  = new StringBuilder(300);
268        sb.append("<").append(POLICY_DECISION)
269               /*
270                .append(" ").append("timeToLive")
271                .append("=\"").append(timeToLive).append("\"") 
272                .append(" ").append("hasAdvices")
273                .append("=\"").append(hasAdvices()).append("\"")  
274                */
275                .append(">").append(PolicyUtils.CRLF);
276        if ((responseAttributes != null) && 
277            (responseAttributes != Collections.EMPTY_MAP)) {
278            sb.append("<").append(RESPONSE_ATTRIBUTES);
279            sb.append(">").append(PolicyUtils.CRLF);
280            sb.append(PolicyUtils.mapToXMLString(responseAttributes));
281            sb.append("<").append("/").append(RESPONSE_ATTRIBUTES);
282            sb.append(">").append(PolicyUtils.CRLF);
283        }
284        Iterator actionNames = actionDecisions.keySet().iterator();
285        while ( actionNames.hasNext() ) {
286            String actionName = (String) actionNames.next();
287            ActionDecision actionDecision = (ActionDecision)
288            actionDecisions.get(actionName);
289            sb.append(actionDecision.toXML());
290        }
291        if (responseDecisions != null) {
292            sb.append("<").append(RESPONSE_DECISIONS).append(">")
293                    .append(PolicyUtils.CRLF);
294            sb.append(PolicyUtils.mapToXMLString(responseDecisions));
295            sb.append("</").append(RESPONSE_DECISIONS).append(">")
296                    .append(PolicyUtils.CRLF);
297        }
298        sb.append("</").append(POLICY_DECISION).append(">");
299        sb.append(PolicyUtils.CRLF);
300        return sb.toString();
301     }
302
303    /**
304     * Gets a PolicyDecision given corresponding XML node
305     * @param policyDecisionNode XML node for the policy decision
306     * @return policy decision based on the XML node
307     */
308     public static PolicyDecision parsePolicyDecision(Node policyDecisionNode) 
309        throws PolicyException 
310    {
311        PolicyDecision policyDecision = new PolicyDecision();
312        Set nodeSet = XMLUtils.getChildNodes(policyDecisionNode, 
313                ActionDecision.ACTION_DECISION);
314        if (nodeSet == null) {
315            PolicyManager.debug.error("parsePolicyDecision: Required element "
316                + "not found in policy decision node:"
317                + ActionDecision.ACTION_DECISION);
318            Object [] args = { ActionDecision.ACTION_DECISION };
319            throw new PolicyException(ResBundleUtils.rbName,
320                "missing_element", args, null);
321        } else {
322            Iterator nodes = nodeSet.iterator();
323            while (nodes.hasNext()) {
324                Node node = (Node)nodes.next();
325                ActionDecision actionDecision = 
326                    ActionDecision.parseActionDecision(node);
327                policyDecision.addActionDecision(actionDecision);
328            }
329        }
330        Set resposeAttrsSet = XMLUtils.getChildNodes(policyDecisionNode, 
331                RESPONSE_ATTRIBUTES);
332        if ( (resposeAttrsSet != null) && !resposeAttrsSet.isEmpty() ) {
333            Node node = (Node) resposeAttrsSet.iterator().next();
334            Map responseAttrsMap = PolicyUtils.parseAttributeValuePairs(node);
335            policyDecision.setResponseAttributes(responseAttrsMap);
336        }
337        Set responseNodeSet = XMLUtils.getChildNodes(policyDecisionNode, 
338                RESPONSE_DECISIONS);
339        if ( (responseNodeSet != null) && !responseNodeSet.isEmpty() ) {
340            Node node = (Node) responseNodeSet.iterator().next();
341            Map responseMap = PolicyUtils.parseAttributeValuePairs(node);
342            policyDecision.setResponseDecisions(responseMap);
343        }
344        return policyDecision;
345     }
346
347    /**
348     * 
349     * Gets response decisions associated with this policy decision
350     * @return <code>Map</code> representing the response decisions associated 
351     * with this policy decision
352     *
353     */
354    public Map getResponseDecisions() {
355        return responseDecisions;
356    }
357
358    /**
359     * 
360     * Sets response decisions associated with this policy decision
361     * @param responseDecisions A <code>Map</code> representing response 
362     * decisions associated with this policy decision
363     */
364    public void setResponseDecisions(Map responseDecisions) {
365        this.responseDecisions = responseDecisions;
366    }
367
368
369    /**
370     * 
371     * Gets response attributes associated with this policy decision.
372     * Response attributes are computed as an aggregation of the return
373     * <code>Map</code>(s) of the <code>ResponseProvider</code> objects 
374     * associated with the policy obtained via the getResponseDecision() call.
375     * @return the <code>Map</code> of response attributes associated with 
376     * this policy decision.
377     *
378     */
379    public Map getResponseAttributes() {
380        return responseAttributes;
381    }
382
383    /**
384     * 
385     * Sets response attributes associated with this policy decision
386     * @param responseAttributes <code>Map</code> of attribute value pairs 
387     * associated with this policy decision.
388     */
389    public void setResponseAttributes(Map responseAttributes) {
390        this.responseAttributes = responseAttributes;
391    }
392    /**
393     * Makes a copy of this object
394     *
395     * @return a copied instance
396     */
397    public Object clone() {
398        PolicyDecision clone = new PolicyDecision();
399        clone.actionDecisions = new HashMap(actionDecisions.size());
400        Iterator actionDecisionIter = actionDecisions.keySet().iterator();
401        while (actionDecisionIter.hasNext()) {
402            String key = (String) actionDecisionIter.next();
403            ActionDecision ad = (ActionDecision) actionDecisions.get(key);
404            clone.addActionDecision((ActionDecision)ad.clone());
405        }
406
407        if (responseDecisions != null) {
408            clone.responseDecisions = new HashMap(responseDecisions.size());
409            Iterator responseDecisionsIter =
410                responseDecisions.keySet().iterator();
411            while (responseDecisionsIter.hasNext()) {
412                String key = (String) responseDecisionsIter.next();
413                clone.responseDecisions.put(key, responseDecisions.get(key));
414            }
415        }
416        if (responseAttributes != null) {
417            clone.responseAttributes = new HashMap(responseAttributes.size());
418            Iterator responseAttributesIter =
419                responseAttributes.keySet().iterator();
420            while (responseAttributesIter.hasNext()) {
421                String key = (String) responseAttributesIter.next();
422                clone.responseAttributes.put(key, responseAttributes.get(key));
423            }
424        }
425        return clone;
426    }
427
428
429    /**
430     * Gets the GMT time in milliseconds since epoch when this object is to
431     * be treated as expired. That is the policy decision would likely 
432     * be different after that time.
433     * This is computed as a result of <code>SimpleTimeCondition</code>s 
434     * specified in the <code>Policy</code> definition. 
435     *
436     * @return time to live
437     */
438    public long getTimeToLive() {
439        return timeToLive;
440    }
441
442    /**
443     * Sets the <code>timeToLive</code> value of the policy decision to the
444     * smallest of <code>timeToLive(s)<code> of contained
445     * <code>ActionDecision(s)<code>. Also sets value of
446     * <code>advicesAreSet</code>. This is set to <code>true</code>
447     * if any of the contained action decision(s) has advice defined.
448     */
449    private void setTimeToLive() {
450        timeToLive = Long.MAX_VALUE;
451        advicesAreSet = false;
452        Iterator actionDecisionIter = actionDecisions.keySet().iterator();
453        while (actionDecisionIter.hasNext()) {
454            String key = (String) actionDecisionIter.next();
455            ActionDecision ad = (ActionDecision) actionDecisions.get(key);
456            long actionTtl = ad.getTimeToLive();
457            if ( actionTtl < timeToLive) {
458                timeToLive = actionTtl;
459            }
460            advicesAreSet = advicesAreSet || 
461                 ((ad.getAdvices()) != null) && (!(ad.getAdvices().isEmpty()));
462        }
463    }
464
465    /**
466     * Sets the timeToLive value of the policy decision.
467     *
468     * @param ttl timeToLive value to be set
469     */
470    void setTimeToLive(long ttl) {
471        timeToLive = ttl;
472    }
473
474    /**
475     * Checks wether advices are set in this object
476     * @return <code>true</code>, if advices are set, else <code>false</code>
477     */
478    public boolean hasAdvices() {
479        return advicesAreSet;
480    }
481}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.