⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 target.java

📁 sunxacml源码
💻 JAVA
字号:

/*
 * @(#)Target.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 com.sun.xacml;

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

import java.util.logging.Level;
import java.util.logging.Logger;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Represents the TargetType XML type in XACML. This also stores several
 * other XML types: Subjects, Resources, Actions, and Environments (in XACML
 * 2.0 and later). The target is used to quickly identify whether the parent
 * element (a policy set, policy, or rule) is applicable to a given request. 
 *
 * @since 1.0
 * @author Seth Proctor
 */
public class Target
{

    // the four sections of a Target
    private TargetSection subjectsSection;
    private TargetSection resourcesSection;
    private TargetSection actionsSection;
    private TargetSection environmentsSection;

    // the version of XACML of the policy containing this target
    private int xacmlVersion;

    // the logger we'll use for all messages
    private static final Logger logger =
        Logger.getLogger(Target.class.getName());

    /**
     * Constructor that creates an XACML 1.x <code>Target</code> from
     * components. Each of the sections must be non-null, but they may match
     * any request. Because this is only used for 1.x Targets, there is no
     * Environments section.
     *
     * @param subjectsSection a <code>TargetSection</code> representing
     *                        the Subjects section of this target
     * @param resourcesSection a <code>TargetSection</code> representing
     *                         the Resources section of this target
     * @param actionsSection a <code>TargetSection</code> representing
     *                       the Actions section of this target
     */
    public Target(TargetSection subjectsSection,
                  TargetSection resourcesSection,
                  TargetSection actionsSection) {
        if ((subjectsSection == null) || (resourcesSection == null) ||
            (actionsSection == null))
            throw new ProcessingException("All sections of a Target must " +
                                          "be non-null");
        
        this.subjectsSection = subjectsSection;
        this.resourcesSection = resourcesSection;
        this.actionsSection = actionsSection;
        this.environmentsSection =
            new TargetSection(null, TargetMatch.ENVIRONMENT,
                              PolicyMetaData.XACML_VERSION_1_0);
        this.xacmlVersion = PolicyMetaData.XACML_VERSION_1_0;
    }

    /**
     * Constructor that creates an XACML 2.0 <code>Target</code> from
     * components. Each of the sections must be non-null, but they may
     * match any request.
     *
     * @param subjectsSection a <code>TargetSection</code> representing
     *                        the Subjects section of this target
     * @param resourcesSection a <code>TargetSection</code> representing
     *                         the Resources section of this target
     * @param actionsSection a <code>TargetSection</code> representing
     *                       the Actions section of this target
     * @param environmentsSection a <code>TargetSection</code> representing
     *                            the Environments section of this target
     */
    public Target(TargetSection subjectsSection,
                  TargetSection resourcesSection,
                  TargetSection actionsSection,
                  TargetSection environmentsSection)
    {
        if ((subjectsSection == null) || (resourcesSection == null) ||
            (actionsSection == null) || (environmentsSection == null))
            throw new ProcessingException("All sections of a Target must " +
                                          "be non-null");

        this.subjectsSection = subjectsSection;
        this.resourcesSection = resourcesSection;
        this.actionsSection = actionsSection;
        this.environmentsSection = environmentsSection;
        this.xacmlVersion =  PolicyMetaData.XACML_VERSION_2_0;
    }

    /**
     * Creates a <code>Target</code> by parsing a node.
     *
     * @deprecated As of 2.0 you should avoid using this method and should
     *             instead use the version that takes a
     *             <code>PolicyMetaData</code> instance. This method will
     *             only work for XACML 1.x policies.
     *
     * @param root the node to parse for the <code>Target</code>
     * @param xpathVersion the XPath version to use in any selectors, or
     *                     null if this is unspecified (ie, not supplied in
     *                     the defaults section of the policy)
     *
     * @return a new <code>Target</code> constructed by parsing
     *
     * @throws ParsingException if the DOM node is invalid
     */
    public static Target getInstance(Node root, String xpathVersion)
        throws ParsingException
    {
        return getInstance(root,
                           new PolicyMetaData(
                                   PolicyMetaData.XACML_1_0_IDENTIFIER,
                                   xpathVersion));
    }

    /**
     * Creates a <code>Target</code> by parsing a node.
     *
     * @param root the node to parse for the <code>Target</code>
     * @return a new <code>Target</code> constructed by parsing
     *
     * @throws ParsingException if the DOM node is invalid
     */
    public static Target getInstance(Node root, PolicyMetaData metaData)
        throws ParsingException
    {
        TargetSection subjects = null;
        TargetSection resources = null;
        TargetSection actions = null;
        TargetSection environments = null;

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

            if (name.equals("Subjects")) {
                subjects =
                    TargetSection.getInstance(child, TargetMatch.SUBJECT,
                                              metaData);
            } else if (name.equals("Resources")) {
                resources =
                    TargetSection.getInstance(child, TargetMatch.RESOURCE,
                                              metaData);
            } else if (name.equals("Actions")) {
                actions =
                    TargetSection.getInstance(child, TargetMatch.ACTION,
                                              metaData);
            } else if (name.equals("Environments")) {
                environments =
                    TargetSection.getInstance(child, TargetMatch.ENVIRONMENT,
                                              metaData);
            }
        }

        // starting in 2.0 an any-matching section is represented by a
        // missing element, and in 1.x there were no Environments elements,
        // so these need to get turned into non-null arguments
        int version = metaData.getXACMLVersion();

        if (subjects == null)
            subjects = new TargetSection(null, TargetMatch.SUBJECT, version);
        if (resources == null)
            resources = new TargetSection(null, TargetMatch.RESOURCE, version);
        if (actions == null)
            actions = new TargetSection(null, TargetMatch.ACTION, version);

        if (version == PolicyMetaData.XACML_VERSION_2_0) {
            if (environments == null)
                environments = new TargetSection(null, TargetMatch.ENVIRONMENT,
                                                 version);
            return new Target(subjects, resources, actions, environments);
        } else {
            return new Target(subjects, resources, actions);
        }
    }

    /**
     * Returns the Subjects section of this Target.
     *
     * @return a <code>TargetSection</code> representing the Subjects
     */
    public TargetSection getSubjectsSection() {
        return subjectsSection;
    }

    /**
     * Returns the Resources section of this Target.
     *
     * @return a <code>TargetSection</code> representing the Resources
     */
    public TargetSection getResourcesSection() {
        return resourcesSection;
    }

    /**
     * Returns the Actions section of this Target.
     *
     * @return a <code>TargetSection</code> representing the Actions
     */
    public TargetSection getActionsSection() {
        return actionsSection;
    }

    /**
     * Returns the Environments section of this Target. Note that if this is
     * an XACML 1.x policy, then the section will always match anything,
     * since XACML 1.x doesn't support matching on the Environment.
     *
     * @return a <code>TargetSection</code> representing the Environments
     */
    public TargetSection getEnvironmentsSection() {
        return environmentsSection;
    }

    /**
     * Returns whether or not this <code>Target</code> matches any request.
     *
     * @return true if this Target matches any request, false otherwise
     */
    public boolean matchesAny() {
        return subjectsSection.matchesAny() && resourcesSection.matchesAny() &&
            actionsSection.matchesAny() && environmentsSection.matchesAny();
    }

    /**
     * Determines whether this <code>Target</code> matches
     * the input request (whether it is applicable). 
     * 
     * @param context the representation of the request
     *
     * @return the result of trying to match the target and the request
     */
    public MatchResult match(EvaluationCtx context) {
        MatchResult result = null;

        // before matching, see if this target matches any request
        if (matchesAny())
            return new MatchResult(MatchResult.MATCH);

        // first, try matching the Subjects section
        result = subjectsSection.match(context);
        if (result.getResult() != MatchResult.MATCH) {
            logger.finer("failed to match Subjects section of Target");
            return result;
        }

        // now try matching the Resources section
        result = resourcesSection.match(context);
        if (result.getResult() != MatchResult.MATCH) {
            logger.finer("failed to match Resources section of Target");
            return result;
        }

        // next, look at the Actions section
        result = actionsSection.match(context);
        if (result.getResult() != MatchResult.MATCH) {
            logger.finer("failed to match Actions section of Target");
            return result;
        }

        // finally, match the Environments section
        result = environmentsSection.match(context);
        if (result.getResult() != MatchResult.MATCH) {
            logger.finer("failed to match Environments section of Target");
            return result;
        }

        // if we got here, then everything matched
        return result;
    }

    /**
     * Encodes this <code>Target</code> into its XML representation and writes
     * this encoding to the given <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>Target</code> into its XML representation and writes
     * this encoding to the given <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();

        // see if this Target matches anything
        boolean matchesAny = (subjectsSection.matchesAny() &&
                              resourcesSection.matchesAny() &&
                              actionsSection.matchesAny() &&
                              environmentsSection.matchesAny());

        if (matchesAny && (xacmlVersion == PolicyMetaData.XACML_VERSION_2_0)) {
            // in 2.0, if all the sections match any request, then the Target
            // element is empty and should be encoded simply as en empty tag
            out.println("<Target/>");
        } else {
            out.println(indent + "<Target>");
            indenter.in();

            subjectsSection.encode(output, indenter);
            resourcesSection.encode(output, indenter);
            actionsSection.encode(output, indenter);
            
            // we should only do this if we're a 2.0 policy
            if (xacmlVersion == PolicyMetaData.XACML_VERSION_2_0)
                environmentsSection.encode(output, indenter);
            
            indenter.out();
            out.println(indent + "</Target>");
        }
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -