Package org.jboss.security.xacml.sunxacml.ctx

Source Code of org.jboss.security.xacml.sunxacml.ctx.Result

/*
* @(#)Result.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*   1. Redistribution of source code must retain the above copyright notice,
*      this list of conditions and the following disclaimer.
*
*   2. Redistribution in binary form must reproduce the above copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/

package org.jboss.security.xacml.sunxacml.ctx;


import java.io.OutputStream;
import java.io.PrintStream;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.jboss.security.xacml.sunxacml.Indenter;
import org.jboss.security.xacml.sunxacml.Obligation;
import org.jboss.security.xacml.sunxacml.ParsingException;
import org.jboss.security.xacml.sunxacml.SunxacmlUtil;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
* Represents the ResultType XML object from the Context schema. Any number
* of these may included in a <code>ResponseCtx</code>. This class encodes the
* decision effect, as well as an optional resource identifier and optional
* status data. Any number of obligations may also be included.
*
* @since 1.0
* @author Seth Proctor
* @author Marco Barreno
*/
@SuppressWarnings({ "unchecked", "rawtypes"})
public class Result
{

    /**
     * The decision to permit the request
     */
    public static final int DECISION_PERMIT = 0;

    /**
     * The decision to deny the request
     */
    public static final int DECISION_DENY = 1;

    /**
     * The decision that a decision about the request cannot be made
     */
    public static final int DECISION_INDETERMINATE = 2;

    /**
     * The decision that nothing applied to us
     */
    public static final int DECISION_NOT_APPLICABLE = 3;

    // string versions of the 4 Decision types used for encoding
    public static final String [] DECISIONS = { "Permit", "Deny",
                                                "Indeterminate",
                                                "NotApplicable" };

    // the decision effect
    private int decision = -1;

    // the status data
    private Status status = null;

    // the resource identifier or null if there is none
    private String resource = null;

    // the set of obligations which may be empty
    private Set obligations;
   
    /**
     * Constructs a <code>Result</code> object with default status data (OK).
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision) throws IllegalArgumentException {
        this(decision, null, null, null);
    }
   
    /**
     * Constructs a <code>Result</code> object with default status data (OK),
     * and obligations, but no resource identifier.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param obligations the obligations the PEP must handle
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, Set obligations)
        throws IllegalArgumentException
    {
        this(decision, null, null, obligations);
    }

    /**
     * Constructs a <code>Result</code> object with status data but without a
     * resource identifier. Typically the decision is DECISION_INDETERMINATE
     * in this case, though that's not always true.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param status the <code>Status</code> to include in this result
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, Status status) throws IllegalArgumentException {
        this(decision, status, null, null);
    }

    /**
     * Constructs a <code>Result</code> object with status data and obligations
     * but without a resource identifier. Typically the decision is
     * DECISION_INDETERMINATE in this case, though that's not always true.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param status the <code>Status</code> to include in this result
     * @param obligations the obligations the PEP must handle
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, Status status, Set obligations)
        throws IllegalArgumentException
    {
        this(decision, status, null, obligations);
    }

    /**
     * Constructs a <code>Result</code> object with a resource identifier,
     * but default status data (OK). The resource being named must match
     * the resource (or a descendent of the resource in the case of a
     * hierarchical resource) from the associated request.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param resource a <code>String</code> naming the resource
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, String resource)
        throws IllegalArgumentException
    {
        this(decision, null, resource, null);
    }

    /**
     * Constructs a <code>Result</code> object with a resource identifier,
     * and obligations, but default status data (OK). The resource being named
     * must match the resource (or a descendent of the resource in the case of
     * a hierarchical resource) from the associated request.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param resource a <code>String</code> naming the resource
     * @param obligations the obligations the PEP must handle
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, String resource, Set obligations)
        throws IllegalArgumentException
    {
        this(decision, null, resource, obligations);
    }

    /**
     * Constructs a <code>Result</code> object with status data and a
     * resource identifier.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param status the <code>Status</code> to include in this result
     * @param resource a <code>String</code> naming the resource
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, Status status, String resource)
        throws IllegalArgumentException
    {
        this(decision, status, resource, null);
    }

    /**
     * Constructs a <code>Result</code> object with status data, a
     * resource identifier, and obligations.
     *
     * @param decision the decision effect to include in this result. This
     *                 must be one of the four fields in this class.
     * @param status the <code>Status</code> to include in this result
     * @param resource a <code>String</code> naming the resource
     * @param obligations the obligations the PEP must handle
     *
     * @throws IllegalArgumentException if decision is not valid
     */
    public Result(int decision, Status status, String resource,
                  Set obligations)
        throws IllegalArgumentException
    {
        // check that decision is valid
        if ((decision != DECISION_PERMIT) && (decision != DECISION_DENY) &&
            (decision != DECISION_INDETERMINATE) &&
            (decision != DECISION_NOT_APPLICABLE))
            throw new IllegalArgumentException("invalid decision value");

        this.decision = decision;
        this.resource = resource;

        if (status == null)
            this.status = Status.getOkInstance();
        else
            this.status = status;

        if (obligations == null)
            this.obligations = new HashSet();
        else
            this.obligations = obligations;
    }

    /**
     * Creates a new instance of a <code>Result</code> based on the given
     * DOM root node. A <code>ParsingException</code> is thrown if the DOM
     * root doesn't represent a valid ResultType.
     *
     * @param root the DOM root of a ResultType
     *
     * @return a new <code>Result</code>
     *
     * @throws ParsingException if the node is invalid
     */
    public static Result getInstance(Node root) throws ParsingException {
        int decision = -1;
        Status status = null;
        String resource = null;
        Set obligations = null;

        NamedNodeMap attrs = root.getAttributes();
        Node resourceAttr = attrs.getNamedItem("ResourceId");
        if (resourceAttr != null)
            resource = resourceAttr.getNodeValue();

        NodeList nodes = root.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            String name = SunxacmlUtil.getNodeName(node);

            if (name.equals("Decision")) {
                String type = node.getFirstChild().getNodeValue();
                for (int j = 0; j < DECISIONS.length; j++) {
                    if (DECISIONS[j].equals(type)) {
                        decision = j;
                        break;
                    }
                }

                if (decision == -1)
                    throw new ParsingException("Unknown Decision: " + type);
            } else if (name.equals("Status")) {
                status = Status.getInstance(node);
            } else if (name.equals("Obligations")) {
                obligations = parseObligations(node);
            }
        }

        return new Result(decision, status, resource, obligations);
    }

    /**
     * Helper method that handles the obligations
     */
    private static Set parseObligations(Node root) throws ParsingException {
        Set set = new HashSet();

        NodeList nodes = root.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if (SunxacmlUtil.getNodeName(node).equals("Obligation"))
                set.add(Obligation.getInstance(node));
        }

        if (set.size() == 0)
            throw new ParsingException("ObligationsType must not be empty");
       
        return set;
    }

    /**
     * Returns the decision associated with this <code>Result</code>. This
     * will be one of the four <code>DECISION_*</code> fields in this class.
     *
     * @return the decision effect
     */
    public int getDecision() {
        return decision;
    }

    /**
     * Returns the status data included in this <code>Result</code>.
     * Typically this will be <code>STATUS_OK</code> except when the decision
     * is <code>INDETERMINATE</code>.
     *
     * @return status associated with this Result
     */
    public Status getStatus() {
        return status;
    }

    /**
     * Returns the resource to which this Result applies, or null if none
     * is specified.
     *
     * @return a resource identifier or null
     */
    public String getResource() {
        return resource;
    }

    /**
     * Sets the resource identifier if it has not already been set before.
     * The core code does not set the resource identifier, so this is useful
     * if you want to write wrapper code that needs this information.
     *
     * @param resource the resource identifier
     *
     * @return true if the resource identifier was set, false if it already
     *         had a value
     */
    public boolean setResource(String resource) {
        if (this.resource != null)
            return false;

        this.resource = resource;

        return true;
    }

    /**
     * Returns the set of obligations that the PEP must fulfill, which may
     * be empty.
     *
     * @return the set of obligations
     */
    public Set getObligations() {
        return obligations;
    }

    /**
     * Adds an obligation to the set of obligations that the PEP must fulfill
     *
     * @param obligation the <code>Obligation</code> to add
     */
    public void addObligation(Obligation obligation) {
        if (obligation != null)
            obligations.add(obligation);
    }

    /**
     * Encodes this <code>Result</code> into its XML form and writes this
     * out to the provided <code>OutputStream<code> with no indentation.
     *
     * @param output a stream into which the XML-encoded data is written
     */
    public void encode(OutputStream output) {
        encode(output, new Indenter(0));
    }

    /**
     * Encodes this <code>Result</code> into its XML form and writes this
     * out to the provided <code>OutputStream<code> with indentation.
     *
     * @param output a stream into which the XML-encoded data is written
     * @param indenter an object that creates indentation strings
     */
    public void encode(OutputStream output, Indenter indenter) {
        PrintStream out = new PrintStream(output);
        String indent = indenter.makeString();

        indenter.in();
        String indentNext = indenter.makeString();

        // encode the starting tag
        if (resource == null)
            out.println(indent + "<Result>");
        else
            out.println(indent + "<Result ResourceId=\"" + resource + "\">");

        // encode the decision
        out.println(indentNext + "<Decision>" + DECISIONS[decision] +
                    "</Decision>");
       
        // encode the status
        if (status != null)
            status.encode(output, indenter);

        // encode the obligations
        if (obligations.size() != 0) {
            out.println(indentNext + "<Obligations>");
           
            Iterator it = obligations.iterator();
            indenter.in();

            while (it.hasNext()) {
                Obligation obligation = (Obligation)(it.next());
                obligation.encode(output, indenter);
            }

            indenter.out();
            out.println(indentNext + "</Obligations>");
        }

        indenter.out();

        // finish it off
        out.println(indent + "</Result>");
    }
}
TOP

Related Classes of org.jboss.security.xacml.sunxacml.ctx.Result

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.