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: StatusCodeImpl.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.StatusCode; 037 038import java.util.ArrayList; 039import java.util.List; 040 041import org.w3c.dom.Document; 042import org.w3c.dom.Element; 043import org.w3c.dom.Node; 044import org.w3c.dom.NodeList; 045 046/** 047 * The <code>StatusCode</code> element is a container of 048 * one or more <code>StatusCode</code>s issuded by authorization authority. 049 * @supported.all.api 050 * <p/> 051 * <pre> 052 * 053 * Schema: 054 * <xs:element name="StatusCode" type="xacml-context:StatusCodeType"/> 055 * <xs:complexType name="StatusCodeType"> 056 * <xs:sequence> 057 * <xs:element ref="xacml-context:StatusCode" minOccurs="0"/> 058 * <xs:sequence> 059 * <xs:attribute name="Value" type="xs:anyURI" use="required"/> 060 * <xs:complexType> 061 * </pre> 062 */ 063public class StatusCodeImpl implements StatusCode { 064 065 066 String value = null; 067 String minorCodeValue = null; 068 private boolean mutable = true; 069 070 /** 071 * Constructs a <code>StatusCode</code> object 072 */ 073 public StatusCodeImpl() throws XACMLException { 074 } 075 076 /** 077 * Constructs a <code>StatusCode</code> object from an XML string 078 * 079 * @param xml string representing a <code>StatusCode</code> object 080 * @throws SAMLException if the XML string could not be processed 081 */ 082 public StatusCodeImpl(String xml) throws XACMLException { 083 Document document = XMLUtils.toDOMDocument(xml, XACMLSDKUtils.debug); 084 if (document != null) { 085 Element rootElement = document.getDocumentElement(); 086 processElement(rootElement); 087 makeImmutable(); 088 } else { 089 XACMLSDKUtils.debug.error( 090 "StatusCodeImpl.processElement(): invalid XML input"); 091 throw new XACMLException( 092 XACMLSDKUtils.xacmlResourceBundle.getString( 093 "errorObtainingElement")); 094 } 095 } 096 097 /** 098 * Constructs a <code>StatusCode</code> object from an XML DOM element 099 * 100 * @param element XML DOM element representing a <code>StatusCode</code> 101 * object 102 * 103 * @throws SAMLException if the DOM element could not be processed 104 */ 105 public StatusCodeImpl(Element element) throws XACMLException { 106 processElement(element); 107 makeImmutable(); 108 } 109 110 /** 111 * Returns the <code>value</code> of this object 112 * 113 * @return the <code>value</code> of this object 114 */ 115 public String getValue() { 116 return value; 117 } 118 119 /** 120 * Sets the <code>value</code> of this object 121 * 122 * @exception XACMLException if the object is immutable 123 */ 124 public void setValue(String value) throws XACMLException { 125 if (!mutable) { 126 throw new XACMLException( 127 XACMLSDKUtils.xacmlResourceBundle.getString( 128 "objectImmutable")); 129 } 130 131 if (value == null) { 132 throw new XACMLException( 133 XACMLSDKUtils.xacmlResourceBundle.getString("null_not_valid")); 134 } 135 136 if (!XACMLSDKUtils.isValidStatusCode(value)) { 137 throw new XACMLException( 138 XACMLSDKUtils.xacmlResourceBundle.getString("invalid_value")); 139 } 140 this.value = value; 141 } 142 143 /** 144 * Returns the <code>minorCodeValue</code> of this object 145 * 146 * @return the <code>minorCodeValue</code> of this object 147 */ 148 public String getMinorCodeValue() { 149 return minorCodeValue; 150 } 151 152 /** 153 * Sets the <code>minorCodeValue</code> of this object 154 * 155 * @exception XACMLException if the object is immutable 156 */ 157 public void setMinorCodeValue(String minorCodeValue) 158 throws XACMLException { 159 if (!mutable) { 160 throw new XACMLException( 161 XACMLSDKUtils.xacmlResourceBundle.getString("objectImmutable")); 162 } 163 164 if (value == null) { 165 throw new XACMLException( 166 XACMLSDKUtils.xacmlResourceBundle.getString("null_not_valid")); 167 } 168 169 if (!XACMLSDKUtils.isValidMinorStatusCode(value)) { 170 throw new XACMLException( 171 XACMLSDKUtils.xacmlResourceBundle.getString("invalid_value")); 172 } 173 this.minorCodeValue = minorCodeValue; 174 } 175 176 /** 177 * Returns a string representation 178 * 179 * @return a string representation 180 * @exception XACMLException if conversion fails for any reason 181 */ 182 public String toXMLString() throws XACMLException { 183 return toXMLString(true, false); 184 } 185 186 /** 187 * Returns a string representation 188 * @param includeNSPrefix Determines whether or not the namespace qualifier 189 * is prepended to the Element when converted 190 * @param declareNS Determines whether or not the namespace is declared 191 * within the Element. 192 * @return a string representation 193 * @exception XACMLException if conversion fails for any reason 194 */ 195 public String toXMLString(boolean includeNSPrefix, boolean declareNS) 196 throws XACMLException { 197 StringBuffer sb = new StringBuffer(2000); 198 String nsPrefix = ""; 199 String nsDeclaration = ""; 200 if (includeNSPrefix) { 201 nsPrefix = XACMLConstants.CONTEXT_NS_PREFIX + ":"; 202 } 203 if (declareNS) { 204 nsDeclaration = XACMLConstants.CONTEXT_NS_DECLARATION; 205 } 206 sb.append("<").append(nsPrefix) 207 .append(XACMLConstants.STATUS_CODE) 208 .append(" ") 209 .append(nsDeclaration); 210 if (value != null) { 211 sb.append(XACMLConstants.VALUE) 212 .append("=") 213 .append(XACMLSDKUtils.quote(value)); 214 } 215 sb.append(">"); 216 if (minorCodeValue != null) { 217 sb.append("<").append(nsPrefix) 218 .append(XACMLConstants.STATUS_CODE) 219 .append(" ") 220 .append(nsDeclaration) 221 .append(XACMLConstants.VALUE) 222 .append("=") 223 .append(XACMLSDKUtils.quote(minorCodeValue)) 224 .append(">"); 225 sb.append("</").append(nsPrefix) 226 .append(XACMLConstants.STATUS_CODE) 227 .append(">"); 228 } 229 sb.append("</").append(nsPrefix).append(XACMLConstants.STATUS_CODE) 230 .append(">\n"); 231 return sb.toString(); 232 } 233 234 /** 235 * Checks if the object is mutable 236 * 237 * @return <code>true</code> if the object is mutable, 238 * <code>false</code> otherwise 239 */ 240 public boolean isMutable() { 241 return mutable; 242 } 243 244 /** 245 * Makes the object immutable 246 */ 247 public void makeImmutable() { 248 mutable = false; 249 } 250 251 private void processElement(Element element) throws XACMLException { 252 if (element == null) { 253 XACMLSDKUtils.debug.error( 254 "StatusMessageImpl.processElement(): invalid root element"); 255 throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString( 256 "invalid_element")); 257 } 258 String elemName = element.getLocalName(); 259 if (elemName == null) { 260 XACMLSDKUtils.debug.error( 261 "StatusMessageImpl.processElement(): local name missing"); 262 throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString( 263 "missing_local_name")); 264 } 265 266 if (!elemName.equals(XACMLConstants.STATUS_CODE)) { 267 XACMLSDKUtils.debug.error( 268 "StatusMessageImpl.processElement(): invalid local name " 269 + elemName); 270 throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString( 271 "invalid_local_name")); 272 } 273 String attrValue = element.getAttribute(XACMLConstants.VALUE); 274 if ((attrValue == null) || (attrValue.length() == 0)) { 275 XACMLSDKUtils.debug.error( 276 "StatusCodeImpl.processElement(): statuscode missing"); 277 throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString( 278 "missing_status_code")); //i18n 279 } 280 if (!XACMLSDKUtils.isValidStatusMessage(attrValue.trim())) { 281 throw new XACMLException( 282 XACMLSDKUtils.xacmlResourceBundle.getString( 283 "invalid_value")); 284 } else { 285 this.value = attrValue; 286 } 287 //process child StatusCode element 288 NodeList nodes = element.getChildNodes(); 289 int numOfNodes = nodes.getLength(); 290 List childElements = new ArrayList(); 291 int i = 0; 292 while (i < numOfNodes) { 293 Node child = (Node) nodes.item(i); 294 if (child.getNodeType() == Node.ELEMENT_NODE) { 295 childElements.add(child); 296 } 297 i++; 298 } 299 int childCount = childElements.size(); 300 if (childCount > 1) { 301 XACMLSDKUtils.debug.error( 302 "ResultImpl.processElement(): invalid child element count: " 303 + childCount); 304 throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString( 305 "invalid_child_count")); 306 } 307 if (childCount == 1) { 308 Element childElement = (Element)childElements.get(0); 309 elemName = childElement.getLocalName(); 310 if (elemName == null) { 311 XACMLSDKUtils.debug.error( 312 "StatusMessageImpl.processElement(): local name missing"); 313 throw new XACMLException( 314 XACMLSDKUtils.xacmlResourceBundle.getString( 315 "missing_local_name")); 316 } 317 318 if (!elemName.equals(XACMLConstants.STATUS_CODE)) { 319 XACMLSDKUtils.debug.error( 320 "StatusMessageImpl.processElement(): invalid local name " 321 + elemName); 322 throw new XACMLException( 323 XACMLSDKUtils.xacmlResourceBundle.getString( 324 "invalid_local_name")); 325 } 326 attrValue = childElement.getAttribute(XACMLConstants.VALUE); 327 if ((attrValue == null) || (attrValue.length() == 0)) { 328 XACMLSDKUtils.debug.error( 329 "StatusCodeImpl.processElement(): minor statuscode missing"); 330 throw new XACMLException( 331 XACMLSDKUtils.xacmlResourceBundle.getString( 332 "missing_minor_status_code")); 333 } 334 if (!XACMLSDKUtils.isValidStatusMessage(attrValue.trim())) { 335 throw new XACMLException( 336 XACMLSDKUtils.xacmlResourceBundle.getString( 337 "invalid_value")); 338 } else { 339 this.minorCodeValue = attrValue; 340 } 341 } else { 342 } 343 } 344 345}