001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 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: AttributeImpl.java,v 1.4 2008/11/10 22:57:05 veiming Exp $ 026 * 027 */ 028 029package com.sun.identity.xacml.context.impl; 030 031import com.sun.identity.shared.xml.XMLUtils; 032import com.sun.identity.xacml.common.XACMLConstants; 033import com.sun.identity.xacml.common.XACMLException; 034import com.sun.identity.xacml.common.XACMLSDKUtils; 035import com.sun.identity.xacml.context.Attribute; 036 037import java.util.List; 038import java.util.ArrayList; 039import java.net.URI; 040import org.w3c.dom.Document; 041import org.w3c.dom.Element; 042import org.w3c.dom.NamedNodeMap; 043import org.w3c.dom.Node; 044import org.w3c.dom.NodeList; 045 046/** 047 * The <code>Attribute</code> element specifies information about the 048 * action/subject/resource requested in the <code>Request</code> context by 049 * listing a sequence of <code>Attribute</code> elements associated with 050 * the action. 051 * <p> 052 * <pre> 053 * <xs:element name="Attribute" type="xacml-context:AttributeType"/> 054 * <xs:complexType name="AttributeType"> 055 * <xs:sequence> 056 * <xs:element ref="xacml-context:AttributeValue" 057 * maxOccurs="unbounded"/> 058 * <xs:sequence> 059 * <xs:attribute name="AttributeId" type="xs:anyURI" use="required"/> 060 * <xs:attribute name="DataType" type="xs:anyURI" use="required"/> 061 * <xs:attribute name="Issuer" type="xs:string" use="optional"/> 062 * <xs:complexType> 063 * </pre> 064 *@supported.all.api 065 */ 066public class AttributeImpl implements Attribute { 067 068 069 URI id = null; 070 URI type = null; 071 String issuer = null; 072 private List values ; 073 private boolean isMutable = true; 074 075 /** 076 * Default constructor 077 */ 078 public AttributeImpl() { 079 } 080 081 /** 082 * This constructor is used to build <code>Attribute</code> object from a 083 * XML string. 084 * 085 * @param xml A <code>java.lang.String</code> representing 086 * an <code>Attribute</code> object 087 * @exception XACMLException if it could not process the XML string 088 */ 089 public AttributeImpl(String xml) throws XACMLException { 090 Document document = XMLUtils.toDOMDocument(xml, XACMLSDKUtils.debug); 091 if (document != null) { 092 Element rootElement = document.getDocumentElement(); 093 processElement(rootElement); 094 makeImmutable(); 095 } else { 096 XACMLSDKUtils.debug.error( 097 "AttributeImpl.processElement(): invalid XML input"); 098 throw new XACMLException( 099 XACMLSDKUtils.xacmlResourceBundle.getString( 100 "errorObtainingElement")); 101 } 102 } 103 104 /** 105 * This constructor is used to build <code>Request</code> object from a 106 * block of existing XML that has already been built into a DOM. 107 * 108 * @param element A <code>org.w3c.dom.Element</code> representing 109 * DOM tree for <code>Request</code> object 110 * @exception XACML2Exception if it could not process the Element 111 */ 112 public AttributeImpl(Element element) throws XACMLException { 113 processElement(element); 114 makeImmutable(); 115 } 116 117 private void processElement(Element element) throws XACMLException { 118 String value = null; 119 if (element == null) { 120 XACMLSDKUtils.debug.error( 121 "AttributeImpl.processElement(): invalid root element"); 122 throw new XACMLException( 123 XACMLSDKUtils.xacmlResourceBundle.getString( 124 "invalid_element")); 125 } 126 127 // First check that we're really parsing an Attribute 128 if (! element.getLocalName().equals(XACMLConstants.ATTRIBUTE)) { 129 XACMLSDKUtils.debug.error( 130 "AttributeImpl.processElement(): invalid root element"); 131 throw new XACMLException( 132 XACMLSDKUtils.xacmlResourceBundle.getString( 133 "invalid_element")); 134 } 135 NamedNodeMap attrs = element.getAttributes(); 136 137 try { 138 id = new URI(attrs.getNamedItem(XACMLConstants.ATTRIBUTE_ID) 139 .getNodeValue()); 140 } catch (Exception e) { 141 throw new XACMLException( 142 XACMLSDKUtils.xacmlResourceBundle.getString( 143 "attribute_not_uri")); 144 } 145 if (id == null) { 146 throw new XACMLException( 147 XACMLSDKUtils.xacmlResourceBundle.getString( 148 "missing_attribute")); 149 } 150 try { 151 type = new URI(attrs.getNamedItem(XACMLConstants.DATATYPE) 152 .getNodeValue()); 153 } catch (Exception e) { 154 throw new XACMLException( 155 XACMLSDKUtils.xacmlResourceBundle.getString( 156 "attribute_not_uri")); 157 } 158 if (type == null) { 159 throw new XACMLException( 160 XACMLSDKUtils.xacmlResourceBundle.getString( 161 "missing_attribute")); 162 } 163 try { 164 Node issuerNode = attrs.getNamedItem(XACMLConstants.ISSUER); 165 if (issuerNode != null) 166 issuer = issuerNode.getNodeValue(); 167 168 } catch (Exception e) { 169 throw new XACMLException( 170 XACMLSDKUtils.xacmlResourceBundle.getString( 171 "attribute_parsing_error")); 172 } 173 174 // now we get the attribute value 175 NodeList nodes = element.getChildNodes(); 176 for (int i = 0; i < nodes.getLength(); i++) { 177 Node node = nodes.item(i); 178 if ((node.getNodeType() == Node.ELEMENT_NODE) || 179 (node.getNodeType() == Node.ATTRIBUTE_NODE)) { 180 if (node.getLocalName().equals(XACMLConstants.ATTRIBUTE_VALUE)) { 181 if (values == null) { 182 values = new ArrayList(); 183 } 184 values.add(node); 185 } 186 } 187 } 188 189 // make sure we got a value 190 if (values ==null || values.isEmpty()) { 191 throw new XACMLException( 192 XACMLSDKUtils.xacmlResourceBundle.getString( 193 "missing_attribute_value")); 194 } 195 } 196 197 /** 198 * Returns the issuer of the <code>Attribute</code>. 199 * @return <code>String</code> representing the issuer. It MAY be an 200 * x500Name that binds to a public key or some other identification 201 * exchanged out-of-band by participating entities. 202 */ 203 public String getIssuer() { 204 return issuer; 205 } 206 207 /** 208 * Sets the issuer of the <code>Attribute</code>. 209 * @param issuer <code>String</code> representing the issuer. 210 * It MAY be an x500Name that binds to a public key or some other 211 * identification exchanged out-of-band by participating entities. 212 * This is optional so return value could be null or an empty 213 * <code>String</code>. 214 * @exception XACMLException if the object is immutable 215 */ 216 public void setIssuer(String issuer) throws XACMLException { 217 if (!isMutable) { 218 throw new XACMLException( 219 XACMLSDKUtils.xacmlResourceBundle.getString( 220 "objectImmutable")); 221 } 222 this.issuer=issuer; 223 } 224 225 /** 226 * Returns the AttributeId of the <code>Attribute</code> 227 * which the attribute identifier. 228 * @return the <code>URI</code> representing the data type. 229 */ 230 public URI getAttributeId() { 231 return id; 232 } 233 234 /** 235 * Sets the attribiteId of the <code>>Attribute</code> 236 * @param attributeId <code>URI</code> representing the attribite id. 237 * @exception XACMLException if the object is immutable 238 */ 239 public void setAttributeId(URI attributeId) throws XACMLException { 240 if (!isMutable) { 241 throw new XACMLException( 242 XACMLSDKUtils.xacmlResourceBundle.getString( 243 "objectImmutable")); 244 } 245 if (attributeId == null) { 246 throw new XACMLException( 247 XACMLSDKUtils.xacmlResourceBundle.getString( 248 "null_not_valid")); 249 } 250 id = attributeId; 251 } 252 253 /** 254 * Returns the datatype of the contents of the <code>AttributeValue</code> 255 * elements. This will be either a primitive datatype defined by XACML 2.0 256 * specification or a type ( primitive or structured) defined in a 257 * namespace declared in the <xacml-context> element. 258 * @return the <code>URI</code> representing the data type. 259 */ 260 public URI getDataType() { 261 return type; 262 } 263 264 /** 265 * Sets the data type of the contents of the <code>AttributeValue</code> 266 * elements. 267 * @param dataType <code>URI</code> representing the data type. 268 * @exception XACMLException if the object is immutable 269 */ 270 public void setDataType(URI dataType) throws XACMLException { 271 if (!isMutable) { 272 throw new XACMLException( 273 XACMLSDKUtils.xacmlResourceBundle.getString( 274 "objectImmutable")); 275 } 276 if (dataType == null) { 277 throw new XACMLException( 278 XACMLSDKUtils.xacmlResourceBundle.getString( 279 "null_not_valid")); 280 } 281 type = dataType; 282 } 283 284 /** 285 * Returns one to many values in the <code>AttributeValue</code> elements 286 * of this object 287 * 288 * @return the List containing <code>Element</code>s representing the 289 * <code>AttributeValue</code> of this object 290 */ 291 public List getAttributeValues() { 292 return values; 293 } 294 295 /** 296 * Sets the <code>AttributeValue</code> elements of this object 297 * 298 * @param values a <code>List</code> containing Element representing 299 * <code>AttributeValue</code> of this object. 300 * 301 * @exception XACMLException if the object is immutable 302 * An object is considered <code>immutable</code> if <code> 303 * makeImmutable()</code> has been invoked on it. It can 304 * be determined by calling <code>isMutable</code> on the object. 305 */ 306 public void setAttributeValues(List values) throws XACMLException { 307 if (!isMutable) { 308 throw new XACMLException( 309 XACMLSDKUtils.xacmlResourceBundle.getString( 310 "objectImmutable")); 311 } 312 if (this.values == null) { 313 this.values = new ArrayList(); 314 } 315 if (values == null || values.isEmpty()) { 316 throw new XACMLException( 317 XACMLSDKUtils.xacmlResourceBundle.getString( 318 "null_not_valid")); 319 320 } 321 for (int i=0; i < values.size(); i++) { 322 Element value = (Element)values.get(i); 323 String elemName = value.getLocalName(); 324 if (elemName == null 325 || !elemName.equals(XACMLConstants.ATTRIBUTE_VALUE)) { 326 XACMLSDKUtils.debug.error( 327 "StatusMessageImpl.processElement():" 328 + "local name missing or incorrect"); 329 throw new XACMLException( 330 XACMLSDKUtils.xacmlResourceBundle.getString( 331 "missing_local_name")); 332 } 333 this.values.add(value); 334 } 335 } 336 337 /** 338 * Sets the attribute values for this object 339 * 340 * @param stringValues a <code>List</code> containing 341 * <code>String<code> values of this object. 342 * @throws XACMLException if the object is immutable 343 * An object is considered <code>immutable</code> if <code> 344 * makeImmutable()</code> has been invoked on it. It can 345 * be determined by calling <code>isMutable</code> on the object. 346 */ 347 public void setAttributeStringValues(List stringValues) 348 throws XACMLException { 349 if (!isMutable) { 350 throw new XACMLException( 351 XACMLSDKUtils.xacmlResourceBundle.getString( 352 "objectImmutable")); 353 } 354 if (this.values == null) { 355 this.values = new ArrayList(); 356 } 357 if (stringValues == null || stringValues.isEmpty()) { 358 throw new XACMLException( 359 XACMLSDKUtils.xacmlResourceBundle.getString( 360 "null_not_valid")); 361 362 } 363 for (int i=0; i < stringValues.size(); i++) { 364 String value = (String)(stringValues.get(i)); 365 StringBuffer sb = new StringBuffer(200); 366 sb.append("<").append(XACMLConstants.ATTRIBUTE_VALUE) 367 .append(">").append(value) 368 .append("</").append(XACMLConstants.ATTRIBUTE_VALUE) 369 .append(">\n"); 370 Document document = XMLUtils.toDOMDocument(sb.toString(), 371 XACMLSDKUtils.debug); 372 Element element = null; 373 if (document != null) { 374 element = document.getDocumentElement(); 375 } 376 if (element != null) { 377 this.values.add(element); 378 } 379 } 380 } 381 382 /** 383 * Returns a <code>String</code> representation of this object 384 * @param includeNSPrefix Determines whether or not the namespace qualifier 385 * is prepended to the Element when converted 386 * @param declareNS Determines whether or not the namespace is declared 387 * within the Element. 388 * @return a string representation of this object 389 * @exception XACMLException if conversion fails for any reason 390 */ 391 public String toXMLString(boolean includeNSPrefix, boolean declareNS) 392 throws XACMLException 393 { 394 StringBuffer sb = new StringBuffer(2000); 395 StringBuffer NS = new StringBuffer(100); 396 397 //TODO: remove the following 2 lines 398 includeNSPrefix = false; 399 declareNS = false; 400 401 String appendNS = ""; 402 if (declareNS) { 403 NS.append(XACMLConstants.CONTEXT_NS_DECLARATION) 404 .append(XACMLConstants.SPACE); 405 NS.append(XACMLConstants.XSI_NS_URI).append(XACMLConstants.SPACE) 406 .append(XACMLConstants.CONTEXT_SCHEMA_LOCATION); 407 } 408 if (includeNSPrefix) { 409 appendNS = XACMLConstants.CONTEXT_NS_PREFIX + ":"; 410 } 411 sb.append("<").append(appendNS).append(XACMLConstants.ATTRIBUTE) 412 .append(NS); 413 sb.append(XACMLConstants.SPACE); 414 if (id != null) { 415 sb.append(XACMLConstants.ATTRIBUTE_ID).append("=").append("\""). 416 append(id.toString()); 417 sb.append("\"").append(XACMLConstants.SPACE); 418 } 419 if (type != null) { 420 sb.append(XACMLConstants.DATATYPE).append("=").append("\""). 421 append(type.toString()); 422 sb.append("\"").append(XACMLConstants.SPACE); 423 } 424 if (issuer != null) { 425 sb.append(XACMLConstants.ISSUER).append("=").append("\"") 426 .append(issuer). 427 append("\""); 428 } 429 sb.append(">"); 430 int length = 0; 431 String xmlString = null; 432 if (values != null && !values.isEmpty()) { 433 for (int i=0; i < values.size(); i++) { 434 Element value = (Element)values.get(i); 435 sb.append("\n"); 436 // ignore trailing ":" 437 if (includeNSPrefix && (value.getPrefix() == null)) { 438 value.setPrefix(appendNS.substring(0, appendNS.length()-1)); 439 } 440 if(declareNS) { 441 int index = NS.indexOf("="); 442 String namespaceName = NS.substring(0, index); 443 String namespaceURI = NS.substring(index+1); 444 if (value.getNamespaceURI() == null) { 445 value.setAttribute(namespaceName, namespaceURI); 446 // does not seem to work to append namespace TODO 447 } 448 } 449 sb.append(XMLUtils.print(value)); 450 } 451 } else { // values are empty put empty tags 452 // This should not happen, not schema compliant 453 /* 454 sb.append("<").append(appendNS) 455 .append(XACMLConstants.ATTRIBUTE_VALUE); 456 sb.append(NS).append(">").append("\n"); 457 sb.append("</").append(appendNS) 458 .append(XACMLConstants.ATTRIBUTE_VALUE); 459 sb.append(">").append("\n"); 460 */ 461 } 462 sb.append("\n</").append(appendNS).append(XACMLConstants.ATTRIBUTE); 463 sb.append(">\n"); 464 return sb.toString(); 465 } 466 467 468 /** 469 * Returns a string representation of this object 470 * 471 * @return a string representation of this object 472 * @exception XACMLException if conversion fails for any reason 473 */ 474 475 public String toXMLString() throws XACMLException { 476 return toXMLString(true, false); 477 } 478 479 /** 480 * Makes the object immutable 481 */ 482 public void makeImmutable() {//TODO 483 } 484 485 /** 486 * Checks if the object is mutable 487 * 488 * @return <code>true</code> if the object is mutable, 489 * <code>false</code> otherwise 490 */ 491 public boolean isMutable() { 492 return isMutable; 493 } 494 495}
Copyright © 2010-2017, ForgeRock All Rights Reserved.