blob: bb1a8c481e54b6ccd8597e0cc844a54f8dbd1e01 [file] [log] [blame]
/*
* 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.
*/
/**
* This class
*
* @author Susantha Kumara (skumara@virtusa.com, susantha@opensource.lk)
* @author damitha kumarage (damitha@hsenid.lk, damitha@opensource.lk)
*
*/
// !!! This include file must be first thing in file !!!
#include "../../platforms/PlatformAutoSense.hpp"
#include <stdio.h>
#include "ChannelFactory.hpp"
#include "HTTPTransportException.hpp"
#include "../../common/AxisTrace.h"
AXIS_CPP_NAMESPACE_START
#define MAXCHANNELS (int)MaxChannelCount
ChannelLibrary *ChannelFactory::m_ChannelLibrary[MAXCHANNELS] = {NULL,NULL};
ChannelFactory::
ChannelFactory()
{
for( int iCount = 0; iCount < (int) MaxChannelCount; iCount++)
{
m_pLibName[iCount] = NULL;
m_LibHandler[iCount] = NULL;
m_pChannel[iCount] = NULL;
}
}
ChannelFactory::
~ChannelFactory()
{
for( int eChannelType = 0; eChannelType < (int) MaxChannelCount; eChannelType++)
{
UnLoadChannelLibrary( (g_ChannelType) eChannelType);
}
}
IChannel * ChannelFactory::
LoadChannelLibrary( g_ChannelType eChannelType, const char * pcLibraryName)
{
logEntryEngine("ChannelFactory::LoadChannelLibrary")
DLHandler sLibHandler;
IChannel * pChannel = NULL;
int iLibCount = (int) eChannelType;
// Additional code added to block reloading of DLL if name has not changed.
if( m_pLibName[iLibCount] == NULL ||
strcmp( pcLibraryName, m_pLibName[iLibCount]) != 0)
{
logDebugArg1("Loading transport %s", pcLibraryName)
sLibHandler = PLATFORM_LOADLIB( pcLibraryName);
if( !sLibHandler)
{
// get load lib error information
string sFullMessage = "Failed to load transport channel library " +
string(pcLibraryName) + ". " + PLATFORM_LOADLIB_ERROR;
logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())
throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
}
else
{
CREATE_OBJECT3 sCreate = (CREATE_OBJECT3)NULL;
DELETE_OBJECT3 sDelete = (DELETE_OBJECT3)NULL;
sCreate = (CREATE_OBJECT3) PLATFORM_GETPROCADDR( sLibHandler, CREATE_FUNCTION3);
if (sCreate)
sDelete = (DELETE_OBJECT3) PLATFORM_GETPROCADDR( sLibHandler, DELETE_FUNCTION3);
if (!sCreate || !sDelete)
{
// get load lib error information
string sFullMessage = "Failed to resolve to transport channel procedures in library " +
string(pcLibraryName) + ". " + PLATFORM_LOADLIB_ERROR;
// Unload library - this must be done after obtaining error info above
PLATFORM_UNLOADLIB( sLibHandler);
if( eChannelType == UnsecureChannel)
{
logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())
throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
}
else
{
logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED", sFullMessage.c_str())
throw HTTPTransportException( SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED, sFullMessage.c_str());
}
}
// Additional code added to that when the user wants to load a different
// library from that which is already loaded, it will now allow the change.
UnLoadChannelLibrary(eChannelType);
delete [] m_pLibName[iLibCount];
m_pLibName[iLibCount] = NULL;
m_pLibName[iLibCount] = new char[ strlen( pcLibraryName) + 1];
strcpy( m_pLibName[iLibCount], pcLibraryName);
m_LibHandler[iLibCount] = sLibHandler;
if( sCreate)
{
sCreate( &pChannel);
m_pChannel[iLibCount] = pChannel;
if (AxisTrace::isLoggingEnabled() && AxisTrace::isTransportLoggingEnabled())
pChannel->enableTrace(AxisTrace::getLogFilePath().c_str(), AxisTrace::getLogFilter().c_str());
}
}
}
else
pChannel = m_pChannel[iLibCount];
logExitWithPointer(pChannel)
return pChannel;
}
bool ChannelFactory::
UnLoadChannelLibrary( g_ChannelType eChannelType)
{
logEntryEngine("ChannelFactory::UnLoadChannelLibrary")
bool bSuccess = false;
int iLibIndex = (int) eChannelType;
if( m_pChannel[iLibIndex] != NULL)
{
if( m_LibHandler[iLibIndex] != NULL)
{
// If there is a channel library object handle then find the entry point in
// the library to call the channel library destructor (DestroyInstance) which
// in turn calls the channel destructor. On return from this call, the
// m_pChannel[iLibIndex] object no longer exists.
DELETE_OBJECT3 sDelete = (DELETE_OBJECT3) PLATFORM_GETPROCADDR( m_LibHandler[iLibIndex], DELETE_FUNCTION3);
sDelete( m_pChannel[iLibIndex]);
}
else
{
// Samisa: somehow, the above block does not seem to deallocate the channel
// As a workaround, I delete the channel here and seems this logic is not having any side effects
// More importantly I could get rid of the memory leak
delete m_pChannel[iLibIndex];
}
m_pChannel[iLibIndex] = NULL;
}
// Delete library name from the library name list.
delete [] m_pLibName[iLibIndex];
m_pLibName[iLibIndex] = NULL;
// If a channel library object handle is valid, then unload the library and
// reset the handle.
if( m_LibHandler[iLibIndex] != NULL)
{
PLATFORM_UNLOADLIB( m_LibHandler[iLibIndex]);
m_LibHandler[iLibIndex] = 0;
bSuccess = true;
}
logExitWithBoolean(bSuccess)
return bSuccess;
}
void ChannelFactory::
preloadChannels(char *unsecChannel, char *secChannel)
{
if (unsecChannel && strcmp(unsecChannel,"Unknown")) preloadChannel(UnsecureChannel, unsecChannel);
if (secChannel && strcmp(secChannel,"Unknown")) preloadChannel(SecureChannel, secChannel);
}
void ChannelFactory::
preloadChannel(g_ChannelType type, const char *pcLibraryName)
{
logEntryEngine("ChannelFactory::preloadChannel")
int iLibCount = (int)type;
ChannelLibrary *pCh = new ChannelLibrary();
pCh->m_Library = PLATFORM_LOADLIB( pcLibraryName);
if( !pCh->m_Library)
{
// get load lib error information
string sFullMessage = "Failed to pre-load transport channel library " +
string(pcLibraryName) + ". " + PLATFORM_LOADLIB_ERROR;
delete pCh;
logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())
throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
}
pCh->m_Create = (CREATE_OBJECT3) PLATFORM_GETPROCADDR( pCh->m_Library, CREATE_FUNCTION3);
if (pCh->m_Create)
pCh->m_Delete = (DELETE_OBJECT3) PLATFORM_GETPROCADDR( pCh->m_Library, DELETE_FUNCTION3);
if (!pCh->m_Create || !pCh->m_Delete)
{
// get load lib error information
string sFullMessage = "Failed to resolve to transport channel procedures in library " +
string(pcLibraryName) + ". " + PLATFORM_LOADLIB_ERROR;
// Unload library - this must be done after obtaining error info above
PLATFORM_UNLOADLIB( pCh->m_Library);
delete pCh;
if( type == UnsecureChannel)
{
logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())
throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
}
else
{
logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED", sFullMessage.c_str())
throw HTTPTransportException( SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED, sFullMessage.c_str());
}
}
m_ChannelLibrary[iLibCount] = pCh;
logExit()
}
IChannel *ChannelFactory::
createChannel(g_ChannelType type)
{
logEntryEngine("ChannelFactory::createChannel")
int iLibCount = (int)type;
IChannel *pChannel = NULL;
if (m_ChannelLibrary[iLibCount])
{
m_ChannelLibrary[iLibCount]->m_Create(&pChannel);
m_pChannel[iLibCount] = pChannel;
if (AxisTrace::isLoggingEnabled() && AxisTrace::isTransportLoggingEnabled())
pChannel->enableTrace(AxisTrace::getLogFilePath().c_str(), AxisTrace::getLogFilter().c_str());
}
logExitWithPointer(pChannel)
return pChannel;
}
void ChannelFactory::
unloadChannels()
{
logEntryEngine("ChannelFactory::unloadChannels")
for (int i=0; i<(int)MaxChannelCount; i++)
{
if (m_ChannelLibrary[i])
{
PLATFORM_UNLOADLIB(m_ChannelLibrary[i]->m_Library);
delete m_ChannelLibrary[i];
m_ChannelLibrary[i] = NULL;
}
}
logExit()
}
AXIS_CPP_NAMESPACE_END