/* * @(#)Obligation.java * * Copyright 2003-2004 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.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.sun.xacml.attr.AttributeFactory; import com.sun.xacml.attr.AttributeValue; import com.sun.xacml.ctx.Attribute; import com.sun.xacml.ctx.Result; /** * Represents the ObligationType XML type in XACML. This also stores all the AttriubteAssignmentType * XML types. * * @since 1.0 * @author Seth Proctor * * Adding generic type support by Christian Mueller (geotools) */ public class Obligation { // the obligation id private URI id; // effect to fulfill on, as defined in Result private int fulfillOn; // the attribute assignments private List<Attribute> assignments; /** * Constructor that takes all the data associated with an obligation. The attribute assignment * list contains <code>Attribute</code> objects, but only the fields used by the * AttributeAssignmentType are used. * * @param id * the obligation's id * @param fulfillOn * the effect denoting when to fulfill this obligation * @param assignments * a <code>List</code> of <code>Attribute</code>s */ public Obligation(URI id, int fulfillOn, List<Attribute> assignments) { this.id = id; this.fulfillOn = fulfillOn; this.assignments = Collections.unmodifiableList(new ArrayList<Attribute>(assignments)); } /** * Creates an instance of <code>Obligation</code> based on the DOM root node. * * @param root * the DOM root of the ObligationType XML type * * @return an instance of an obligation * * @throws ParsingException * if the structure isn't valid */ public static Obligation getInstance(Node root) throws ParsingException { URI id; int fulfillOn = -1; List<Attribute> assignments = new ArrayList<Attribute>(); AttributeFactory attrFactory = AttributeFactory.getInstance(); NamedNodeMap attrs = root.getAttributes(); try { id = new URI(attrs.getNamedItem("ObligationId").getNodeValue()); } catch (Exception e) { throw new ParsingException("Error parsing required attriubte " + "ObligationId", e); } String effect = null; try { effect = attrs.getNamedItem("FulfillOn").getNodeValue(); } catch (Exception e) { throw new ParsingException("Error parsing required attriubte " + "FulfillOn", e); } if (effect.equals("Permit")) { fulfillOn = Result.DECISION_PERMIT; } else if (effect.equals("Deny")) { fulfillOn = Result.DECISION_DENY; } else { throw new ParsingException("Invlid Effect type: " + effect); } NodeList nodes = root.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node.getNodeName().equals("AttributeAssignment")) { try { URI attrId = new URI(node.getAttributes().getNamedItem("AttributeId") .getNodeValue()); AttributeValue attrValue = attrFactory.createValue(node); assignments.add(new Attribute(attrId, null, null, attrValue)); } catch (URISyntaxException use) { throw new ParsingException("Error parsing URI", use); } catch (UnknownIdentifierException uie) { throw new ParsingException("Unknown AttributeId", uie); } catch (Exception e) { throw new ParsingException("Error parsing attribute " + "assignments", e); } } } return new Obligation(id, fulfillOn, assignments); } /** * Returns the id of this obligation * * @return the id */ public URI getId() { return id; } /** * Returns effect that will cause this obligation to be included in a response * * @return the fulfillOn effect */ public int getFulfillOn() { return fulfillOn; } /** * Returns the attribute assignment data in this obligation. The <code>List</code> contains * objects of type <code>Attribute</code> with only the correct attribute fields being used. * * @return the assignments */ public List<Attribute> getAssignments() { return assignments; } /** * Encodes this <code>Obligation</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>Obligation</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(); out.println(indent + "<Obligation ObligationId=\"" + id.toString() + "\" FulfillOn=\"" + Result.DECISIONS[fulfillOn] + "\">"); indenter.in(); for (Attribute attr : assignments) { out.println(indenter.makeString() + "<AttributeAssignment AttributeId=\"" + attr.getId().toString() + "\" DataType=\"" + attr.getType().toString() + "\">" + attr.getValue().encode() + "</AttributeAssignment>"); } indenter.out(); out.println(indent + "</Obligation>"); } }