//
// CIMHTTPListener.java
//
// The contents of this file are subject to the SNIA Public License Version 1.0
// (the "License"); you may not use this file except in compliance with the
// License. You may obtain a copy of the License at
//
//      http://www.snia.org/resources/openSource.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is CIMHTTPListener.java
//
// This source uses the Solaris WBEM APIs version 2.2.
// Synchronization will be maintained with the Solaris WBEM APIS,
// which are being standardized through the Java Community Process.
//
// The Initial Developer of the Original Code is Adrian Schuur.
//
// Contributor(s):
//
// For HP Release 2.0 2003/03/12 ( Bapu Patil)
// Support Indication and seperate CIMListner part from
// Client API code
//
//
//
package org.snia.wbem.listener;

import java.util.*;
import java.net.*;
import java.io.*;
import org.snia.wbemcfg.GlobalConfig;
import org.snia.wbem.cim.CIMException;
import org.snia.wbemcmd.utils.Log;
import org.snia.wbemcmd.xml.SocketProvider;
import org.snia.wbemcmd.xml.PlainSocketProvider;
import org.snia.wbemcmd.xml.JSSESocketProvider;
import org.snia.wbemcmd.xml.CannotCreateSocketException;


/**
  CIMHTTPListener extends CIMListner and implements CIM/XML Listener
  to handle CIM/XML indications events.

  This Class handles both SSL and Non-SSL connection for the CIMListener
  Consumer. Consumers application can specify SSL enable option
  in the constrctor if it wants to do SSL communication.
 
   @ see org.snia.wben.listner.CIMListener
 */
public class CIMHTTPListener implements CIMListener
{
   CIMHTTPIndicationReceiver rcv=null;
   String name=null;
   String creationName="_";
   int port=-1;
   boolean enableSSL=false;

   ServerSocket serverSocket=null;

   Vector listeners=new Vector();
   Vector ports=new Vector();


   /**
    * constructor for CIMHTTPListener
    *
    * @param portno - Port number for CIMListener to run
    *
    * @exception CIMException
    *     In case something wrong..what
    */
   public CIMHTTPListener(int portNo)
          throws CIMException 
   {
      this.port=portNo;
   }

   /**
    * constructor for CIMHTTPListener. By default SSL is not enabled
    * caller must set sslEnable parameter to true if CIM Listener
    * should run in SSL mode.
    *
    * @param portno - Port number for CIMListener to run
    * @param sslEnabled - true or false for SSL Listenr
    *
    * @exception CIMException
    *     In case something wrong..what
    */
   public CIMHTTPListener(int portNo, boolean sslEnabled)
          throws CIMException 
   {
      this.port=portNo;
      this.enableSSL=sslEnabled;
   }

   /**
    * indicationOccured method is called when the indication
    * received by the CIMListener. Called must implement it's
    * own indicationOccured method in order to process
    * indication.
    *
    * @param CIMIndication - is a CIM Instance Object
    *
    * @param URL - URL name of the indication request.
    *              This is returned to Indication Consumer
    *		   by the CIMListener.
    */
   public void indicationOccured(CIMIndication e, String URL) { }

   /**
    * getSocketProvider
    *   get socket connection outputstream for HTTP operation. 
    * @return ServerSocket 
    *   Socket handle
    * @exception CIMException
    *   In case of unable to connect to the Server
    */
    private SocketProvider getSocketProvider() throws CIMException 
    {
            SocketProvider sp = null;
            if ( enableSSL  == false )
            {
                // obtain the right socket provider from global config
                if (GlobalConfig.httpSocketProvider != null)
                try 
                {
                     Class spClass = Class.forName(GlobalConfig.httpSocketProvider);
                     sp = (SocketProvider) spClass.newInstance();
                }
                catch (Exception exhttp ) 
                {
                     Log.println("HTTPOutputSimple: Error loading httpSocketProvider \"" +
                         GlobalConfig.httpSocketProvider + "\", message : " +
                         exhttp.getLocalizedMessage());
                }
            }
            else
            {
                // obtain the right socket provider from global config
                if (GlobalConfig.httpsSocketProvider != null)
                try 
                {
                     Class spClass = Class.forName(GlobalConfig.httpsSocketProvider);
                     sp = (SocketProvider) spClass.newInstance();
                }
                catch (Exception exhttps ) 
                {
                     Log.println("HTTPOutputSimple: Error loading httpsSocketProvider \"" +
                         GlobalConfig.httpSocketProvider + "\", message : " +
                         exhttps.getLocalizedMessage());
                }
            }

            // if none specified or if it could not be loaded use default
            if (sp == null)
            {
                 Log.println("HTTPOutputSimple: No http(s)SocketProvider specified - " +
                             "Will use the the plainSocketProvider");
                 sp = new PlainSocketProvider();
            }

	    return(sp);
   }

   /**
    * Start the CIM HTTP Listener. This will start Listener server
    * on the port that was specified. 
    *
    * @exception CIMException
    *     In case something wrong.
    */
   public void startCIMHTTPListener() 
          throws CIMException 
   {
      try 
      {
            // use SocketProvider to obtain a new server socket
            SocketProvider  sockSP = getSocketProvider();
            serverSocket = sockSP.createServerSocket(port,1000);

            rcv=new CIMHTTPIndicationReceiver(serverSocket, this);
            rcv.start();
            System.err.println("--- socket provider is "+sockSP);
      }
      catch ( RuntimeException rune ) 
      {
         if (GlobalConfig.DEBUG_XML)
         { 
             Log.println( "RunTimeException, exception="+rune );
         }
         throw new CIMException(rune.toString());
      }
      catch ( CannotCreateSocketException cce ) 
      {
         if (GlobalConfig.DEBUG_XML)
         { 
             Log.println( "socket create failed, exception="+cce );
         }
            throw new CIMException(cce.toString());
      }
      catch (java.net.UnknownHostException unhe) 
      {
         if (GlobalConfig.DEBUG_XML)
         { 
             Log.println( "Unknown host exception="+unhe );
         }
         throw new CIMException(unhe.toString());
      }
      catch (java.io.IOException ioe) 
      {
         if (GlobalConfig.DEBUG_XML)
         { 
             Log.println( "IO exception="+ioe );
         }
         throw new CIMException(ioe.toString());
      }
   }

   /**
    * Stop the CIM HTTP Listener. This closes the server socket
    * connection.
    *
    * @exception CIMException
    *     In case something wrong.
    */
   public void stopHTTPCIMListener()
          throws CIMException 
   {
      try 
      {
         serverSocket.close();
      }
      catch (java.io.IOException ioe) 
      {
         if (GlobalConfig.DEBUG_XML)
         { 
            Log.println( "IO exception="+ioe);
         }
         throw new CIMException(ioe.toString());
      }	  
   }
};

