From b451504922f13731c49105fc1e82da07c1bc155b Mon Sep 17 00:00:00 2001 From: Jens-Heiner Rechtien Date: Wed, 27 Jun 2007 13:57:39 +0000 Subject: INTEGRATION: CWS sdblogging (1.1.2); FILE ADDED 2007/05/22 19:14:03 fs 1.1.2.4: #i76119# implement changes suggested by API review: initialize components by generic ctor, not by component context values 2007/05/20 13:33:17 fs 1.1.2.3: #i10000# 2007/04/12 19:06:29 fs 1.1.2.2: #i10000# (unxsoli4) 2007/04/05 07:34:16 fs 1.1.2.1: #i76119# initial implementation of the new logging API --- extensions/source/logging/filehandler.cxx | 452 ++++++++++++++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 extensions/source/logging/filehandler.cxx (limited to 'extensions/source/logging') diff --git a/extensions/source/logging/filehandler.cxx b/extensions/source/logging/filehandler.cxx new file mode 100644 index 000000000000..966e48bdeea3 --- /dev/null +++ b/extensions/source/logging/filehandler.cxx @@ -0,0 +1,452 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: filehandler.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-06-27 14:57:39 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "log_module.hxx" +#include "methodguard.hxx" +#include "loghandler.hxx" + +/** === begin UNO includes === **/ +#ifndef _COM_SUN_STAR_LOGGING_XLOGHANDLER_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_UCB_ALREADYINITIALIZEDEXCEPTION_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_ +#include +#endif +#ifndef _COM_SUN_STAR_UTIL_XSTRINGSUBSTITUTION_HPP_ +#include +#endif +/** === end UNO includes === **/ + +#include + +#include + +#include +#include + +#include +#include + +#include + +#include + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::logging::XLogHandler; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::ucb::AlreadyInitializedException; + using ::com::sun::star::lang::XInitialization; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::util::XStringSubstitution; + using ::com::sun::star::beans::NamedValue; + /** === end UNO using === **/ + + //==================================================================== + //= FileHandler - declaration + //==================================================================== + typedef ::cppu::WeakComponentImplHelper3 < XLogHandler + , XServiceInfo + , XInitialization + > FileHandler_Base; + class FileHandler :public ::cppu::BaseMutex + ,public FileHandler_Base + { + private: + enum FileValidity + { + /// never attempted to open the file + eUnknown, + /// file is valid + eValid, + /// file is invalid + eInvalid + }; + + private: + ::comphelper::ComponentContext m_aContext; + LogHandlerHelper m_aHandlerHelper; + ::rtl::OUString m_sFileURL; + ::std::auto_ptr< ::osl::File > m_pFile; + FileValidity m_eFileValidity; + + protected: + FileHandler( const Reference< XComponentContext >& _rxContext ); + virtual ~FileHandler(); + + // XLogHandler + virtual ::rtl::OUString SAL_CALL getEncoding() throw (RuntimeException); + virtual void SAL_CALL setEncoding( const ::rtl::OUString& _encoding ) throw (RuntimeException); + virtual Reference< XLogFormatter > SAL_CALL getFormatter() throw (RuntimeException); + virtual void SAL_CALL setFormatter( const Reference< XLogFormatter >& _formatter ) throw (RuntimeException); + virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException); + virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException); + virtual void SAL_CALL flush( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL publish( const LogRecord& Record ) throw (RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // OComponentHelper + virtual void SAL_CALL disposing(); + + public: + // XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); + + public: + typedef ComponentMethodGuard< FileHandler > MethodGuard; + void enterMethod( MethodGuard::Access ); + void leaveMethod( MethodGuard::Access ); + + private: + /** prepares our output file for writing + */ + bool impl_prepareFile_nothrow(); + + /// writes the given string to our file + void impl_writeString_nothrow( const ::rtl::OString& _rEntry ); + + /** does string substitution on a (usually externally provided) file url + */ + void impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL ); + }; + + //==================================================================== + //= FileHandler - implementation + //==================================================================== + //-------------------------------------------------------------------- + FileHandler::FileHandler( const Reference< XComponentContext >& _rxContext ) + :FileHandler_Base( m_aMutex ) + ,m_aContext( _rxContext ) + ,m_aHandlerHelper( _rxContext, m_aMutex, rBHelper ) + ,m_sFileURL( ) + ,m_pFile( ) + ,m_eFileValidity( eUnknown ) + { + } + + //-------------------------------------------------------------------- + FileHandler::~FileHandler() + { + if ( !rBHelper.bDisposed ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + bool FileHandler::impl_prepareFile_nothrow() + { + if ( m_eFileValidity == eUnknown ) + { + m_pFile.reset( new ::osl::File( m_sFileURL ) ); + // check whether the log file already exists + ::osl::DirectoryItem aFileItem; + ::osl::DirectoryItem::get( m_sFileURL, aFileItem ); + ::osl::FileStatus aStatus( FileStatusMask_Validate ); + if ( ::osl::FileBase::E_None == aFileItem.getFileStatus( aStatus ) ) + ::osl::File::remove( m_sFileURL ); + + ::osl::FileBase::RC res = m_pFile->open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ); + m_eFileValidity = res == ::osl::FileBase::E_None + ? eValid + : eInvalid; + #if OSL_DEBUG_LEVEL > 0 + if ( m_eFileValidity == eInvalid ) + { + ::rtl::OStringBuffer sMessage; + sMessage.append( "FileHandler::impl_prepareFile_nothrow: could not open the designated log file:" ); + sMessage.append( "\nURL: " ); + sMessage.append( ::rtl::OString( m_sFileURL.getStr(), m_sFileURL.getLength(), osl_getThreadTextEncoding() ) ); + sMessage.append( "\nerror code: " ); + sMessage.append( (sal_Int32)res ); + OSL_ENSURE( false, sMessage.makeStringAndClear() ); + } + #endif + if ( m_eFileValidity == eValid ) + { + ::rtl::OString sHead; + if ( m_aHandlerHelper.getEncodedHead( sHead ) ) + impl_writeString_nothrow( sHead ); + } + } + + return m_eFileValidity == eValid; + } + + //-------------------------------------------------------------------- + void FileHandler::impl_writeString_nothrow( const ::rtl::OString& _rEntry ) + { + OSL_PRECOND( m_pFile.get(), "FileHandler::impl_writeString_nothrow: no file!" ); + + sal_uInt64 nBytesToWrite( _rEntry.getLength() ); + sal_uInt64 nBytesWritten( 0 ); + #if OSL_DEBUG_LEVEL > 0 + ::osl::FileBase::RC res = + #endif + m_pFile->write( _rEntry.getStr(), nBytesToWrite, nBytesWritten ); + OSL_ENSURE( ( res == ::osl::FileBase::E_None ) && ( nBytesWritten == nBytesToWrite ), + "FileHandler::impl_writeString_nothrow: could not write the log entry!" ); + } + + //-------------------------------------------------------------------- + void FileHandler::impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL ) + { + try + { + Reference< XStringSubstitution > xStringSubst; + if ( m_aContext.createComponent( "com.sun.star.util.PathSubstitution", xStringSubst ) ) + _inout_rURL = xStringSubst->substituteVariables( _inout_rURL, true ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::disposing() + { + if ( m_eFileValidity == eValid ) + { + ::rtl::OString sTail; + if ( m_aHandlerHelper.getEncodedTail( sTail ) ) + impl_writeString_nothrow( sTail ); + } + + m_pFile.reset( NULL ); + m_aHandlerHelper.setFormatter( NULL ); + } + + //-------------------------------------------------------------------- + void FileHandler::enterMethod( MethodGuard::Access ) + { + m_aHandlerHelper.enterMethod(); + } + + //-------------------------------------------------------------------- + void FileHandler::leaveMethod( MethodGuard::Access ) + { + m_aMutex.release(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL FileHandler::getEncoding() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + ::rtl::OUString sEncoding; + OSL_VERIFY( m_aHandlerHelper.getEncoding( sEncoding ) ); + return sEncoding; + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::setEncoding( const ::rtl::OUString& _rEncoding ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + OSL_VERIFY( m_aHandlerHelper.setEncoding( _rEncoding ) ); + } + + //-------------------------------------------------------------------- + Reference< XLogFormatter > SAL_CALL FileHandler::getFormatter() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_aHandlerHelper.getFormatter(); + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::setFormatter( const Reference< XLogFormatter >& _rxFormatter ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aHandlerHelper.setFormatter( _rxFormatter ); + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL FileHandler::getLevel() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_aHandlerHelper.getLevel(); + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::setLevel( ::sal_Int32 _nLevel ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aHandlerHelper.setLevel( _nLevel ); + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::flush( ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + // nothing to do, our ::osl::File implementation is not buffered + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL FileHandler::publish( const LogRecord& _rRecord ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + + if ( !impl_prepareFile_nothrow() ) + return sal_False; + + ::rtl::OString sEntry; + if ( !m_aHandlerHelper.formatForPublishing( _rRecord, sEntry ) ) + return sal_False; + + impl_writeString_nothrow( sEntry ); + return sal_True; + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_aHandlerHelper.getIsInitialized() ) + throw AlreadyInitializedException(); + + if ( _rArguments.getLength() != 1 ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + Sequence< NamedValue > aSettings; + if ( _rArguments[0] >>= m_sFileURL ) + { + // create( [in] string URL ); + impl_doStringsubstitution_nothrow( m_sFileURL ); + } + else if ( _rArguments[0] >>= aSettings ) + { + // createWithSettings( [in] sequence< ::com::sun::star::beans::NamedValue > Settings ) + ::comphelper::NamedValueCollection aTypedSettings( aSettings ); + m_aHandlerHelper.initFromSettings( aTypedSettings ); + + if ( aTypedSettings.get_ensureType( "FileURL", m_sFileURL ) ) + impl_doStringsubstitution_nothrow( m_sFileURL ); + } + else + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + m_aHandlerHelper.setIsInitialized(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL FileHandler::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL FileHandler::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) + { + const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() ); + for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); + pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); + ++pServiceNames + ) + if ( _rServiceName == *pServiceNames ) + return sal_True; + return sal_False; + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL FileHandler::getImplementationName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FileHandler" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames_static() + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.FileHandler" ) ); + return aServiceNames; + } + + //-------------------------------------------------------------------- + Reference< XInterface > FileHandler::Create( const Reference< XComponentContext >& _rxContext ) + { + return *( new FileHandler( _rxContext ) ); + } + + //-------------------------------------------------------------------- + void createRegistryInfo_FileHandler() + { + static OAutoRegistration< FileHandler > aAutoRegistration; + } + +//........................................................................ +} // namespace logging +//........................................................................ -- cgit