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

// $Id: AbstractServlet.java,v 1.1.2.2 2005/03/02 14:32:32 tdiesler Exp $

import org.jboss.axis.AxisEngine;
import org.jboss.axis.AxisFault;
import org.jboss.axis.ConfigurationException;
import org.jboss.axis.MessageContext;
import org.jboss.axis.description.OperationDesc;
import org.jboss.axis.description.ServiceDesc;
import org.jboss.axis.server.AxisServer;
import org.jboss.axis.transport.http.AxisServlet;
import org.jboss.axis.utils.XMLUtils;
import org.jboss.logging.Logger;
import org.jboss.mx.util.MBeanProxy;
import org.jboss.mx.util.MBeanProxyCreationException;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.webservice.AxisServiceMBean;
import org.jboss.webservice.PortComponentInfo;
import org.w3c.dom.Document;

import javax.management.MBeanServer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * The servlet that that is associated with context /ws4ee
 * 
 * It manages the 'Version' service
 *
 * @author Thomas.Diesler@jboss.org
 * @since 09-Feb-2005
 */
public abstract class AbstractServlet extends AxisServlet
{
   // provide logging
   protected final Logger log = Logger.getLogger(AbstractServlet.class);

   /**
    * Get the transport URL
    * <p/>
    * For JSE service endpoints
    * e.g. http://localhost:8080/whatever-url-mapping
    */
   protected String getTransportURL(HttpServletRequest req, String serviceName)
   {
      return req.getRequestURI();
   }

   protected void setupHTMLResponseHeader(HttpServletResponse res, PrintWriter writer)
   {
      writer.println("<head>");
      writer.println("<meta http-equiv='Content-Type content='text/html; charset=iso-8859-1'>");
      writer.println("<title>JBossWS</title>");
      writer.println("<link rel='stylesheet' href='/ws4ee/styles.css'>");
      writer.println("</head>");
   }

   /**
    * This method lists the available services; it is called when there is
    * nothing to execute on a GET
    */
   protected void reportAvailableServices(HttpServletResponse res, PrintWriter writer, HttpServletRequest req)
           throws ConfigurationException, AxisFault
   {
      AxisEngine engine = getEngine();

      res.setContentType("text/html");
      setupHTMLResponseHeader(res, writer);
      writer.println("<h2>And now... Some Services</h2>");
      writer.println("<ul>");

      // Get the JBossWS AxisService
      AxisServiceMBean axisService = null;
      try
      {
         MBeanServer server = MBeanServerLocator.locateJBoss();
         axisService = (AxisServiceMBean)MBeanProxy.get(AxisServiceMBean.class, AxisServiceMBean.OBJECT_NAME, server);
      }
      catch (MBeanProxyCreationException e)
      {
         throw new IllegalStateException("Cannot obtain: " + AxisServiceMBean.OBJECT_NAME);
      }

      Iterator it = engine.getConfig().getDeployedServices();
      while (it.hasNext())
      {
         ServiceDesc sd = (ServiceDesc)it.next();
         String serviceName = sd.getName();

         PortComponentInfo pcInfo = axisService.getPortComponentInfo(serviceName);
         String serviceURL = null;
         if (pcInfo != null)
         {
            serviceURL = pcInfo.getServiceEndpointURL();
         }
         else
         {
            serviceURL = getWebappBase(req) + "/services/" + serviceName;
         }

         StringBuffer sb = new StringBuffer("<li>" + serviceName + "<a href='" + serviceURL + "?wsdl'>&nbsp;<i>(wsdl)</i></a></li>");

         ArrayList operations = sd.getOperations();
         if (!operations.isEmpty())
         {
            sb.append("<ul>");
            for (Iterator itOp = operations.iterator(); itOp.hasNext();)
            {
               OperationDesc desc = (OperationDesc)itOp.next();
               sb.append("<li>" + desc.getName() + "</li>");
            }
            sb.append("</ul>");
         }
         writer.println(sb.toString());
      }
      writer.println("</ul>");
   }

   /**
    * Handle a wsdl request
    */
   protected void processWsdlRequest(MessageContext msgContext, HttpServletResponse res, PrintWriter writer)
           throws AxisFault
   {
      String serviceURL = (String)msgContext.getProperty(MessageContext.TRANS_URL);

      AxisEngine engine = getEngine();
      engine.generateWSDL(msgContext);

      Document doc = (Document)msgContext.getProperty("WSDL");
      if (doc == null)
         throw new AxisFault("Cannot get wsdl document for service: " + serviceURL);

      res.setContentType("text/xml");
      XMLUtils.DocumentToWriter(doc, writer);
   }

   /**
    * Get an AxisServer with the EngineConfiguration from the JMX AxisService
    */
   public AxisServer getEngine() throws AxisFault
   {
      try
      {
         MBeanServer server = MBeanServerLocator.locateJBoss();
         axisServer = (AxisServer)server.getAttribute(AxisServiceMBean.OBJECT_NAME, "AxisServer");
      }
      catch (Exception e)
      {
         log.warn("Cannot access AxisService, using default server config");
         axisServer = super.getEngine();
      }

      return axisServer;
   }
}
