package com.psol.resourceful;

import java.io.*;
import java.sql.*;
import java.util.*;
import java.text.*;
import javax.mail.*;
import org.w3c.dom.*;
import org.apache.soap.*;
import javax.xml.parsers.*;
import org.apache.soap.rpc.*;

public class BookingMessage
   extends BookingService
{
    private static final String namespaceURI =
                  "http://www.psol.com/2001/resourceful/message";
    private DateFormat dateFormat;

    public BookingMessage()
    {
        dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM,
                                                Locale.US);
        dateFormat.setLenient(true);
    }

    private void processBooking(Connection connection,
                                Element booking)
       throws SQLException
    {
       if(!booking.getLocalName().equals("booking") ||
          !booking.getNamespaceURI().equals(namespaceURI))
           throw new IllegalArgumentException(
                               "expecting <rf:booking> element");
       String name = booking.getAttribute("name"),
              sstart = booking.getAttribute("start"),
              send = booking.getAttribute("end"),
              email = booking.getAttribute("email");
       java.util.Date start,
                      end;
       try {
           start = dateFormat.parse(sstart);
           end = dateFormat.parse(send);
       }
       catch(ParseException e) {
           throw new IllegalArgumentException("invalid date");
       }
       doBookResource(connection,name,start,end,email);
    }

    private void processBookings(Connection connection,
                                 Element bookings)
       throws SQLException
    {
       if(!bookings.getLocalName().equals("bookings") ||
          !bookings.getNamespaceURI().equals(namespaceURI))
           throw new IllegalArgumentException(
                              "expecting <rf:bookings> element");
       NodeList children =
           bookings.getElementsByTagNameNS(namespaceURI,
                                           "booking");
       for(int i = 0;i < children.getLength();i++)
           processBooking(connection,
                          (Element)children.item(i));
    }

    public void bookings(Envelope envelope,
                         SOAPContext request,
                         SOAPContext response)
       throws IOException, SQLException, MessagingException,
              ParserConfigurationException
    {
       Vector entries = envelope.getBody().getBodyEntries();
       if(entries.size() != 1)
          throw new IllegalArgumentException(
                    "cannot process body with multiple entries");
       Element root = (Element)entries.firstElement();
       Connection connection = makeConnection();
       try {
           processBookings(connection,root);
           connection.commit();
       }
       catch(SQLException e) {
           connection.rollback();
           throw e;
       }
       catch(IllegalArgumentException e) {
           connection.rollback();
           throw e;
       }
       DocumentBuilderFactory factory =
           DocumentBuilderFactory.newInstance();
       factory.setNamespaceAware(true);
       DocumentBuilder builder = factory.newDocumentBuilder();
       Document document = builder.newDocument();
       root = document.createElementNS(namespaceURI,"success");
       root.appendChild(document.createTextNode("Many thanks!"));
       Vector vector = new Vector();
       vector.addElement(root);
       Body body = new Body();
       body.setBodyEntries(vector);
       Envelope env = new Envelope();
       env.setBody(body);
       StringWriter writer = new StringWriter();
       env.marshall(writer,null,response);
       response.setRootPart(writer.toString(),"text/xml");
    }
}
