
/*
This Java source file was generated by test-to-java.xsl
and is a derived work from the source document.
The source document contained the following notice:



Copyright (c) 2001-2004 World Wide Web Consortium, 
(Massachusetts Institute of Technology, Institut National de
Recherche en Informatique et en Automatique, Keio University).  All 
Rights Reserved.  This program is distributed under the W3C's Software
Intellectual Property License.  This program is distributed in the 
hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  

See W3C License http://www.w3.org/Consortium/Legal/ for more details.


*/

package org.w3c.domts.level2.core;

import org.w3c.dom.*;


import org.w3c.domts.DOMTestCase;
import org.w3c.domts.DOMTestDocumentBuilderFactory;



/**
 *     The "setAttributeNS(namespaceURI,qualifiedName,value)" method adds a new attribute.
 *    If an attribute with the same local name and namespace URI is already present
 *    on the element, its prefix is changed to be the prefix part of the "qualifiedName",
 *    and its vale is changed to be the "value" paramter.
 *    null value if no previously existing Attr node with the
 *    same name was replaced.
 *    
 *    Add a new attribute to the "emp:address" element.
 *    Check to see if the new attribute has been successfully added to the document
 *    by getting the attributes value, namespace URI, local Name and prefix.
 *    The prefix will be changed to the prefix part of the "qualifiedName" 
 *    and its value changed to the "value" parameter.    
* @author NIST
* @author Mary Brady
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#">http://www.w3.org/TR/DOM-Level-2-Core/core#</a>
*/
public final class setAttributeNS04 extends DOMTestCase {

   /**
    * Constructor.
    * @param factory document factory, may not be null
    * @throws org.w3c.domts.DOMTestIncompatibleException Thrown if test is not compatible with parser configuration
    */
   public setAttributeNS04(final DOMTestDocumentBuilderFactory factory)  throws org.w3c.domts.DOMTestIncompatibleException {

      org.w3c.domts.DocumentBuilderSetting[] settings = 
          new org.w3c.domts.DocumentBuilderSetting[] {
org.w3c.domts.DocumentBuilderSetting.namespaceAware
        };
        DOMTestDocumentBuilderFactory testFactory = factory.newInstance(settings);
        setFactory(testFactory);

    //
    //   check if loaded documents are supported for content type
    //
    String contentType = getContentType();
    preload(contentType, "staffNS", true);
    }

   /**
    * Runs the test case.
    * @throws Throwable Any uncaught exception causes test to fail
    */
   public void runTest() throws Throwable {
      Document doc;
      NodeList elementList;
      Node testAddr;
      Attr addrAttr;
      String resultAttr;
      String resultNamespaceURI;
      String resultLocalName;
      String resultPrefix;
      doc = (Document) load("staffNS", true);
      elementList = doc.getElementsByTagName("emp:address");
      testAddr = elementList.item(0);
      assertNotNull("empAddrNotNull", testAddr);
      ((Element) /*Node */testAddr).setAttributeNS("http://www.nist.gov", "newprefix:zone", "newValue");
      addrAttr = ((Element) /*Node */testAddr).getAttributeNodeNS("http://www.nist.gov", "zone");
      resultAttr = ((Element) /*Node */testAddr).getAttributeNS("http://www.nist.gov", "zone");
      assertEquals("attrValue", "newValue", resultAttr);
      resultNamespaceURI = addrAttr.getNamespaceURI();
      assertEquals("nsuri", "http://www.nist.gov", resultNamespaceURI);
      resultLocalName = addrAttr.getLocalName();
      assertEquals("lname", "zone", resultLocalName);
      resultPrefix = addrAttr.getPrefix();
      assertEquals("prefix", "newprefix", resultPrefix);
      }
   /**
    *  Gets URI that identifies the test.
    *  @return uri identifier of test
    */
   public String getTargetURI() {
      return "http://www.w3.org/2001/DOM-Test-Suite/level2/core/setAttributeNS04";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(setAttributeNS04.class, args);
   }
}

