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 * &lt;xs:element name="Attribute" type="xacml-context:AttributeType"/>
054 * &lt;xs:complexType name="AttributeType">
055 *    &lt;xs:sequence>
056 *       &lt;xs:element ref="xacml-context:AttributeValue" 
057 *        maxOccurs="unbounded"/>
058 *    &lt;xs:sequence>
059 *    &lt;xs:attribute name="AttributeId" type="xs:anyURI" use="required"/>
060 *    &lt;xs:attribute name="DataType" type="xs:anyURI" use="required"/>
061 *    &lt;xs:attribute name="Issuer" type="xs:string" use="optional"/>
062 * &lt;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.