001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2007 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: StatusDetailImpl.java,v 1.3 2008/06/25 05:48:13 qcheng Exp $ 026 * 027 */ 028 029package com.sun.identity.xacml.context.impl; 030 031import com.sun.identity.shared.xml.XMLUtils; 032 033import com.sun.identity.xacml.common.XACMLConstants; 034import com.sun.identity.xacml.common.XACMLException; 035import com.sun.identity.xacml.common.XACMLSDKUtils; 036import com.sun.identity.xacml.context.StatusDetail; 037 038import java.util.StringTokenizer; 039 040import org.w3c.dom.Document; 041import org.w3c.dom.Element; 042 043/** 044 * The <code>StatusCode</code> element is a container of 045 * one or more <code>Status</code>s issuded by authorization authority. 046 * @supported.all.api 047 * <p/> 048 * Schema: 049 * <pre> 050 * <xs:element name="StatusDetail" type="xacml-context:StatusDetailType"/> 051 * <xs:complexType name="StatusDetailType"> 052 * <xs:sequence> 053 * <xs:any namespace="##any" processContents="lax" 054 * minOccurs="0" maxOccurs="unbounded"/> 055 * <xs:sequence> 056 * <xs:complexType> 057 * >/pre> 058 */ 059public class StatusDetailImpl implements StatusDetail { 060 061 062 private Element element; 063 private boolean mutable = true; 064 065 /** 066 * Constructs a <code>StatusDetail</code> object 067 */ 068 public StatusDetailImpl() throws XACMLException { 069 String xmlString = "<xacml-context:StatusDetail xmlns:xacml-context=" 070 + "\"urn:oasis:names:tc:xacml:2.0:context:schema:cd:04\"/>"; 071 element = new StatusDetailImpl(xmlString).getElement(); 072 } 073 074 /** 075 * Constructs a <code>StatusDetail</code> object from an XML string 076 * 077 * @param xml string representing a <code>StatusDetail</code> object 078 * @throws SAMLException if the XML string could not be processed 079 */ 080 public StatusDetailImpl(String xml) throws XACMLException { 081 Document document = XMLUtils.toDOMDocument(xml, XACMLSDKUtils.debug); 082 if (document != null) { 083 Element rootElement = document.getDocumentElement(); 084 processElement(rootElement); 085 makeImmutable(); 086 } else { 087 XACMLSDKUtils.debug.error( 088 "StatusDetailImpl.processElement(): invalid XML input"); 089 throw new XACMLException( 090 XACMLSDKUtils.xacmlResourceBundle.getString( 091 "errorObtainingElement")); 092 } 093 } 094 095 /** 096 * Constructs a <code>StatusDetail</code> object from an XML DOM element 097 * 098 * @param element XML DOM element representing a <code>StatusDetail</code> 099 * object 100 * 101 * @throws SAMLException if the DOM element could not be processed 102 */ 103 public StatusDetailImpl(Element element) throws XACMLException { 104 processElement(element); 105 makeImmutable(); 106 } 107 108 public Element getElement() { 109 return element; 110 } 111 112 public void setElement(Element element) throws XACMLException { 113 if (!mutable) { 114 throw new XACMLException( 115 XACMLSDKUtils.xacmlResourceBundle.getString("objectImmutable")); 116 } 117 118 if (element == null) { 119 throw new XACMLException( 120 XACMLSDKUtils.xacmlResourceBundle.getString("null_not_valid")); 121 } 122 123 String elemName = element.getLocalName(); 124 if (elemName == null) { 125 XACMLSDKUtils.debug.error( 126 "StatusMessageImpl.processElement(): local name missing"); 127 throw new XACMLException( 128 XACMLSDKUtils.xacmlResourceBundle.getString( 129 "missing_local_name")); 130 } 131 this.element = element; 132 } 133 134 /** 135 * Returns a string representation 136 * 137 * @return a string representation 138 * @exception XACMLException if conversion fails for any reason 139 */ 140 public String toXMLString() throws XACMLException { 141 return toXMLString(true, false); 142 } 143 144 /** 145 * Returns a string representation 146 * @param includeNSPrefix Determines whether or not the namespace qualifier 147 * is prepended to the Element when converted 148 * @param declareNS Determines whether or not the namespace is declared 149 * within the Element. 150 * @return a string representation 151 * @exception XACMLException if conversion fails for any reason 152 */ 153 public String toXMLString(boolean includeNSPrefix, boolean declareNS) 154 throws XACMLException { 155 String xmlString = null; 156 String nsPrefix = ""; 157 String nsDeclaration = ""; 158 if (includeNSPrefix) { 159 nsPrefix = XACMLConstants.CONTEXT_NS_PREFIX + ":"; 160 } 161 if (declareNS) { 162 nsDeclaration = XACMLConstants.CONTEXT_NS_DECLARATION; 163 } 164 if (element != null) { 165 if (includeNSPrefix && (element.getPrefix() == null)) { 166 element.setPrefix(nsPrefix); 167 } 168 if(declareNS) { 169 StringTokenizer st = new StringTokenizer(nsDeclaration, "="); 170 String nsName = st.nextToken(); 171 String nsUri = st.nextToken(); 172 if (element.getAttribute(nsName) == null) { 173 element.setAttribute(nsName, nsUri); 174 } 175 } 176 xmlString = XMLUtils.print(element) + "\n"; 177 } else { 178 StringBuffer sb = new StringBuffer(2000); 179 sb.append("<").append(nsPrefix) 180 .append(XACMLConstants.STATUS_DETAIL) 181 .append(" ") 182 .append(nsDeclaration) 183 .append(">") 184 .append("</") 185 .append(nsPrefix) 186 .append(XACMLConstants.STATUS_DETAIL) 187 .append(">\n"); 188 xmlString = sb.toString(); 189 } 190 return xmlString; 191 } 192 193 /** 194 * Checks if the object is mutable 195 * 196 * @return <code>true</code> if the object is mutable, 197 * <code>false</code> otherwise 198 */ 199 public boolean isMutable() { 200 return mutable; 201 } 202 203 /** 204 * Makes the object immutable 205 */ 206 public void makeImmutable() { 207 mutable = false; 208 } 209 210 private void processElement(Element element) throws XACMLException { 211 if (element == null) { 212 XACMLSDKUtils.debug.error( 213 "StatusMessageImpl.processElement(): invalid root element"); 214 throw new XACMLException( 215 XACMLSDKUtils.xacmlResourceBundle.getString( 216 "invalid_element")); 217 } 218 String elemName = element.getLocalName(); 219 if (elemName == null) { 220 XACMLSDKUtils.debug.error( 221 "StatusMessageImpl.processElement(): local name missing"); 222 throw new XACMLException( 223 XACMLSDKUtils.xacmlResourceBundle.getString( 224 "missing_local_name")); 225 } 226 227 if (!elemName.equals(XACMLConstants.STATUS_DETAIL)) { 228 XACMLSDKUtils.debug.error( 229 "StatusMessageImpl.processElement(): invalid local name " 230 + elemName); 231 throw new XACMLException( 232 XACMLSDKUtils.xacmlResourceBundle.getString( 233 "invalid_local_name")); 234 } 235 this.element = element; 236 } 237 238}