/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.test.webservice.message;

// $Id: MessageJavaBean.java,v 1.1.2.3 2005/02/25 12:05:05 tdiesler Exp $

import com.ibm.wsdl.util.xml.DOM2Writer;
import org.jboss.logging.Logger;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.rmi.RemoteException;

/**
 * @author Thomas.Diesler@jboss.org
 * @since 26-Nov-2004
 */
public class MessageJavaBean implements Message
{
   // provide logging
   private final Logger log = Logger.getLogger(MessageJavaBean.class);

   /** org.w3c.dom.Element
    */
   public Element processElement(Element msg) throws RemoteException
   {
      StringWriter swr = new StringWriter();
      DOM2Writer.serializeAsXML(msg, swr);
      log.info("processElement: " + swr);

      try
      {
         SOAPElement reqElement = (SOAPElement)msg;
         SOAPFactory factory = SOAPFactory.newInstance();

         // verify order element
         Name name = factory.createName("Order", PREFIX_1, NSURI_1);
         Name elementName = reqElement.getElementName();
         if (name.equals(elementName) == false)
            throw new IllegalArgumentException("Unexpected element: " + elementName);

         // Verify attribute list
         // Note, is it correct that the NS declarations are not seen by Node.getAttributes() ?
         NamedNodeMap attributes = reqElement.getAttributes();
         if (attributes.getLength() != 1)
            throw new IllegalArgumentException("Unexpected number of attributes: " + attributes.getLength());

         for (int i = 0; i < attributes.getLength(); i++)
         {
            Attr attr = (Attr)attributes.item(i);
            String attrName = attr.getName();
            String nsURI = attr.getNamespaceURI();
            String value = attr.getValue();
            if ("attrval".equals(attrName))
            {
               if (value.equals("somevalue") == false)
                  throw new IllegalArgumentException("Unexpected attribute value: " + value);
               if (nsURI != null)
                  throw new IllegalArgumentException("Unexpected nsURI: " + nsURI);
            }
            else
            {
               throw new IllegalArgumentException("Unexpected attribute: " + attrName);
            }
         }

         // Verify NS declarations
         String nsURI_1 = reqElement.getNamespaceURI(PREFIX_1);
         if (NSURI_1.equals(nsURI_1) == false)
            throw new IllegalArgumentException("Unexpected namespace URI: " + nsURI_1);

         String nsURI_2 = reqElement.getNamespaceURI(PREFIX_2);
         if (NSURI_2.equals(nsURI_2) == false)
            throw new IllegalArgumentException("Unexpected namespace URI: " + nsURI_2);

         // Test getElementsByTagNameNS
         // http://jira.jboss.com/jira/browse/JBWS-99
         NodeList nodeList1 = reqElement.getElementsByTagNameNS(NSURI_2, "Customer");
         if (nodeList1.getLength() != 1)
            throw new IllegalArgumentException("Cannot getElementsByTagNameNS");

         // Test getElementsByTagName
         // http://jira.jboss.com/jira/browse/JBWS-99
         NodeList nodeList2 = reqElement.getElementsByTagName("Item");
         if (nodeList2.getLength() != 1)
            throw new IllegalArgumentException("Cannot getElementsByTagName");

         // verify customer element
         name = factory.createName("Customer", PREFIX_2, NSURI_2);
         reqElement = (SOAPElement)reqElement.getChildElements(name).next();
         String elementValue = reqElement.getValue();
         if ("Customer".equals(reqElement.getLocalName()) == false || "Kermit".equals(elementValue) == false)
            throw new IllegalArgumentException("Unexpected element value: " + elementValue);

         // verify item element
         reqElement = (SOAPElement)reqElement.getNextSibling();
         elementValue = reqElement.getValue();
         if ("Item".equals(reqElement.getLocalName()) == false || "Ferrari".equals(elementValue) == false)
            throw new IllegalArgumentException("Unexpected element value: " + elementValue);

         // Setup document builder
         DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
         docBuilderFactory.setNamespaceAware(true);

         // Prepare response
         DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
         Document doc = builder.parse(new ByteArrayInputStream(response.getBytes()));
         Element resElement = doc.getDocumentElement();

         return resElement;
      }
      catch (RuntimeException e)
      {
         throw e;
      }
      catch (Exception e)
      {
         throw new RemoteException(e.toString(), e);
      }
   }
}