Package nexj.core.rpc.xml

Source Code of nexj.core.rpc.xml.XMLMarshallerTest

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.rpc.xml;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import javax.xml.transform.dom.DOMSource;

import junit.framework.TestCase;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import nexj.core.meta.MetadataValidationException;
import nexj.core.meta.PrivilegeSet;
import nexj.core.meta.Repository;
import nexj.core.persistence.OID;
import nexj.core.persistence.QueryTimeoutException;
import nexj.core.rpc.MarshallerException;
import nexj.core.rpc.MockServer;
import nexj.core.rpc.Request;
import nexj.core.rpc.Response;
import nexj.core.rpc.TransferObject;
import nexj.core.rpc.soap.SOAPFault;
import nexj.core.runtime.InvocationContext;
import nexj.core.runtime.ValidationException;
import nexj.core.scripting.PCodeFunction;
import nexj.core.scripting.PCodeMacro;
import nexj.core.scripting.Pair;
import nexj.core.scripting.Symbol;
import nexj.core.util.Binary;
import nexj.core.util.GenericException;
import nexj.core.util.IOUtil;
import nexj.core.util.LinkedHashTab;
import nexj.core.util.LookupDeque;
import nexj.core.util.URLUtil;
import nexj.core.util.XMLUtil;
import nexj.core.util.XMLUtil.ElementHandler;
import nexj.test.util.TempFileUtil;

public class XMLMarshallerTest extends TestCase
{
   private final static URL SOAP_ENVELOPE_URL =
      XMLMarshallerTest.class.getResource("SOAPEnvelope.xsd"); // hardcoded copy

   private final static URL XML_NAMESPACE_URL =
      XMLMarshallerTest.class.getResource("XMLNamespace.xsd"); // hardcoded copy

   private File m_tmpSOAPXSD;
   private File m_tmpTNSXSD;
   private File m_tmpTNSBasicXSD;
   private Request m_request;
   private Response m_response;
   private Exception m_exception;
   private SOAPFault m_soapFault;
   private XMLMarshaller m_marshaller;
   private XMLUnmarshaller m_unmarshaller;
   private Writer m_writer;
   private LookupDeque m_xsdMap = new LinkedHashTab();
   private LookupDeque m_xsdMapBasic = new LinkedHashTab();

   /**
    * compare string values of valid vs. other without comparing any pointer references
    * and assert their quality
    * @param valid the valid value
    * @param other the other value
    */
   public void assertEqualsPointerless(Object valid, Object other)
   {
      assertEquals((valid == null)
                   ? null : valid.toString().replaceAll("(=[A-Za-z0-9\\.]+@)[a-f0-9]+", "$1"),
                   (other == null)
                   ? null : other.toString().replaceAll("(=[A-Za-z0-9\\.]+@)[a-f0-9]+", "$1"));
   }

   protected Node generateXSD(XSDGenerator gen) throws IOException
   {
      StringWriter xsdOut = new StringWriter();

      gen.setCompatible(false);
      gen.generate(xsdOut, Repository.getMetadata().getMetaclassIterator(), null);

      // extract the schema portion of the generated XML
      Document xsdDoc = XMLUtil.parse(new StringReader(xsdOut.toString()));
      List/*<Node>*/ namespaceList = new ArrayList/*<Node>*/();
      Node xsdNode;

      for (xsdNode = xsdDoc.getFirstChild();
           !XML.XSD_URI.equals(xsdNode.getNamespaceURI()) ||
           !"schema".equals(xsdNode.getLocalName());
           xsdNode = xsdNode.getFirstChild()) // for every ancestor extract its attributes
      {
         NamedNodeMap attr = xsdNode.getAttributes();

         for (int i = 0, nCount = (attr == null) ? 0 : attr.getLength(); i < nCount; ++i)
         {
            if ("http://www.w3.org/2000/xmlns/".equals(attr.item(i).getNamespaceURI()) &&
                !"xmlns".equals(attr.item(i).getLocalName())) // ignore namespace declaration
            {
               namespaceList.add(attr.item(i).cloneNode(false));
            }
         }
      }

      while (!namespaceList.isEmpty()) // add all attributes to XSD schema node
      {
         xsdNode.getAttributes().setNamedItemNS(
            (Node)namespaceList.remove(namespaceList.size() - 1));
      }

      return xsdNode;
   }

   /*
    * @see TestCase#setUp()
    */
   protected void setUp() throws Exception
   {
      InputStream istream = URLUtil.openStream(SOAP_ENVELOPE_URL);
      Document xsdSOAP;

      try
      {
         xsdSOAP = XMLUtil.parse(new InputSource(istream));
      }
      finally
      {
         IOUtil.close(istream);
      }

      Element schema = XMLUtil.findChildElement(xsdSOAP, "xs:schema"); // hardcoded in XSD file

      schema.setAttribute("elementFormDefault", "qualified"); // needed for SOAP->Fault->faultcode

      m_tmpSOAPXSD = TempFileUtil.makeTemporaryFile();
      m_tmpTNSXSD = TempFileUtil.makeTemporaryFile();
      m_tmpTNSBasicXSD = TempFileUtil.makeTemporaryFile();

      XMLUtil.formatXML(
         new DOMSource(xsdSOAP),
         true,
         new OutputStreamWriter(new FileOutputStream(m_tmpSOAPXSD), IOUtil.ENCODING));
      XMLUtil.formatXML(
         new DOMSource(generateXSD(new WSDLGenerator(""))),
         true,
         new OutputStreamWriter(new FileOutputStream(m_tmpTNSXSD), IOUtil.ENCODING));
      XMLUtil.formatXML(
         new DOMSource(generateXSD(new WSDLBasicGenerator(""))),
         true,
         new OutputStreamWriter(new FileOutputStream(m_tmpTNSBasicXSD), IOUtil.ENCODING));

      m_xsdMap.put(XML.NS_URI_TNS, m_tmpTNSXSD.toURL());
      m_xsdMap.put(XML.NS_URI_XML, XML_NAMESPACE_URL);
      m_xsdMap.put(XML.ENV_URI, m_tmpSOAPXSD.toURL());

      m_xsdMapBasic.put(XML.NS_URI_TNS, m_tmpTNSBasicXSD.toURL());
      m_xsdMapBasic.put(XML.NS_URI_XML, XML_NAMESPACE_URL);
      m_xsdMapBasic.put(XML.ENV_URI, m_tmpSOAPXSD.toURL());

      m_request = new Request();

      TransferObject contact = new TransferObject();

      contact.setOID(new OID(new Object[]{"123"}));

      // make sure not to be same as an existing metaclass,
      // otherwise only metaclass fields are valid
      contact.setClassName("Contact-test");

      contact.setEventName("update");
      contact.setVersion((short)12345);
      contact.setValue("firstName", "Java");
      contact.setValue("lastName", "Kava");
      contact.setValue("null", null);
      contact.setValue("self", contact);
      contact.setValue("integer", new Integer(1));
      contact.setValue("long", new Long(2));
      contact.setValue("float", new Float(0.625f));
      contact.setValue("double", new Double(1.625));
      contact.setValue("decimal", new BigDecimal("1.2345"));
      contact.setValue("timestamp", new Timestamp(12345));
      contact.setValue("boolean", Boolean.TRUE);
      contact.setValue("binary", new Binary(new byte[]{1, 2, 3, 4, 5}));
      contact.setValue("binary2", new Binary(new byte[]{1, 2, 3, 4, 5, 6, 7}));
      contact.setValue("binary3", new Binary(new byte[]{1, 2}));
      contact.setValue("symbol", Symbol.define("sym"));
      contact.setValue("pair", new Pair("A", new Pair("B")));
      contact.setValue("cvector", new char[]{'a', 'b', 'c'});
      contact.setValue("bvector", new byte[]{0, (byte)0xAB, 0x12});
      contact.setValue("svector", new String[]{"a", "b", "c"});
      contact.setValue("vector", new Object[]{"a", "b", "c"});
      contact.setValue("function", new PCodeFunction(new char[]{0, 1, 2}, new Object[]{"abc"}));
      contact.setValue("macro", new PCodeMacro(new char[]{3, 4, 5}, new Object[]{"cde"}, null));

      PrivilegeSet privilegeSet = Repository.getMetadata().createPrivilegeSet();

      privilegeSet.add(Repository.getMetadata().getPrimitivePrivilege("updateContact"));
      privilegeSet.add(Repository.getMetadata().getPrimitivePrivilege("WorkflowManage"));
      contact.setValue("privilegeSet", privilegeSet);

      ArrayList addressList = new ArrayList();
     
      TransferObject address = new TransferObject();
      address.setOID(new OID(new Object[]{"456"}));

      // make sure not to be same as an existing metaclass,
      // otherwise only metaclass fields are valid
      address.setClassName("Address-test");

      address.setEventName("update");
      address.setValue("country", "Canada");
      address.setValue("self", address);
      address.setValue("contact", contact);
      address.setValue("symbol", Symbol.define("sym"));
      addressList.add(address);
     
      address = new TransferObject();
      address.setOID(new OID(new Object[]{"789"}));

      // make sure not to be same as an existing metaclass,
      // otherwise only metaclass fields are valid
      address.setClassName("Address-test");

      address.setEventName("new");
      address.setValue("country", "USA");
      address.setValue("contact", contact);
      addressList.add(address);
     
      contact.setValue("addresses", addressList);

      m_request.setNamespace("http://www.nexjsystems.com/ns/test");
      m_request.setVersion("10");
      m_request.setAsync(true);
      m_request.setCommit(true);
      m_request.setCorrelator(address);
      m_request.setLocale(new Locale("bg", "BG", "SF"));
      m_request.setTimeZone(TimeZone.getTimeZone("AST"));
      m_request.addInvocation(contact);
      m_request.addInvocation(contact, Pair.list("a", "b"));
      m_request.addInvocation(contact,
                       new Object[]{ new Integer(42),
                                     new Double(Math.PI),
                                     new String("Hello World!") },
                       Pair.list("c", "d"));
      m_request.addInvocation(
         contact, "invokeEv", new Object[]{new Long(-1), new Double(Math.E)}, Pair.list("e", "f"));
      m_request.addFilter(contact);

      m_response = new Response();
      m_response.addResult(contact);
      m_response.addResult(address);

      ArrayList eventList = new ArrayList();

      eventList.add(address);
      eventList.add(address);

      m_response.addEvent(eventList);
     
      ValidationException e = new ValidationException("err.validation.requiredAttributes",
                                                      new Object[]{"Contact"});

      e.addException(new MetadataValidationException("err.meta.x", new Object[]{"a", "b"}));
      e.addException(new QueryTimeoutException());
      e.setClassName("Contact");
      e.setOIDHolder(contact);
      e.setOrdinal(1);
      e.addException("firstName",
                     new ValidationException("err.validation.requiredAttribute",
                                             new Object[]{"firstName", "Contact"}));

      m_exception = e;

      m_soapFault = new SOAPFault(m_exception);

      m_marshaller = new XMLMarshaller(new InvocationContext(Repository.getMetadata()),
                                       Repository.getMetadata());
      m_unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()),
                                           Repository.getMetadata());
     
      m_writer = new StringWriter();
   }

   /**
    * @see junit.framework.TestCase#tearDown()
    */
   protected void tearDown() throws Exception
   {
      m_tmpSOAPXSD.delete();
      m_tmpTNSXSD.delete();
      m_tmpTNSBasicXSD.delete();

      super.tearDown();

      m_request = null;
      m_response = null;
      m_exception = null;
      m_soapFault = null;
      m_marshaller = null;
      m_unmarshaller = null;
      m_writer = null;
      m_xsdMap = null;
      m_xsdMapBasic = null;
   }

   public void testSerializeRequest() throws IOException
   {
      m_marshaller.serialize(m_request, m_writer);
      XMLUtil.parse(new StringReader(m_writer.toString()), m_xsdMap); // validate to XSD

      StringReader reader = new StringReader(m_writer.toString());
      Request req = (Request)m_unmarshaller.deserialize(reader);

      assertEquals("http://www.nexjsystems.com/ns/test", req.getNamespace());
      assertEquals("10", req.getVersion());
      assertEquals(true, req.isAsync());
      assertEquals(true, req.isCommit());
      assertEquals("bg_BG_SF", req.getLocale().toString());
      assertEquals("AST", req.getTimeZone().getID());
      assertEquals(4, req.getInvocationCount());
      assertEquals(1, req.getFilterCount());

      TransferObject contact = req.getObject(0);

      // remove all pointer references,
      // objects are going to be different due to being unmarshalled from different branches of the
      // XML tree (i.e. first argument and first filter blocks)
      assertEqualsPointerless(contact, req.getFilter(0));

      // remove all pointer references,
      // objects are going to be different due to being unmarshalled from different branches of the
      // XML tree (i.e. first argument and first filter blocks)
      assertEqualsPointerless(contact, req.getObject(1));

      Request.Invocation action = req.getInvocation(0);

      assertTrue(contact == action.getObject());
      assertNull(action.getEventName());
      assertNull(action.getAttributes());

      Pair pair = req.getInvocation(1).getAttributes();

      assertEquals("a", pair.getHead());
      assertEquals("b", pair.getNext().getHead());
      assertNull(pair.getNext().getNext());
     
      Object[] params = req.getInvocation(2).getArguments();
      assertEquals(3, params.length);
      assertTrue(params[0] instanceof Integer);
      assertEquals(42, ((Integer)params[0]).intValue());
      assertTrue(params[1] instanceof Double);
      assertEquals(Math.PI, ((Double)params[1]).doubleValue(), 0);
      assertTrue(params[2] instanceof String);
      assertEquals("Hello World!", params[2]);

      action = req.getInvocation(3);
      assertEquals("invokeEv", action.getEventName());
      assertEquals("update", action.getObject().getEventName());
      params = action.getArguments();
      assertEquals(2, params.length);
      assertTrue(params[0] instanceof Long);
      assertEquals(-1, ((Long)params[0]).intValue());
      assertTrue(params[1] instanceof Double);
      assertEquals(Math.E, ((Double)params[1]).doubleValue(), 0);
      pair = action.getAttributes();
      assertEquals("e", pair.getHead());
      assertEquals("f", pair.getNext().getHead());
      assertNull(pair.getNext().getNext());

      OID oid = contact.getOID();

      assertEquals(1, oid.getCount());
      assertEquals("123", oid.getValue(0));

      assertEquals("Contact-test", contact.getClassName());
      assertEquals("update", contact.getEventName());
      assertEquals(12345, contact.getVersion());
      assertEquals(24, contact.getValueCount());
      assertEquals("Java", contact.getValue("firstName"));
      assertEquals("Kava", contact.getValue("lastName"));
      assertNull(contact.getValue("null"));
      assertSame(contact, contact.getValue("self"));
      assertEquals(new Integer(1), contact.getValue("integer"));
      assertEquals(new Long(2), contact.getValue("long"));
      assertEquals(new Float(0.625f), contact.getValue("float"));
      assertEquals(new Double(1.625), contact.getValue("double"));
      assertEquals(new BigDecimal("1.2345"), contact.getValue("decimal"));
      assertEquals(new Timestamp(12345), contact.getValue("timestamp"));
      assertEquals(Boolean.TRUE, contact.getValue("boolean"));
      assertEquals(new Binary(new byte[]{1, 2, 3, 4, 5}), contact.getValue("binary"));
      assertEquals(new Binary(new byte[]{1, 2, 3, 4, 5, 6, 7}), contact.getValue("binary2"));
      assertEquals(new Binary(new byte[]{1, 2}), contact.getValue("binary3"));
      assertEquals("sym", ((Symbol)contact.getValue("symbol")).getName());
      assertSame(Symbol.define("sym"), contact.getValue("symbol"));
     
      Pair pairA = (Pair)contact.getValue("pair");
      assertEquals("A", pairA.getHead());
     
      Pair pairB = pairA.getNext();
      assertEquals("B", pairB.getHead());
      assertNull(pairB.getTail());

      char[] cvec = (char[])contact.getValue("cvector");

      assertEquals(3, cvec.length);
      assertEquals('a', cvec[0]);
      assertEquals('b', cvec[1]);
      assertEquals('c', cvec[2]);

      byte[] bvec = (byte[])contact.getValue("bvector");

      assertEquals(3, bvec.length);
      assertEquals(0, bvec[0]);
      assertEquals((byte)0xAB, bvec[1]);
      assertEquals(0x12, bvec[2]);

      String[] svec = (String[])contact.getValue("svector");

      assertEquals(3, svec.length);
      assertEquals("a", svec[0]);
      assertEquals("b", svec[1]);
      assertEquals("c", svec[2]);

      // XMLMarshaller is hardcoded to marshal Object[] as List for compatibility with MS.NET
      List vec = (List)contact.getValue("vector");

      assertEquals(3, vec.size());
      assertEquals("a", vec.get(0));
      assertEquals("b", vec.get(1));
      assertEquals("c", vec.get(2));

      PCodeFunction fun = (PCodeFunction)contact.getValue("function");

      assertEquals(3, fun.code.length);
      assertEquals(0, fun.code[0]);
      assertEquals(1, fun.code[1]);
      assertEquals(2, fun.code[2]);
      assertEquals(1, fun.constants.length);
      assertEquals("abc", fun.constants[0]);
     
      PCodeMacro mac = (PCodeMacro)contact.getValue("macro");
     
      assertEquals(3, mac.code.length);
      assertEquals(3, mac.code[0]);
      assertEquals(4, mac.code[1]);
      assertEquals(5, mac.code[2]);
      assertEquals(1, mac.constants.length);
      assertEquals("cde", mac.constants[0]);

      PrivilegeSet privilegeSet = (PrivilegeSet)contact.getValue("privilegeSet");

      assertTrue(privilegeSet.contains(Repository
                                          .getMetadata()
                                             .getPrimitivePrivilege("updateContact")));
      assertTrue(privilegeSet.contains(Repository
                                          .getMetadata()
                                             .getPrimitivePrivilege("WorkflowManage")));
      assertFalse(privilegeSet.contains(Repository
                                           .getMetadata()
                                              .getPrimitivePrivilege("createContact")));

      List addressList = (List)contact.getValue("addresses");

      assertEquals(2, addressList.size());

      TransferObject addr1 = (TransferObject)addressList.get(0);

      oid = addr1.getOID();

      assertEquals(1, oid.getCount());
      assertEquals("456", oid.getValue(0));

      assertEquals("Address-test", addr1.getClassName());
      assertEquals("update", addr1.getEventName());
      assertEquals(0, addr1.getVersion());
      assertEquals("Canada", addr1.getValue("country"));
      assertSame(addr1, addr1.getValue("self"));
      assertSame(contact, addr1.getValue("contact"));
      assertSame(contact.getValue("symbol"), addr1.getValue("symbol"));

      TransferObject addr2 = (TransferObject)addressList.get(1);

      assertEquals(2, addr2.getValueCount());
      assertEquals("USA", addr2.getValue("country"));
      assertSame(contact, addr2.getValue("contact"));
     
      // remove all pointer references,
      // objects are going to be different due to being unmarshalled from different branches of the
      // XML tree (i.e. correlator and first argument blocks)
      assertEqualsPointerless(req.getCorrelator(), addr2);
   }
  
   public void testSerializeResponse() throws IOException
   {
      m_marshaller.serialize(m_response, m_writer);
      XMLUtil.parse(new StringReader(m_writer.toString()), m_xsdMap); // validate to XSD

      StringReader reader = new StringReader(m_writer.toString());
      Response resp = (Response)m_unmarshaller.deserialize(reader);

      assertEquals(2, resp.getResultCount());

      // remove all pointer references,
      // objects are going to be different due to being unmarshalled from different branches of the
      // XML tree (i.e. first argument and second argument blocks)
      // XMLMarshaller is hardcoded to marshal List as Object[] for compatibility with MS.NET
      assertEqualsPointerless(
         ((List)((TransferObject)resp.getResult(0)).getValue("addresses")).get(1),
         resp.getResult(1));

      assertEquals(1, resp.getEventCount());
      List eventList = (List)resp.getEvent(0);

      // remove all pointer references,
      // objects are going to be different due to being unmarshalled from different branches of the
      // XML tree (i.e. first event and second event blocks)
      assertEqualsPointerless(eventList.get(0), eventList.get(1));
   }
  
   public void testSerializeException() throws IOException
   {
      m_marshaller.serialize(m_exception, m_writer);
      XMLUtil.parse(new StringReader(m_writer.toString()), m_xsdMap); // validate to XSD

      StringReader reader = new StringReader(m_writer.toString());
      Throwable t = (Throwable)m_unmarshaller.deserialize(reader);
     
      assertTrue(t instanceof ValidationException);
     
      ValidationException e = (ValidationException)t;

      assertEquals("err.validation.requiredAttributes", e.getErrorCode());
      assertEquals(1, e.getErrorArgs().length);
      assertEquals("Contact", e.getClassName());
      assertEquals("123", e.getOIDHolder().getOID().getValue(0));
      assertEquals(1, e.getOrdinal());
      assertEquals(1, e.getExceptionCount());
      assertEquals("err.persistence.queryTimeout",
                   ((GenericException)e.getExceptionIterator().next()).getErrorCode());
      assertEquals("err.validation.requiredAttribute",
                   ((GenericException)e.findException("firstName")).getErrorCode());
   }

   public void testSerializeSOAPFault() throws IOException
   {
      m_marshaller.serialize(m_soapFault, m_writer);
      XMLUtil.parse(new StringReader(m_writer.toString()), m_xsdMap); // validate to XSD

      StringReader reader = new StringReader(m_writer.toString());
      SOAPFault fault = (SOAPFault)m_unmarshaller.deserialize(reader);

      assertEquals("http://schemas.xmlsoap.org/soap/envelope/", fault.getURI());
      assertEquals("Server.nexj.core.runtime.ValidationException", fault.getCode());
      assertEquals("err.validation.requiredAttributes(\"Contact\")", fault.getMessage());
      assertEquals("err.validation.requiredAttributes",
                   ((ValidationException)fault.getException()).getErrorCode());
   }

   public void testSerializeTransferObject() throws IOException
   {
      Request request = new Request();
      TransferObject tobj = new TransferObject();
      List/*<String>*/ list = new ArrayList/*<String>*/(3);

      list.add("name1");
      list.add("name2");
      list.add("name3");
      tobj.setClassName("User");
      tobj.setValue("firstName", "fName");
      tobj.setValue("names", list);
      request.setVersion("0");
      request.addInvocation(tobj);
      m_marshaller.serialize(request, m_writer);
      XMLUtil.parse(new StringReader(m_writer.toString()), m_xsdMap); // validate to XSD

      request = (Request)m_unmarshaller.deserialize(new StringReader(m_writer.toString()));

      TransferObject processed = request.getObject(0);

      assertEquals(tobj.getClassName(), processed.getClassName());
      assertEquals(tobj.getValueCount(), processed.getValueCount());
      assertEquals(tobj.getValue("firstName"), processed.getValue("firstName"));

      Object names = processed.getValue("names");

      assertTrue(names instanceof List);
      assertEquals(list.size(), ((List)names).size());
      assertEquals(list.get(0), ((List)names).get(0));
      assertEquals(list.get(1), ((List)names).get(1));
      assertEquals(list.get(2), ((List)names).get(2));
   }

   public void testBasicResponse() throws IOException
   {
      StringWriter writer = new StringWriter();
      XMLUnmarshaller unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()));
      Response response = new Response();
      TransferObject tobj = new TransferObject("User");

      tobj.setValue("e", new Double(2.71828183));
      tobj.setValue("privilegeSet", new Integer(42));
      tobj.setValue("name", "Name");
      response.addResult(tobj);

      writer.getBuffer().setLength(0);
      XMLChangeRequest request = (XMLChangeRequest)unmarshaller.deserialize(
         new StringReader("<Change-Request xmlns=\"" + XML.NS_URI_TNS
         + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><objects xsi:type=\"User\"><"
         + XML.BASE_PREFIX + "oid>10e8359492f25f4be49109b9979e684ff3</" + XML.BASE_PREFIX
         + "oid><" + XML.BASE_PREFIX + "event>welcome</" + XML.BASE_PREFIX
         + "event><name>fullname</name></objects><attributes>(e privilegeSet name)</attributes></Change-Request>"));

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMap); // validate to XSD

      Node root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Change-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertEquals(1, root.getChildNodes().item(0).getAttributes().getLength());
      assertEquals("User",
                   root
                      .getChildNodes()
                         .item(0)
                            .getAttributes()
                               .getNamedItem(XML.XSI_NS + ":type")
                                  .getNodeValue());
      assertEquals(6, root.getChildNodes().item(0).getChildNodes().getLength());

      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));
      assertEquals("e",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "keys")
                         .getTextContent());
      assertEquals(XML.XSD_NS + ":double",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getAttributes()
                            .getNamedItem(XML.XSI_NS + ":type")
                               .getNodeValue());
      assertEquals("2.71828183",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getTextContent());
      assertEquals(XML.XSD_NS + ":int",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0), "privilegeSet")
                         .getAttributes()
                            .getNamedItem(XML.XSI_NS + ":type")
                               .getNodeValue());
      assertEquals("42",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0), "privilegeSet")
                         .getTextContent());
      assertEquals("Name",
                   XMLUtil.findChildElement(root.getChildNodes().item(0), "name").getTextContent());

      writer.getBuffer().setLength(0);
      request = (XMLChangeRequest)unmarshaller.deserialize(new StringReader("<User-Change-Request xmlns=\"" + XML.NS_URI_TNS
         + "\"><objects><" + XML.BASE_PREFIX + "oid>10e8359492f25f4be49109b9979e684ff3</"
         + XML.BASE_PREFIX + "oid><" + XML.BASE_PREFIX + "event>welcome</"
         + XML.BASE_PREFIX + "event><name>fullname</name></objects><attributes>(e privilegeSet name)</attributes></User-Change-Request>"));
      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMapBasic); // validate to XSD
      root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "User-Change-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertFalse(root.getChildNodes().item(0).hasAttributes());
      assertEquals(6, root.getChildNodes().item(0).getChildNodes().getLength());

      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));
      assertEquals("e",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "keys")
                         .getTextContent());
      assertEquals(XML.XSD_NS + ":string",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getAttributes()
                            .getNamedItem(XML.XSI_NS + ":type")
                               .getNodeValue());
      assertEquals("2.71828183",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getTextContent());
      assertNull(XMLUtil
                    .findChildElement(root.getChildNodes().item(0), "privilegeSet")
                       .getAttributes()
                          .getNamedItem(XML.XSI_NS + ":type"));
      assertEquals("42",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0), "privilegeSet")
                         .getTextContent());
      assertEquals("Name",
                   XMLUtil.findChildElement(root.getChildNodes().item(0), "name").getTextContent());
   }

   public void testDynamicChangeResponse() throws MarshallerException, IOException
   {
      StringWriter writer = new StringWriter();
      XMLUnmarshaller unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()));
      StringReader reader = new StringReader("<Change-Request xmlns=\"" + XML.NS_URI_TNS
         + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><objects x" + "si:type=\"Principal\"><"
         + XML.BASE_PREFIX + "oid>10e8359492f25f4be49109b9979e684ff3</" + XML.BASE_PREFIX
         + "oid><" + XML.BASE_PREFIX + "event>welcome</" + XML.BASE_PREFIX
         + "event><name>fullname</name></objects><attributes>(firstName name)</attributes></Change-Request>");
      Response response = new Response();
      TransferObject tobj = new TransferObject("User");

      tobj.setValue("firstName", "FName");
      tobj.setValue("name", "fullName");
      response.addResult(tobj);
      XMLChangeRequest request = (XMLChangeRequest)unmarshaller.deserialize(reader);

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMap); // validate to XSD

      Node root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Change-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertEquals(1, root.getChildNodes().item(0).getAttributes().getLength());
      assertEquals("User",
                   root
                      .getChildNodes()
                         .item(0)
                            .getAttributes()
                               .getNamedItem(XML.XSI_NS + ":type")
                                  .getNodeValue());
      assertEquals(5, root.getChildNodes().item(0).getChildNodes().getLength());

      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));

      // this is not an attribute of 'User' hence it goes into _keys/_values
      assertEquals("firstName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "keys")
                         .getTextContent());

      // this is not an attribute of 'User' hence it goes into _keys/_values
      assertEquals("FName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getTextContent());

      assertEquals("fullName",
                   XMLUtil.findChildElement(root.getChildNodes().item(0), "name").getTextContent());
   }

   public void testDynamicReadResponse() throws MarshallerException, IOException
   {
      StringWriter writer = new StringWriter();
      XMLUnmarshaller unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()));
      StringReader reader = new StringReader("<Read-Request xmlns=\"" + XML.NS_URI_TNS + "\"><class>Principal</class>"
         + "<attributes>(fullName name)</attributes><where></where><orderBy></orderBy><count>8</count>"
         + "<offset>0</offset></Read-Request>");
      Response response = new Response();
      TransferObject tobj = new TransferObject("User");

      tobj.setValue("fullName", "FName");
      tobj.setValue("name", null);
      response.addResult(Arrays.asList(new Object[]{tobj}));
      XMLReadRequest request = (XMLReadRequest)unmarshaller.deserialize(reader);

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMap); // validate to XSD

      Node root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Read-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertEquals(1, root.getChildNodes().item(0).getAttributes().getLength());
      assertEquals("User",
                   root
                      .getChildNodes()
                         .item(0)
                            .getAttributes()
                               .getNamedItem(XML.XSI_NS + ":type")
                                  .getNodeValue());
      assertEquals(5, root.getChildNodes().item(0).getChildNodes().getLength());

      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));
      assertEquals("FName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0), "fullName")
                         .getTextContent());
      assertEquals("name",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "keys")
                         .getTextContent());
      assertEquals("true",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getAttributes()
                            .getNamedItem(XML.XSI_NS + ":nil")
                               .getNodeValue());
   }

   public void testDynamicRestrictedChangeResponse() throws MarshallerException, IOException
   {
      StringWriter writer = new StringWriter();
      XMLUnmarshaller unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()));
      StringReader reader = new StringReader("<Principal-Change-Request xmlns=\"" + XML.NS_URI_TNS + "\"><objects><"
         + XML.BASE_PREFIX + "oid>10e8359492f25f4be49109b9979e684ff3</" + XML.BASE_PREFIX
         + "oid><" + XML.BASE_PREFIX + "event>welcome</" + XML.BASE_PREFIX
         + "event><name>fullname</name></objects><attributes>(fullName name)</attributes></Principal-Change-Request>");
      Response response = new Response();
      TransferObject tobj = new TransferObject("User");

      tobj.setValue("fullName", "FName");
      tobj.setValue("name", "Name");
      response.addResult(tobj);
      XMLChangeRequest request = (XMLChangeRequest)unmarshaller.deserialize(reader);

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMapBasic); // validate to XSD

      Node root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Principal-Change-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertFalse(root.getChildNodes().item(0).hasAttributes());
      assertEquals(6, root.getChildNodes().item(0).getChildNodes().getLength());

      assertEquals("User",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "class")
                         .getTextContent());
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));
      assertEquals("fullName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "keys")
                         .getTextContent());
      assertEquals("FName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getTextContent());
      assertEquals("Name",
                   XMLUtil.findChildElement(root.getChildNodes().item(0), "name").getTextContent());
   }

   public void testDynamicRestrictedReadResponse() throws MarshallerException, IOException
   {
      StringWriter writer = new StringWriter();
      XMLUnmarshaller unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()));
      StringReader reader = new StringReader("<Principal-Read-Request xmlns=\"" + XML.NS_URI_TNS
         + "\"><class>User-test</class>"
         + "<attributes>(fullName)</attributes><where></where><orderBy></orderBy><count>8</count>"
         + "<offset>0</offset></Principal-Read-Request>");
      Response response = new Response();
      TransferObject tobj = new TransferObject("User");
     
      tobj.setValue("fullName", "FName");
      tobj.setValue("name", "Name");
      response.addResult(Arrays.asList(new Object[]{tobj}));
      XMLReadRequest request = (XMLReadRequest)unmarshaller.deserialize(reader);

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMapBasic); // validate to XSD

      Node root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Principal-Read-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertFalse(root.getChildNodes().item(0).hasAttributes());
      assertEquals(6, root.getChildNodes().item(0).getChildNodes().getLength());

      assertEquals("User",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "class")
                         .getTextContent());
      assertNotNull(XMLUtil
                       .findChildElement(root.getChildNodes().item(0),
                                         XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil
                       .findChildElement(root.getChildNodes().item(0),
                                         XML.BASE_PREFIX + "version"));
      assertEquals("fullName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "keys")
                          .getTextContent());
      assertEquals("FName",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0),
                                        XML.BASE_PREFIX + "values")
                         .getTextContent());
      assertEquals("Name",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0), "name")
                         .getTextContent());
   }

   public void testNestedMetaclassPolymorphism() throws MarshallerException, IOException
   {
      StringWriter writer = new StringWriter();
      XMLUnmarshaller unmarshaller = new XMLUnmarshaller(new InvocationContext(Repository.getMetadata()));
      StringReader reader = new StringReader("<Read-Request xmlns=\"" + XML.NS_URI_TNS + "\"><class>Patient</class>"
         + "<attributes>(fullName name)</attributes><where></where><orderBy></orderBy><count>8</count>"
         + "<offset>0</offset></Read-Request>");
      Response response = new Response();
      TransferObject tobj = new TransferObject("Patient");
      TransferObject tobj2 = new TransferObject("Doctor");

      tobj2.setOID(OID.fromBinary(Binary.parse("1000000000000010008000BEEF0000000A")));
      tobj.setValue("doctor", tobj2);
      response.addResult(Arrays.asList(new Object[]{tobj}));
      XMLReadRequest request = (XMLReadRequest)unmarshaller.deserialize(reader);

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMap); // validate to XSD

      Node root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Read-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertEquals(1, root.getChildNodes().item(0).getAttributes().getLength());
      assertEquals("Patient",
                   root
                      .getChildNodes()
                         .item(0)
                            .getAttributes()
                               .getNamedItem(XML.XSI_NS + ":type")
                                  .getNodeValue());
      assertEquals(3, root.getChildNodes().item(0).getChildNodes().getLength());

      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));
      assertNull(XMLUtil
                    .findChildElement(root.getChildNodes().item(0), "doctor")
                       .getAttributes()
                          .getNamedItem(XML.XSI_NS + ":type"));

      writer.getBuffer().setLength(0);
      reader = new StringReader("<Read-Request xmlns=\"" + XML.NS_URI_TNS + "\"><class>Patient</class>"
         + "<attributes>(fullName name)</attributes><where></where><orderBy></orderBy><count>8</count>"
         + "<offset>0</offset></Read-Request>");
      response = new Response();
      tobj = new TransferObject("User");
      tobj2 = new TransferObject("Doctor");

      tobj2.setOID(OID.fromBinary(Binary.parse("1000000000000010008000BEEF0000000A")));
      tobj.setValue("contact", tobj2);
      response.addResult(Arrays.asList(new Object[]{tobj}));
      request = (XMLReadRequest)unmarshaller.deserialize(reader);

      m_marshaller.serialize(request.invoke(new MockServer(response)), writer);
      XMLUtil.parse(new StringReader(writer.toString()), m_xsdMap); // validate to XSD

      root = XMLUtil.parse(new StringReader(writer.toString())).getFirstChild();

      assertEquals(XML.BASE_PREFIX + "Read-Response", root.getNodeName());
      assertEquals(1, root.getChildNodes().getLength());
      assertEquals("item", root.getChildNodes().item(0).getNodeName());
      assertEquals(1, root.getChildNodes().item(0).getAttributes().getLength());
      assertEquals("User",
                   root
                      .getChildNodes()
                         .item(0)
                            .getAttributes()
                               .getNamedItem(XML.XSI_NS + ":type")
                                  .getNodeValue());
      assertEquals(3, root.getChildNodes().item(0).getChildNodes().getLength());

      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "oid"));
      assertNotNull(XMLUtil.findChildElement(root.getChildNodes().item(0),
                                             XML.BASE_PREFIX + "version"));
      assertEquals("Doctor",
                   XMLUtil
                      .findChildElement(root.getChildNodes().item(0), "contact")
                         .getAttributes()
                            .getNamedItem(XML.XSI_NS + ":type")
                               .getNodeValue());
   }

   public void testMarshalValidateMetaclass() throws MarshallerException, IOException
   {
      StringWriter writer = new StringWriter();
      Response response = new Response();
      TransferObject tobj = new TransferObject("Contact"); // valid Metaclass object

      tobj.setValue("firstName", "Name First");
      tobj.setValue("lastName", null);
      tobj.setValue("customKey", "Key Custom");
      response.addResult(tobj); // need to marshal inside a Response since need predefined element

      m_marshaller.serialize(response, writer);

      Document rsp = XMLUtil.parse(new StringReader(writer.toString()), m_xsdMap);//validate to XSD
      Node root = rsp.getFirstChild();

      assertEquals(1, root.getChildNodes().getLength());

      Node result = root.getFirstChild();

      assertEquals("results", result.getNodeName());
      assertEquals(1, result.getAttributes().getLength());
      assertEquals(tobj.getClassName(),
                   result.getAttributes().getNamedItem(XML.XSI_NS + ":type").getNodeValue());
      assertEquals(7, result.getChildNodes().getLength());
      assertEquals(Short.toString(tobj.getVersion()),
                   XMLUtil.findChildElement(result, XML.BASE_PREFIX + "version")
                      .getTextContent());
      assertEquals("@b", // temporary ID not in tobj
                   XMLUtil.findChildElement(result, XML.BASE_PREFIX + "oid")
                      .getTextContent());

      final List/*<Element>*/ list = new ArrayList();
      ElementHandler listFiller = new ElementHandler()
      {
         public void handleElement(Element element)
         {
            list.add(element);
         }
      };

      XMLUtil.forEachChildElement(
         (Element)result, XML.BASE_PREFIX + "keys", listFiller);
      assertEquals("lastName", ((Element)list.get(0)).getTextContent());
      assertEquals("customKey", ((Element)list.get(1)).getTextContent());

      list.clear();
      XMLUtil.forEachChildElement(
         (Element)result, XML.BASE_PREFIX + "values", listFiller);
      assertEquals(1, ((Element)list.get(0)).getAttributes().getLength());
      assertEquals("true", ((Element)list.get(0)).getAttributes()
                           .getNamedItem(XML.XSI_NS + ":nil").getNodeValue());
      assertEquals("", ((Element)list.get(0)).getTextContent());
      assertEquals(1, ((Element)list.get(1)).getAttributes().getLength());
      assertEquals(XML.XSD_NS + ":string", ((Element)list.get(1)).getAttributes()
                                           .getNamedItem(XML.XSI_NS + ":type").getNodeValue());
      assertEquals(tobj.getValue("customKey"), ((Element)list.get(1)).getTextContent());

      assertEquals(tobj.getValue("firstName"),
                   XMLUtil.findChildElement(result, "firstName").getTextContent());
   }
}
TOP

Related Classes of nexj.core.rpc.xml.XMLMarshallerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.