/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cppuhelper.hxx"
#include <rtl/string.hxx>
#include <osl/diagnose.h>
#include <cppuhelper/component.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <cppuhelper/typeprovider.hxx>
#include "com/sun/star/uno/RuntimeException.hpp"

using namespace osl;
using namespace rtl;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;

namespace cppu
{

//	----------------------------------------------------
//	class OComponentHelper
//	----------------------------------------------------

OComponentHelper::OComponentHelper( Mutex & rMutex ) SAL_THROW( () )
	: rBHelper( rMutex )
{
}
OComponentHelper::~OComponentHelper() SAL_THROW( (RuntimeException) )
{
}

Any OComponentHelper::queryInterface( Type const & rType ) throw (RuntimeException)
{
    return OWeakAggObject::queryInterface( rType );
}
Any OComponentHelper::queryAggregation( Type const & rType ) throw (RuntimeException)
{
    if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
    {
        void * p = static_cast< lang::XComponent * >( this );
        return Any( &p, rType );
    }
    else if (rType == ::getCppuType( (Reference< lang::XTypeProvider > const *)0 ))
    {
        void * p = static_cast< lang::XTypeProvider * >( this );
        return Any( &p, rType );
    }
    return OWeakAggObject::queryAggregation( rType );
}
void OComponentHelper::acquire() throw ()
{
	OWeakAggObject::acquire();
}

void OComponentHelper::release() throw()
{
	Reference<XInterface > x( xDelegator );
	if (! x.is())
	{
		if (osl_decrementInterlockedCount( &m_refCount ) == 0)
		{
			if (! rBHelper.bDisposed)
			{
                // *before* again incrementing our ref count, ensure that our weak connection point
                // will not create references to us anymore (via XAdapter::queryAdapted)
                disposeWeakConnectionPoint();

				Reference<XInterface > xHoldAlive( *this );
				// First dispose
				try
				{
					dispose();
				}
				catch (::com::sun::star::uno::RuntimeException & exc)
				{
					// release should not throw exceptions
#if OSL_DEBUG_LEVEL > 0
                    OString msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
                    OSL_ENSURE( 0, msg.getStr() );
#else
                    (void) exc; // avoid warning about unused variable
#endif
				}

				// only the alive ref holds the object
				OSL_ASSERT( m_refCount == 1 );
				// destroy the object if xHoldAlive decrement the refcount to 0
				return;
			}
		}
		// restore the reference count
		osl_incrementInterlockedCount( &m_refCount );
	}
	OWeakAggObject::release();
}

Sequence< Type > OComponentHelper::getTypes() throw (RuntimeException)
{
	static OTypeCollection * s_pTypes = 0;
	if (! s_pTypes)
	{
		MutexGuard aGuard( Mutex::getGlobalMutex() );
		if (! s_pTypes)
		{
			static OTypeCollection s_aTypes(
				::getCppuType( (const Reference< lang::XComponent > *)0 ),
				::getCppuType( (const Reference< lang::XTypeProvider > *)0 ),
				::getCppuType( (const Reference< XAggregation > *)0 ),
				::getCppuType( (const Reference< XWeak > *)0 ) );
			s_pTypes = &s_aTypes;
		}
	}
	return s_pTypes->getTypes();
}

// XComponent
void OComponentHelper::disposing()
{
}

// XComponent
void OComponentHelper::dispose()
	throw(::com::sun::star::uno::RuntimeException)
{
	// An frequently programming error is to release the last
	// reference to this object in the disposing message.
	// Make it robust, hold a self Reference.
	Reference<XComponent > xSelf( this );

	// Guard dispose against multiple threading
	// Remark: It is an error to call dispose more than once
	sal_Bool bDoDispose = sal_False;
	{
	MutexGuard aGuard( rBHelper.rMutex );
	if( !rBHelper.bDisposed && !rBHelper.bInDispose )
	{
		// only one call go into this section
		rBHelper.bInDispose = sal_True;
		bDoDispose = sal_True;
	}
	}

	// Do not hold the mutex because we are broadcasting
	if( bDoDispose )
	{
		// Create an event with this as sender
		try
		{
            try
            {
                Reference<XInterface > xSource(
                    Reference<XInterface >::query( (XComponent *)this ) );
                EventObject aEvt;
                aEvt.Source = xSource;
                // inform all listeners to release this object
                // The listener container are automatically cleared
                rBHelper.aLC.disposeAndClear( aEvt );
                // notify subclasses to do their dispose
                disposing();
            }
            catch (...)
            {
                MutexGuard aGuard( rBHelper.rMutex );
                // bDispose and bInDisposing must be set in this order:
                rBHelper.bDisposed = sal_True;
                rBHelper.bInDispose = sal_False;
                throw;
            }
            MutexGuard aGuard( rBHelper.rMutex );
            // bDispose and bInDisposing must be set in this order:
            rBHelper.bDisposed = sal_True;
            rBHelper.bInDispose = sal_False;
		}
		catch (RuntimeException &)
		{
			throw;
		}
		catch (Exception & exc)
		{
            throw RuntimeException(
                OUString( RTL_CONSTASCII_USTRINGPARAM(
                              "unexpected UNO exception caught: ") ) +
                exc.Message, Reference< XInterface >() );
		}
	}
	else
	{
		// in a multithreaded environment, it can't be avoided,
		// that dispose is called twice.
		// However this condition is traced, because it MAY indicate an error.
		OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" );
	}
}

// XComponent
void OComponentHelper::addEventListener(
	const Reference<XEventListener > & rxListener )
	throw(::com::sun::star::uno::RuntimeException)
{
	ClearableMutexGuard aGuard( rBHelper.rMutex );
	if (rBHelper.bDisposed || rBHelper.bInDispose)
	{
        aGuard.clear();
        Reference< XInterface > x( (XComponent *)this, UNO_QUERY );
		rxListener->disposing( EventObject( x ) );
	}
	else
	{
		rBHelper.addListener( ::getCppuType( &rxListener ) , rxListener );
	}
}

// XComponent
void OComponentHelper::removeEventListener(
	const Reference<XEventListener > & rxListener )
	throw(::com::sun::star::uno::RuntimeException)
{
	rBHelper.removeListener( ::getCppuType( &rxListener ) , rxListener );
}

}
