1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package test.auctionportal;
  24 
  25 import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE;
  26 import static org.testng.Assert.assertFalse;
  27 import java.io.FileOutputStream;
  28 import java.io.IOException;
  29 import java.nio.file.Files;
  30 import java.nio.file.Path;
  31 import java.nio.file.Paths;
  32 import java.nio.file.StandardCopyOption;
  33 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
  34 import javax.xml.parsers.DocumentBuilder;
  35 import javax.xml.parsers.DocumentBuilderFactory;
  36 import javax.xml.parsers.ParserConfigurationException;
  37 import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold;
  38 import static jaxp.library.JAXPTestUtilities.failCleanup;
  39 import static jaxp.library.JAXPTestUtilities.failUnexpected;
  40 import static org.testng.Assert.assertEquals;
  41 import static org.testng.Assert.assertTrue;
  42 
  43 import org.testng.annotations.Test;
  44 import org.w3c.dom.Attr;
  45 import org.w3c.dom.Document;
  46 import org.w3c.dom.Element;
  47 import org.w3c.dom.NodeList;
  48 import org.w3c.dom.Text;
  49 import org.w3c.dom.bootstrap.DOMImplementationRegistry;
  50 import org.w3c.dom.ls.DOMImplementationLS;
  51 import org.w3c.dom.ls.LSParser;
  52 import org.w3c.dom.ls.LSSerializer;
  53 import org.xml.sax.SAXException;
  54 import static test.auctionportal.HiBidConstants.CLASS_DIR;
  55 import static test.auctionportal.HiBidConstants.GOLDEN_DIR;
  56 import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS;
  57 import static test.auctionportal.HiBidConstants.XML_DIR;
  58 
  59 /**
  60  * This is the user controller class for the Auction portal HiBid.com.
  61  */
  62 public class UserController {
  63     /**
  64      * Checking when creating an XML document using DOM Level 2 validating
  65      * it without having a schema source or a schema location It must throw a
  66      * sax parse exception.
  67      */
  68     @Test
  69     public void testCreateNewUser() {
  70         String resultFile = CLASS_DIR + "accountInfoOut.xml";
  71         try { 
  72             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  73             dbf.setNamespaceAware(true);
  74             dbf.setValidating(true);
  75 
  76             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
  77             MyErrorHandler eh = new MyErrorHandler();
  78             docBuilder.setErrorHandler(eh);
  79 
  80             Document document = docBuilder.newDocument();
  81 
  82             Element account = document.createElementNS(PORTAL_ACCOUNT_NS, "acc:Account");
  83             Attr accountID = document.createAttributeNS(PORTAL_ACCOUNT_NS, "acc:accountID");
  84             account.setAttributeNode(accountID);
  85 
  86             account.appendChild(document.createElement("FirstName"));
  87             account.appendChild(document.createElementNS(PORTAL_ACCOUNT_NS, "acc:LastName"));
  88             account.appendChild(document.createElement("UserID"));
  89 
  90             DOMImplementationLS impl 
  91                     = (DOMImplementationLS) DOMImplementationRegistry
  92                             .newInstance().getDOMImplementation("LS");
  93             LSSerializer writer = impl.createLSSerializer();
  94             LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
  95             FileOutputStream output = new FileOutputStream(resultFile);
  96             MyDOMOutput domOutput = new MyDOMOutput();
  97 
  98             domOutput.setByteStream(output);
  99             writer.write(account, domOutput);
 100             docBuilder.parse(resultFile);
 101 
 102             assertTrue(eh.isAnyError());
 103         } catch (ParserConfigurationException | ClassNotFoundException | 
 104                 InstantiationException | IllegalAccessException 
 105                 | ClassCastException | SAXException | IOException e) {
 106             failUnexpected(e);
 107         }
 108     }
 109 
 110     /**
 111      * Checking conflicting namespaces and use renameNode and normalizeDocument.
 112      * @see <a href="../content/accountInfo.xml">accountInfo.xml</a>
 113      */
 114     @Test
 115     public void testAddUser() {
 116         String resultFile = CLASS_DIR + "accountRole.out";
 117         String xmlFile = XML_DIR + "accountInfo.xml";
 118 
 119         try {
 120             // Copy schema for outputfile
 121             Files.copy(Paths.get(XML_DIR, "accountInfo.xsd"), 
 122                     Paths.get(CLASS_DIR, "accountInfo.xsd"),
 123                     StandardCopyOption.REPLACE_EXISTING);
 124             MyErrorHandler eh = new MyErrorHandler();
 125             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 126 
 127             dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI);
 128             dbf.setNamespaceAware(true);
 129             dbf.setValidating(true);
 130 
 131             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 132             docBuilder.setErrorHandler(eh);
 133 
 134             Document document = docBuilder.parse(xmlFile);
 135             Element sell = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Sell").item(0);
 136             Element role = (Element) sell.getParentNode();
 137 
 138             Element buy = (Element) document.renameNode(sell, PORTAL_ACCOUNT_NS, "acc:Buy");
 139             role.appendChild(buy);
 140 
 141             DOMImplementationLS impl 
 142                     = (DOMImplementationLS) DOMImplementationRegistry
 143                             .newInstance().getDOMImplementation("LS");
 144             LSSerializer writer = impl.createLSSerializer();
 145 
 146             
 147             try(FileOutputStream output = new FileOutputStream(resultFile)) {
 148                 MyDOMOutput mydomoutput = new MyDOMOutput();
 149                 mydomoutput.setByteStream(output);
 150                 writer.write(document, mydomoutput);
 151             }
 152             
 153             docBuilder.parse(resultFile);
 154             assertFalse(eh.isAnyError());
 155         } catch (ParserConfigurationException | SAXException | IOException 
 156                 | ClassNotFoundException | InstantiationException 
 157                 | IllegalAccessException | ClassCastException e) {
 158             failUnexpected(e);
 159         }
 160     }
 161 
 162     /**
 163      * Checking Text content in XML file.
 164      * @see <a href="../content/accountInfo.xml">accountInfo.xml</a>
 165      */
 166     @Test
 167     public void testMoreUserInfo() {
 168         String xmlFile = XML_DIR + "accountInfo.xml";
 169 
 170         try {
 171             System.out.println("Checking additional user info");
 172 
 173             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 174 
 175             dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI);
 176             dbf.setNamespaceAware(true);
 177             dbf.setValidating(true);
 178 
 179             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 180             MyErrorHandler eh = new MyErrorHandler();
 181             docBuilder.setErrorHandler(eh);
 182 
 183             Document document = docBuilder.parse(xmlFile);
 184             Element account = (Element)document
 185                     .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0);
 186             String textContent = account.getTextContent();
 187             assertTrue(textContent.trim().regionMatches(0, "Rachel", 0, 6));
 188             assertEquals(textContent, "RachelGreen744");
 189             
 190             Attr accountID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID");
 191             assertTrue(accountID.getTextContent().trim().equals("1"));
 192 
 193             assertFalse(eh.isAnyError());
 194         } catch (ParserConfigurationException | SAXException | IOException e) {
 195             failUnexpected(e);
 196         }
 197     }
 198 
 199     /**
 200      * This will check if adoptNode works will adoptNode from
 201      * @see <a href="../content/userInfo.xml">userInfo.xml</a>
 202      * @see <a href="../content/accountInfo.xml">accountInfo.xml</a>. This is
 203      * adopting a node from the XML file which is validated by a DTD and
 204      * into an XML file which is validated by the schema This covers Row 5
 205      * for the table 
 206      * http://javaweb.sfbay/~jsuttor/JSR206/jsr-206-html/ch03s05.html. Filed
 207      * bug 4893745 because there was a difference in behavior
 208      */
 209     @Test
 210     public void testCreateUserAccount() {
 211         System.out.println("Creating user account");
 212         String userXmlFile = XML_DIR + "userInfo.xml";
 213         String accountXmlFile = XML_DIR + "accountInfo.xml";
 214 
 215         try {
 216             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 217             dbf.setNamespaceAware(true);
 218             dbf.setValidating(true);
 219 
 220             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 221             MyErrorHandler eh = new MyErrorHandler();
 222             docBuilder.setErrorHandler(eh);
 223 
 224             Document document = docBuilder.parse(userXmlFile);
 225             Element user = (Element) document.getElementsByTagName("FirstName").item(0);
 226             // Set schema after parsing userInfo.xml. Otherwise it will conflict
 227             // with DTD validation.
 228             dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI);
 229             DocumentBuilder docBuilder1 = dbf.newDocumentBuilder();
 230             docBuilder1.setErrorHandler(eh);
 231             Document accDocument = docBuilder1.parse(accountXmlFile);
 232 
 233             Element firstName = (Element) accDocument
 234                     .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0);
 235             Element adoptedAccount = (Element) accDocument.adoptNode(user);
 236 
 237             Element parent = (Element) firstName.getParentNode();
 238             parent.replaceChild(adoptedAccount, firstName);
 239 
 240             DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
 241             DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
 242             LSSerializer writer = impl.createLSSerializer();
 243 
 244             MyDOMOutput mydomoutput = new MyDOMOutput();
 245             mydomoutput.setByteStream(System.out);
 246             
 247             writer.write(document, mydomoutput);
 248             writer.write(accDocument, mydomoutput);
 249 
 250             assertFalse(eh.isAnyError());
 251         } catch (ParserConfigurationException | SAXException | IOException 
 252                 | ClassNotFoundException | InstantiationException 
 253                 | IllegalAccessException | ClassCastException e) {
 254             failUnexpected(e);
 255         }
 256     }
 257 
 258     /**
 259      * Checking for Row 8 from the schema table when setting the schemaSource
 260      * without the schemaLanguage must report an error.
 261      */
 262     @Test(expectedExceptions = IllegalArgumentException.class)
 263     public void testUserError() throws IllegalArgumentException {
 264         System.out.println("Creating an error in user account");
 265 
 266         String xmlFile = XML_DIR + "userInfo.xml";
 267         String schema = "http://java.sun.com/xml/jaxp/properties/schemaSource";
 268         String schemaValue = "http://dummy.com/dummy.xsd";
 269 
 270         try {
 271             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 272             dbf.setNamespaceAware(true);
 273             dbf.setValidating(true);
 274             dbf.setAttribute(schema, schemaValue);
 275 
 276             DocumentBuilder docBuilder = dbf.newDocumentBuilder();
 277             MyErrorHandler eh = new MyErrorHandler();
 278             docBuilder.setErrorHandler(eh);
 279             Document document = docBuilder.parse(xmlFile);
 280             assertFalse(eh.isAnyError());
 281         } catch (ParserConfigurationException | SAXException | IOException e) {
 282             failUnexpected(e);
 283         }
 284     }
 285 
 286     /**
 287      * Checking for namespace normalization.
 288      * @see <a href="../content/screenName.xml">screenName.xml</a> has prefix of
 289      * userName is bound to "http://hibid.com/user" namespace normalization
 290      * will create a namespace of prefix us and attach userEmail.
 291      */
 292     @Test
 293     public void testCheckScreenNameExists() {
 294         String resultFile = CLASS_DIR + "screenName.out";
 295         String xmlFile = XML_DIR + "screenName.xml";
 296         String goldFile = GOLDEN_DIR + "screenNameGold.xml";
 297 
 298         String nsTagName = "http://hibid.com/screenName";
 299         String userNs = "http://hibid.com/user";
 300         
 301         try (FileOutputStream output = new FileOutputStream(resultFile)) {
 302             DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
 303             DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
 304             LSSerializer writer = impl.createLSSerializer();
 305             LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
 306             Document document = builder.parseURI(xmlFile);
 307             NodeList nl = document.getElementsByTagNameNS(nsTagName, "screen-name");
 308             assertEquals(nl.getLength(), 1);
 309             Element screenName = (Element)nl.item(0);
 310             Element userEmail = document.createElementNS(userNs, "userEmail");
 311             assertTrue(userEmail.isDefaultNamespace(userNs));
 312 
 313             Text email = document.createTextNode("myid@hibid.com");
 314             userEmail.appendChild(email);
 315             screenName.appendChild(userEmail);
 316             document.normalizeDocument();
 317 
 318             MyDOMOutput domoutput = new MyDOMOutput();
 319             domoutput.setByteStream(output);
 320             writer.write(document, domoutput);
 321 
 322             assertTrue(compareDocumentWithGold(goldFile, resultFile));
 323         } catch (ClassNotFoundException | InstantiationException 
 324                 | IllegalAccessException | ClassCastException | IOException
 325                 | ParserConfigurationException | SAXException e) {
 326             failUnexpected(e);
 327         } finally {
 328             try {
 329                 Path resultPath = Paths.get(resultFile);
 330                 if (Files.exists(resultPath)) {
 331                     Files.delete(resultPath);
 332                 }
 333             } catch (IOException ex) {
 334                 failCleanup(ex, resultFile);
 335             }
 336         }
 337     }
 338 }