
/*
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 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 importNode method imports a node from another document to this document. 
 *  The returned node has no parent; (parentNode is null). The source node is not 
 *  altered or removed from the original document but a new copy of the source node
 *  is created.
 *  
 *  Using the method importNode with deep=true, retreive the entity refs present in the 
 *  second element node whose tagName is address and import these nodes into another document. 
 *  Verify if the nodes have been imported correctly by checking the nodeNames of the 
 *  imported nodes, since they are imported into a new document which doesnot have thes defined,
 *  the imported nodes should not have any children.
 *  Now import the entityRef nodes into the same document and verify if the nodes have been 
 *  imported correctly by checking the nodeNames of the imported nodes, and by checking the 
 *  value of the replacement text of the imported nodes.
* @author IBM
* @author Neil Delima
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core">http://www.w3.org/TR/DOM-Level-2-Core/core</a>
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode">http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode</a>
*/
public final class documentimportnode21 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 documentimportnode21(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.notExpandEntityReferences
        };
        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;
      DocumentType docTypeNull = null;

      Document docImp;
      DOMImplementation domImpl;
      NodeList addressList;
      NodeList addressChildList;
      Element element;
      EntityReference entRef2;
      EntityReference entRefImp2;
      EntityReference entRef3;
      EntityReference entRefImp3;
      String nodeName2;
      String nodeName3;
      String nodeNameImp2;
      String nodeNameImp3;
      NodeList nodes;
      Node nodeImp3;
      Node nodeImp2;
      String nodeValueImp2;
      String nodeValueImp3;
      doc = (Document) load("staffNS", true);
      domImpl = doc.getImplementation();
      docImp = domImpl.createDocument("http://www.w3.org/DOM/Test", "a:b", docTypeNull);
      addressList = doc.getElementsByTagName("address");
      element = (Element) addressList.item(1);
      addressChildList = element.getChildNodes();
      entRef2 = (EntityReference) addressChildList.item(0);
      entRef3 = (EntityReference) addressChildList.item(2);
      entRefImp2 = (EntityReference) docImp.importNode(entRef2, true);
      entRefImp3 = (EntityReference) docImp.importNode(entRef3, false);
      nodeName2 = entRef2.getNodeName();
      nodeName3 = entRef3.getNodeName();
      nodeNameImp2 = entRefImp2.getNodeName();
      nodeNameImp3 = entRefImp3.getNodeName();
      assertEquals("documentimportnode21_Ent2NodeName", nodeName2, nodeNameImp2);
      assertEquals("documentimportnode21_Ent3NodeName", nodeName3, nodeNameImp3);
      entRefImp2 = (EntityReference) doc.importNode(entRef2, true);
      entRefImp3 = (EntityReference) doc.importNode(entRef3, false);
      nodes = entRefImp2.getChildNodes();
      nodeImp2 = nodes.item(0);
      nodeValueImp2 = nodeImp2.getNodeValue();
      nodes = entRefImp3.getChildNodes();
      nodeImp3 = nodes.item(0);
      nodeValueImp3 = nodeImp3.getNodeValue();
      assertEquals("documentimportnode21_Ent2NodeValue", "1900 Dallas Road", nodeValueImp2);
      assertEquals("documentimportnode21_Ent3Nodevalue", "Texas", nodeValueImp3);
      }
   /**
    *  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/documentimportnode21";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(documentimportnode21.class, args);
   }
}

