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

// $Id: ServiceEndpointServlet.java,v 1.8.2.5 2005/04/12 16:07:49 starksm Exp $

import org.jboss.axis.AxisEngine;
import org.jboss.axis.AxisFault;
import org.jboss.axis.MessageContext;
import org.jboss.axis.handlers.soap.SOAPService;
import org.jboss.logging.Logger;
import org.jboss.webservice.ServiceDeployer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * An JBossWS AxisServlet.
 *
 * It gets the server config via JMX from the AxisService.
 * Supports URL wsdl lookup with imports
 *
 * @author Thomas.Diesler@jboss.org
 * @since 15-April-2004
 */
public class ServiceEndpointServlet extends AbstractServlet
{
   /** @since 4.0.2 */
   static final long serialVersionUID = 3806847653370058302L;

   // provide logging
   protected final Logger log = Logger.getLogger(getClass());

   /**
    * Process GET requests.
    */
   public void doGet(HttpServletRequest req, HttpServletResponse res)
           throws ServletException, IOException
   {
      String url = req.getRequestURL().toString();
      String queryString = req.getQueryString();
      log.debug("doGet: " + url + (queryString != null ? "?" + queryString : ""));

      PrintWriter writer = res.getWriter();
      try
      {
         AxisEngine engine = getEngine();

         // Get the SOAP servie
         String serviceName = getServiceName(req);
         SOAPService service = (serviceName != null ? engine.getService(serviceName) : null);

         boolean wsdlRequested = req.getParameter("wsdl") != null || req.getParameter("WSDL") != null;

         if (!wsdlRequested)
         {
            log.debug("Report available services");

            // If the user requested the servlet (i.e. /ws4ee/services)
            // with no service name, present the user with a list of deployed services to be helpful
            // Don't do this if we are doing WSDL or list.
            reportAvailableServices(res, writer, req);
            return;
         }

         if (service == null)
         {
            log.error("Cannot get axis service: " + serviceName);
            reportCantGetAxisService(req, res, writer);
            return;
         }

         // get message context w/ various properties set
         MessageContext msgContext = createMessageContext(engine, req, res);

         // we found the service, so we can set it in the msg context
         // whoever comes after, won't have to retry finding it
         if (service != null)
            msgContext.setTargetService(serviceName);

         String transportURL = getTransportURL(req, serviceName);
         if (transportURL != null)
         {
            msgContext.setProperty(MessageContext.TRANS_URL, transportURL);
            log.debug("Set transport.url=" + transportURL);
         }

         if (wsdlRequested)
         {
            String wsdlResource = req.getParameter("resource");
            if (wsdlResource != null)
            {
               log.debug("Process wsdl import request: " + wsdlResource);
               msgContext.setProperty(MessageContext.WSDLGEN_RESOURCE, wsdlResource);
            }
            else
            {
               log.debug("Process wsdl request");
            }

            processWsdlRequest(msgContext, res, writer);
            return;
         }

         // If nothing else was done previously
         log.debug("Report service info");
         reportServiceInfo(res, writer, service, serviceName);
      }
      catch (AxisFault fault)
      {
         reportTrouble(fault, res, writer);
      }
      catch (Exception e)
      {
         reportTrouble(e, res, writer);
      }
      finally
      {
         // Make sure the MessageContext is removed from the calling ThreadLocal
         AxisEngine.setCurrentMessageContext(null);
         writer.close();
      }
   }

   /**
    * Get the service name as it is known to Axis
    * <p/>
    * For JSE service endpoints it is obtained from the generated init parameter in web.xml
    */
   protected String getServiceName(HttpServletRequest req)
   {
      String serviceName = getServletConfig().getInitParameter(ServiceDeployer.INIT_PARAM_WEBSERVICE_ID);
      return serviceName;
   }
}