
/*
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-2003 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 "removeAttributeNS(namespaceURI,localName)" removes an attribute by 
 *    local name and namespace URI.  If the removed attribute has a
 *    default value it is immediately replaced.  The replacing attribute has the same
 *    namespace URI and local name, as well as the original prefix.
 *    
 *    Retrieve the attribute named "emp:local" from emp:address
 *    node, then remove the "emp:local" 
 *    attribute by invoking the "removeAttributeNS(namespaceURI,localName)" method.
 *    The "emp:local" attribute has a default value defined in the
 *    DTD file, that value should immediately replace the old
 *    value.
* @author NIST
* @author Mary Brady
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElRemAtNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElRemAtNS</a>
* @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=238">http://www.w3.org/Bugs/Public/show_bug.cgi?id=238</a>
*/
public final class removeAttributeNS02 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 removeAttributeNS02(final DOMTestDocumentBuilderFactory factory)  throws org.w3c.domts.DOMTestIncompatibleException {

      org.w3c.domts.DocumentBuilderSetting[] settings = 
          new org.w3c.domts.DocumentBuilderSetting[] {
org.w3c.domts.DocumentBuilderSetting.namespaceAware,
org.w3c.domts.DocumentBuilderSetting.validating
        };
        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 attr;
      String namespaceURI;
      String localName;
      String prefix;
      doc = (Document) load("staffNS", true);
      elementList = doc.getElementsByTagName("emp:address");
      testAddr = elementList.item(0);
      ((Element) /*Node */testAddr).removeAttributeNS("http://www.nist.gov", "local1");
      elementList = doc.getElementsByTagName("emp:address");
      testAddr = elementList.item(0);
      addrAttr = ((Element) /*Node */testAddr).getAttributeNodeNS("http://www.nist.gov", "local1");
      attr = ((Element) /*Node */testAddr).getAttributeNS("http://www.nist.gov", "local1");
      namespaceURI = addrAttr.getNamespaceURI();
      localName = addrAttr.getLocalName();
      prefix = testAddr.getPrefix();
      assertEquals("attr", "FALSE", attr);
      assertEquals("uri", "http://www.nist.gov", namespaceURI);
      assertEquals("lname", "local1", localName);
      assertEquals("prefix", "emp", prefix);
      }
   /**
    *  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/removeAttributeNS02";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(removeAttributeNS02.class, args);
   }
}

