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: ResourceImpl.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.xacml.common.XACMLSDKUtils; 032import com.sun.identity.shared.xml.XMLUtils; 033import com.sun.identity.xacml.common.XACMLSDKUtils; 034import com.sun.identity.xacml.common.XACMLConstants; 035import com.sun.identity.xacml.common.XACMLException; 036import com.sun.identity.xacml.context.Attribute; 037import com.sun.identity.xacml.context.ContextFactory; 038import com.sun.identity.xacml.context.Resource; 039import com.sun.identity.xacml.context.ResourceContent; 040import java.util.ArrayList; 041 042import java.util.List; 043import org.w3c.dom.Document; 044import org.w3c.dom.Element; 045import org.w3c.dom.Node; 046import org.w3c.dom.NodeList; 047 048/** 049 * The <code>Resource</code> element specifies information about the 050 * resource to which access is requested by listing a 051 * sequence of <code>Attribute</code> elements associated with the 052 * resource. it may include <code>ResourceContent</code> 053 * <p> 054 * <pre> 055 * <xs:element name="Resource" type="xacml-context:ResourceType"/> 056 * <xs:complexType name="ResourceType"> 057 * <xs:sequence> 058 * <xs:element ref="xacml-context:ResourceContent" minOccurs="0"/> 059 * <xs:element ref="xacml-context:Attribute" minOccurs="0" 060 * maxOccurs="unbounded"/> 061 * <xs:sequence> 062 * <xs:complexType> 063 * </pre> 064 *@supported.all.api 065 */ 066public class ResourceImpl implements Resource { 067 private List attributes; 068 private Element resourceContent; 069 private boolean isMutable = true; 070 071 /** 072 * Default constructor 073 */ 074 public ResourceImpl() { 075 } 076 077 /** 078 * This constructor is used to build <code>Resource</code> object from a 079 * XML string. 080 * 081 * @param xml A <code>java.lang.String</code> representing 082 * a <code>Resource</code> object 083 * @exception XACMLException if it could not process the XML string 084 */ 085 public ResourceImpl(String xml) throws XACMLException { 086 Document document = XMLUtils.toDOMDocument(xml, XACMLSDKUtils.debug); 087 if (document != null) { 088 Element rootElement = document.getDocumentElement(); 089 processElement(rootElement); 090 makeImmutable(); 091 } else { 092 XACMLSDKUtils.debug.error( 093 "SubjectImpl.processElement(): invalid XML input"); 094 throw new XACMLException( 095 XACMLSDKUtils.xacmlResourceBundle.getString( 096 "errorObtainingElement")); 097 } 098 } 099 100 /** 101 * This constructor is used to build <code>resource</code> object from a 102 * block of existing XML that has already been built into a DOM. 103 * 104 * @param element A <code>org.w3c.dom.Element</code> representing 105 * DOM tree for <code>Resource</code> object 106 * @exception XACML2Exception if it could not process the Element 107 */ 108 public ResourceImpl(Element element) throws XACMLException { 109 processElement(element); 110 makeImmutable(); 111 } 112 113 private void processElement(Element element) throws XACMLException { 114 if (element == null) { 115 XACMLSDKUtils.debug.error( 116 "ResourceImpl.processElement(): invalid root element"); 117 throw new XACMLException( 118 XACMLSDKUtils.xacmlResourceBundle.getString( 119 "invalid_element")); 120 } 121 String elemName = element.getLocalName(); 122 if (elemName == null) { 123 XACMLSDKUtils.debug.error( 124 "ResourceImpl.processElement(): local name missing"); 125 throw new XACMLException( 126 XACMLSDKUtils.xacmlResourceBundle.getString( 127 "missing_local_name")); 128 } 129 130 if (!elemName.equals(XACMLConstants.RESOURCE)) { 131 XACMLSDKUtils.debug.error( 132 "ResourceImpl.processElement(): invalid local name " + 133 elemName); 134 throw new XACMLException( 135 XACMLSDKUtils.xacmlResourceBundle.getString( 136 "invalid_local_name")); 137 } 138 139 // starts processing subelements 140 NodeList nodes = element.getChildNodes(); 141 int numOfNodes = nodes.getLength(); 142 if (numOfNodes > 0) { 143 ContextFactory factory = ContextFactory.getInstance(); 144 for (int i=0; i< numOfNodes; i++) { 145 Node child = (Node)nodes.item(i); 146 if (child.getNodeType() == Node.ELEMENT_NODE) { 147 String childName = child.getLocalName(); 148 // The child nodes should be <Attribute> or 149 // <ResourceContent> 150 if (childName.equals(XACMLConstants.ATTRIBUTE)) { 151 if (attributes == null) { 152 attributes = new ArrayList(); 153 } 154 Attribute attribute = factory.getInstance(). 155 createAttribute((Element)child); 156 attributes.add(attribute); 157 } else if (childName.equals( 158 XACMLConstants.RESOURCE_CONTENT)) { 159 resourceContent = (Element)child; 160 } 161 } 162 } 163 } else { 164 /* not a schema violation 165 XACMLSDKUtils.debug.error( 166 "ResourceImpl.processElement(): no attributes or resource " 167 +"content"); 168 throw new XACMLException( 169 XACMLSDKUtils.xacmlResourceBundle.getString( 170 "missing_subelements")); 171 */ 172 } 173 } 174 175 /** 176 * Returns the ResourceConent 177 * 178 * @return the ResourceContent of the Resource 179 */ 180 public Element getResourceContent() { 181 return resourceContent; 182 } 183 184 /** 185 * Sets the ResourceContent of this Resource 186 * 187 * @param resourceContent ResourceContent of this Resource. 188 * ResourceContent is optional, so could be null. 189 * 190 * @exception XACMLException if the object is immutable 191 * An object is considered <code>immutable</code> if <code> 192 * makeImmutable()</code> has been invoked on it. It can 193 * be determined by calling <code>isMutable</code> on the object. 194 */ 195 public void setResourceContent(Element resourceContent) 196 throws XACMLException { 197 if (!isMutable) { 198 throw new XACMLException( 199 XACMLSDKUtils.xacmlResourceBundle.getString( 200 "objectImmutable")); 201 } 202 String elemName = resourceContent.getLocalName(); 203 if (elemName == null 204 || !elemName.equals(XACMLConstants.RESOURCE_CONTENT)) { 205 XACMLSDKUtils.debug.error( 206 "StatusMessageImpl.processElement():" 207 + "local name missing or incorrect"); 208 throw new XACMLException( 209 XACMLSDKUtils.xacmlResourceBundle.getString( 210 "missing_local_name")); 211 } 212 this.resourceContent = resourceContent; 213 } 214 215 /** 216 * Returns zero to many <code>Attribute</code> elements of this object 217 * If no attributes and present, empty <code>List</code> will be returned. 218 * Typically a <code>Resource</code> element will contain an <code> 219 * Attribute</code> with an <code>AttributeId</code> of 220 * "urn:oasis:names:tc:xacml:1.0:resource:resource-id". Each such 221 * <code>Attribute</code> SHALL be an absolute abd fully resolved 222 * representation of the identity of the single resource to which 223 * access is requested. 224 * 225 * @return <code>List</code> containing the <code>Attribute</code> 226 * elements of this object 227 */ 228 public List getAttributes() { 229 return attributes; 230 } 231 232 /** 233 * Sets the <code>Attribute</code> elements of this object 234 * 235 * @param attributes <code>Attribute</code> elements of this object 236 * attributes could be an empty <code>List</code>, if no attributes 237 * are present. 238 * 239 * @exception XACMLException if the object is immutable 240 * An object is considered <code>immutable</code> if <code> 241 * makeImmutable()</code> has been invoked on it. It can 242 * be determined by calling <code>isMutable</code> on the object. 243 */ 244 public void setAttributes(List attributes) throws XACMLException { 245 if (!isMutable) { 246 throw new XACMLException( 247 XACMLSDKUtils.xacmlResourceBundle.getString( 248 "objectImmutable")); 249 } 250 if (attributes != null && !attributes.isEmpty()) { 251 if (this.attributes == null) { 252 this.attributes = new ArrayList(); 253 } 254 this.attributes.addAll(attributes); 255 } 256 } 257 258 /** 259 * Returns a <code>String</code> representation of this object 260 * @param includeNSPrefix Determines whether or not the namespace qualifier 261 * is prepended to the Element when converted 262 * @param declareNS Determines whether or not the namespace is declared 263 * within the Element. 264 * @return a string representation of this object 265 * @exception XACMLException if conversion fails for any reason 266 */ 267 public String toXMLString(boolean includeNSPrefix, boolean declareNS) 268 throws XACMLException 269 { 270 StringBuffer sb = new StringBuffer(2000); 271 StringBuffer NS = new StringBuffer(100); 272 String appendNS = ""; 273 if (declareNS) { 274 NS.append(XACMLConstants.CONTEXT_NS_DECLARATION) 275 .append(XACMLConstants.SPACE); 276 NS.append(XACMLConstants.XSI_NS_URI) 277 .append(XACMLConstants.SPACE) 278 .append(XACMLConstants.CONTEXT_SCHEMA_LOCATION); 279 } 280 if (includeNSPrefix) { 281 appendNS = XACMLConstants.CONTEXT_NS_PREFIX + ":"; 282 } 283 sb.append("<").append(appendNS).append(XACMLConstants.RESOURCE) 284 .append(NS); 285 sb.append(">"); 286 int length = 0; 287 if (attributes != null) { 288 sb.append("\n"); 289 length = attributes.size(); 290 for (int i = 0; i < length; i++) { 291 Attribute attr = (Attribute)attributes.get(i); 292 sb.append(attr.toXMLString(includeNSPrefix, false)); 293 } 294 } 295 if (resourceContent != null) { 296 sb.append("\n"); 297 // ignore trailing ":" 298 if (includeNSPrefix && (resourceContent.getPrefix() == null)) { 299 resourceContent.setPrefix(appendNS.substring(0, appendNS.length()-1)); 300 } 301 if(declareNS) { 302 int index = NS.indexOf("="); 303 String namespaceName = NS.substring(0, index); 304 String namespaceURI = NS.substring(index+1); 305 if (resourceContent.getNamespaceURI() == null) { 306 resourceContent.setAttribute(namespaceName, namespaceURI); 307 // does not seem to work to append namespace TODO 308 } 309 } 310 sb.append(XMLUtils.print(resourceContent)); 311 } 312 sb.append("</").append(appendNS).append(XACMLConstants.RESOURCE); 313 sb.append(">\n"); 314 return sb.toString(); 315 } 316 317 /** 318 * Returns a string representation of this object 319 * 320 * @return a string representation of this object 321 * @exception XACMLException if conversion fails for any reason 322 */ 323 public String toXMLString() throws XACMLException { 324 return toXMLString(true, false); 325 } 326 327 /* 328 * Makes the object immutable 329 */ 330 public void makeImmutable() {// TODO 331 } 332 333 /** 334 * Checks if the object is mutable 335 * 336 * @return <code>true</code> if the object is mutable, 337 * <code>false</code> otherwise 338 */ 339 public boolean isMutable() { 340 return isMutable; 341 } 342}
Copyright © 2010-2017, ForgeRock All Rights Reserved.