/*
 *   Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
 *
 *   Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#if !defined(_IHANDLERSOAPSERIALIZER_H____OF_AXIS_INCLUDED_)
#define _IHANDLERSOAPSERIALIZER_H____OF_AXIS_INCLUDED_

/**
 * @file IHandlerSoapSerializer.hpp
 */

#include <axis/IWrapperSoapSerializer.hpp>
#include <axis/SoapEnvVersions.hpp>

AXIS_CPP_NAMESPACE_START

class IHeaderBlock;
/**
  * @class IHandlerSoapSerializer
  * @brief interface for the IHandlerSoapSerializer class. This interface is
  * exposed to a Handler Writer, to let him manipulate on the Serialzer object.
  * Example usage is given below.
  * <PRE>
  * int ESHHandler::invoke(void *pvIMsg)
  * {
  *     IMessageData *pIMsg = (IMessageData*) pvIMsg;
  *     AxisChar* pachTemp;
  *     if(pIMsg->isPastPivot())
  *     {
  *         //this is a response
  * 
  *         IHandlerSoapSerializer* pISZ;
  *         pIMsg->getSoapSerializer(&pISZ);
  *
  *         IHeaderBlock* pIHeaderBlock= pISZ->createHeaderBlock();
  *
  *         pIHeaderBlock->setLocalName("echoMeStringResponse");
  *     }
  * }
  * </PRE>
  * 
  */
class IHandlerSoapSerializer : public IWrapperSoapSerializer

{
public:        
    virtual ~IHandlerSoapSerializer() {};

    /**
      * Will create a Header Block and adds it to the Serializer.
      *
      * @return The created Header Block pointer will be returned, which the
      * user can manipulate on it.
      */
    virtual IHeaderBlock* createHeaderBlock()=0;

    /**
      * Will create a Header Block using the given local name and the namespace
      * uri, and adds it to the Serializer.
      *
      * @param pachLocalName The local name of the Header Block
      * @param pachUri The namespace uri of the Header Block.
      * @return The created Header Block pointer will be returned, which the
      * user can manipulate on it.
      */
    virtual IHeaderBlock*  createHeaderBlock(const AxisChar *pachLocalName, 
                                             const AxisChar *pachUri)=0;    

    /**
      * Adds the given Header Block to the Serialzer.
      *
      * @param pBlk The Header Block to be added.
      * @return AXIS_SUCCESS or AXIS_FAIL to indicate success or fail.
      */
    virtual int AXISCALL addHeaderBlock(IHeaderBlock* pBlk)=0;

    /**
      * Sets the SOAP Version.
      * @param eSOAP_VERSION The SOAP version to set.
      * @return AXIS_SUCCESS to indicate success.
      */
    virtual int setSoapVersion(SOAP_VERSION eSOAP_VERSION)=0;

    /**
     * Gets and returns the Header Block of the given local name and 
     * namespace uri.After returning the Header Block pointer, it will not be
     * removed from the available Header Block list of the Serializer.
     * The caller of this method should not delete the returned pointer 
     * object.
     * 
     * @param pcName local name of the HeaderBlock
     * @param pcNamespace namespace of the HeaderBlock
     * @return HeaderBlock
     */
     virtual IHeaderBlock* getHeaderBlock(const AxisChar *pcName, 
                                          const AxisChar *pcNamespace)=0;
     /**
      * Used with getNextHeaderBlock, it returns the first header block,
      * or NULL if there are no headers.
      * 
      * @return First HeaderBlock
      */
     virtual IHeaderBlock* getFirstHeaderBlock()=0;
 
     /**
      * Used with getFirstHeaderBlock, it returns the next header block,
      * or NULL if there are no headers.
      * 
      * @return Next HeaderBlock
      */
     virtual IHeaderBlock* getNextHeaderBlock()=0;

     /**
      * Used with getFirstHeaderBlock, it returns the current header block,
      * or NULL if:
      *  - there are no headers, 
      *  - or if the getFirstHeaderBlock method is not called at least once.
      * @return Current HeaderBlock
      */
     virtual IHeaderBlock* getCurrentHeaderBlock()=0;

    /*
     * A handler may get the entire soap body and encrypt/compress 
     * it and encode to either base64Binary or hexBinary before 
     * sending to the transport. So any handler in the response message 
     * path may use following functions to get the entire soap 
     * body / set encrypted and/or compressed and then encoded soap body
     * back to the Serializer
     */

    /**
     * Set the SOAP body with HexBinary data.
     * 
     * @param body SOAP body to set, in HexBinary.
     * @return status
     */
    virtual int AXISCALL setBodyAsHexBinary(xsd__hexBinary body)=0;
    
    /**
     * Set the SOAP body with Base64Binary data.
     * 
     * @param body SOAP body to set, in Base64Binary.
     * @return status
     */
    virtual int AXISCALL setBodyAsBase64Binary(xsd__base64Binary body)=0;

    /**
     * Get the SOAP body as a string.
     * 
     * @return SOAP body as a string
     */
    virtual const AxisChar* AXISCALL getBodyAsString()=0;


    /**
    *Used to delete a header block
    *
    */
    
    virtual int deleteHeaderBlock(const AxisChar* pName, 
                                  const AxisChar* pNamespace)=0;
    /**
    *Used to delete all the header block
    *
    */
    virtual int removeSoapHeader()=0;

    /**
     * Adds the namespace declaration to the SOAP Envelope.
     * @param pachNamespaceURI namespace URI to add to SOAP envelope
     * @param pachPrefix prefix to be used for namespace URI
     */
    virtual void addNamespaceToEnvelope(AxisChar *pachNamespaceURI, 
                                        AxisChar* pachPrefix)=0;
};

AXIS_CPP_NAMESPACE_END

#endif 

