update dev300-m58
[ooovba.git] / extensions / source / logging / filehandler.cxx
blob00d9bd5a86ab312b9d2b54b916e66d248de8ab5a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: filehandler.cxx,v $
10 * $Revision: 1.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "log_module.hxx"
35 #include "methodguard.hxx"
36 #include "loghandler.hxx"
38 /** === begin UNO includes === **/
39 #include <com/sun/star/logging/XLogHandler.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
42 #include <com/sun/star/lang/XInitialization.hpp>
43 #include <com/sun/star/lang/IllegalArgumentException.hpp>
44 #include <com/sun/star/util/XStringSubstitution.hpp>
45 /** === end UNO includes === **/
47 #include <tools/diagnose_ex.h>
49 #include <comphelper/componentcontext.hxx>
51 #include <cppuhelper/compbase3.hxx>
52 #include <cppuhelper/basemutex.hxx>
54 #include <osl/thread.h>
55 #include <osl/file.hxx>
57 #include <rtl/strbuf.hxx>
59 #include <memory>
61 //........................................................................
62 namespace logging
64 //........................................................................
66 /** === begin UNO using === **/
67 using ::com::sun::star::uno::Reference;
68 using ::com::sun::star::logging::LogRecord;
69 using ::com::sun::star::uno::RuntimeException;
70 using ::com::sun::star::logging::XLogFormatter;
71 using ::com::sun::star::uno::Sequence;
72 using ::com::sun::star::uno::XInterface;
73 using ::com::sun::star::uno::XComponentContext;
74 using ::com::sun::star::logging::XLogHandler;
75 using ::com::sun::star::lang::XServiceInfo;
76 using ::com::sun::star::ucb::AlreadyInitializedException;
77 using ::com::sun::star::lang::XInitialization;
78 using ::com::sun::star::uno::Any;
79 using ::com::sun::star::uno::Exception;
80 using ::com::sun::star::lang::IllegalArgumentException;
81 using ::com::sun::star::uno::UNO_QUERY_THROW;
82 using ::com::sun::star::util::XStringSubstitution;
83 using ::com::sun::star::beans::NamedValue;
84 /** === end UNO using === **/
86 //====================================================================
87 //= FileHandler - declaration
88 //====================================================================
89 typedef ::cppu::WeakComponentImplHelper3 < XLogHandler
90 , XServiceInfo
91 , XInitialization
92 > FileHandler_Base;
93 class FileHandler :public ::cppu::BaseMutex
94 ,public FileHandler_Base
96 private:
97 enum FileValidity
99 /// never attempted to open the file
100 eUnknown,
101 /// file is valid
102 eValid,
103 /// file is invalid
104 eInvalid
107 private:
108 ::comphelper::ComponentContext m_aContext;
109 LogHandlerHelper m_aHandlerHelper;
110 ::rtl::OUString m_sFileURL;
111 ::std::auto_ptr< ::osl::File > m_pFile;
112 FileValidity m_eFileValidity;
114 protected:
115 FileHandler( const Reference< XComponentContext >& _rxContext );
116 virtual ~FileHandler();
118 // XLogHandler
119 virtual ::rtl::OUString SAL_CALL getEncoding() throw (RuntimeException);
120 virtual void SAL_CALL setEncoding( const ::rtl::OUString& _encoding ) throw (RuntimeException);
121 virtual Reference< XLogFormatter > SAL_CALL getFormatter() throw (RuntimeException);
122 virtual void SAL_CALL setFormatter( const Reference< XLogFormatter >& _formatter ) throw (RuntimeException);
123 virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException);
124 virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException);
125 virtual void SAL_CALL flush( ) throw (RuntimeException);
126 virtual ::sal_Bool SAL_CALL publish( const LogRecord& Record ) throw (RuntimeException);
128 // XInitialization
129 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);
131 // XServiceInfo
132 virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
133 virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException);
134 virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
136 // OComponentHelper
137 virtual void SAL_CALL disposing();
139 public:
140 // XServiceInfo - static version
141 static ::rtl::OUString SAL_CALL getImplementationName_static();
142 static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static();
143 static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext );
145 public:
146 typedef ComponentMethodGuard< FileHandler > MethodGuard;
147 void enterMethod( MethodGuard::Access );
148 void leaveMethod( MethodGuard::Access );
150 private:
151 /** prepares our output file for writing
153 bool impl_prepareFile_nothrow();
155 /// writes the given string to our file
156 void impl_writeString_nothrow( const ::rtl::OString& _rEntry );
158 /** does string substitution on a (usually externally provided) file url
160 void impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL );
163 //====================================================================
164 //= FileHandler - implementation
165 //====================================================================
166 //--------------------------------------------------------------------
167 FileHandler::FileHandler( const Reference< XComponentContext >& _rxContext )
168 :FileHandler_Base( m_aMutex )
169 ,m_aContext( _rxContext )
170 ,m_aHandlerHelper( _rxContext, m_aMutex, rBHelper )
171 ,m_sFileURL( )
172 ,m_pFile( )
173 ,m_eFileValidity( eUnknown )
177 //--------------------------------------------------------------------
178 FileHandler::~FileHandler()
180 if ( !rBHelper.bDisposed )
182 acquire();
183 dispose();
187 //--------------------------------------------------------------------
188 bool FileHandler::impl_prepareFile_nothrow()
190 if ( m_eFileValidity == eUnknown )
192 m_pFile.reset( new ::osl::File( m_sFileURL ) );
193 // check whether the log file already exists
194 ::osl::DirectoryItem aFileItem;
195 ::osl::DirectoryItem::get( m_sFileURL, aFileItem );
196 ::osl::FileStatus aStatus( FileStatusMask_Validate );
197 if ( ::osl::FileBase::E_None == aFileItem.getFileStatus( aStatus ) )
198 ::osl::File::remove( m_sFileURL );
200 ::osl::FileBase::RC res = m_pFile->open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
201 m_eFileValidity = res == ::osl::FileBase::E_None
202 ? eValid
203 : eInvalid;
204 #if OSL_DEBUG_LEVEL > 0
205 if ( m_eFileValidity == eInvalid )
207 ::rtl::OStringBuffer sMessage;
208 sMessage.append( "FileHandler::impl_prepareFile_nothrow: could not open the designated log file:" );
209 sMessage.append( "\nURL: " );
210 sMessage.append( ::rtl::OString( m_sFileURL.getStr(), m_sFileURL.getLength(), osl_getThreadTextEncoding() ) );
211 sMessage.append( "\nerror code: " );
212 sMessage.append( (sal_Int32)res );
213 OSL_ENSURE( false, sMessage.makeStringAndClear() );
215 #endif
216 if ( m_eFileValidity == eValid )
218 ::rtl::OString sHead;
219 if ( m_aHandlerHelper.getEncodedHead( sHead ) )
220 impl_writeString_nothrow( sHead );
224 return m_eFileValidity == eValid;
227 //--------------------------------------------------------------------
228 void FileHandler::impl_writeString_nothrow( const ::rtl::OString& _rEntry )
230 OSL_PRECOND( m_pFile.get(), "FileHandler::impl_writeString_nothrow: no file!" );
232 sal_uInt64 nBytesToWrite( _rEntry.getLength() );
233 sal_uInt64 nBytesWritten( 0 );
234 #if OSL_DEBUG_LEVEL > 0
235 ::osl::FileBase::RC res =
236 #endif
237 m_pFile->write( _rEntry.getStr(), nBytesToWrite, nBytesWritten );
238 OSL_ENSURE( ( res == ::osl::FileBase::E_None ) && ( nBytesWritten == nBytesToWrite ),
239 "FileHandler::impl_writeString_nothrow: could not write the log entry!" );
242 //--------------------------------------------------------------------
243 void FileHandler::impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL )
247 Reference< XStringSubstitution > xStringSubst;
248 if ( m_aContext.createComponent( "com.sun.star.util.PathSubstitution", xStringSubst ) )
249 _inout_rURL = xStringSubst->substituteVariables( _inout_rURL, true );
251 catch( const Exception& )
253 DBG_UNHANDLED_EXCEPTION();
257 //--------------------------------------------------------------------
258 void SAL_CALL FileHandler::disposing()
260 if ( m_eFileValidity == eValid )
262 ::rtl::OString sTail;
263 if ( m_aHandlerHelper.getEncodedTail( sTail ) )
264 impl_writeString_nothrow( sTail );
267 m_pFile.reset( NULL );
268 m_aHandlerHelper.setFormatter( NULL );
271 //--------------------------------------------------------------------
272 void FileHandler::enterMethod( MethodGuard::Access )
274 m_aHandlerHelper.enterMethod();
277 //--------------------------------------------------------------------
278 void FileHandler::leaveMethod( MethodGuard::Access )
280 m_aMutex.release();
283 //--------------------------------------------------------------------
284 ::rtl::OUString SAL_CALL FileHandler::getEncoding() throw (RuntimeException)
286 MethodGuard aGuard( *this );
287 ::rtl::OUString sEncoding;
288 OSL_VERIFY( m_aHandlerHelper.getEncoding( sEncoding ) );
289 return sEncoding;
292 //--------------------------------------------------------------------
293 void SAL_CALL FileHandler::setEncoding( const ::rtl::OUString& _rEncoding ) throw (RuntimeException)
295 MethodGuard aGuard( *this );
296 OSL_VERIFY( m_aHandlerHelper.setEncoding( _rEncoding ) );
299 //--------------------------------------------------------------------
300 Reference< XLogFormatter > SAL_CALL FileHandler::getFormatter() throw (RuntimeException)
302 MethodGuard aGuard( *this );
303 return m_aHandlerHelper.getFormatter();
306 //--------------------------------------------------------------------
307 void SAL_CALL FileHandler::setFormatter( const Reference< XLogFormatter >& _rxFormatter ) throw (RuntimeException)
309 MethodGuard aGuard( *this );
310 m_aHandlerHelper.setFormatter( _rxFormatter );
313 //--------------------------------------------------------------------
314 ::sal_Int32 SAL_CALL FileHandler::getLevel() throw (RuntimeException)
316 MethodGuard aGuard( *this );
317 return m_aHandlerHelper.getLevel();
320 //--------------------------------------------------------------------
321 void SAL_CALL FileHandler::setLevel( ::sal_Int32 _nLevel ) throw (RuntimeException)
323 MethodGuard aGuard( *this );
324 m_aHandlerHelper.setLevel( _nLevel );
327 //--------------------------------------------------------------------
328 void SAL_CALL FileHandler::flush( ) throw (RuntimeException)
330 MethodGuard aGuard( *this );
331 // nothing to do, our ::osl::File implementation is not buffered
334 //--------------------------------------------------------------------
335 ::sal_Bool SAL_CALL FileHandler::publish( const LogRecord& _rRecord ) throw (RuntimeException)
337 MethodGuard aGuard( *this );
339 if ( !impl_prepareFile_nothrow() )
340 return sal_False;
342 ::rtl::OString sEntry;
343 if ( !m_aHandlerHelper.formatForPublishing( _rRecord, sEntry ) )
344 return sal_False;
346 impl_writeString_nothrow( sEntry );
347 return sal_True;
350 //--------------------------------------------------------------------
351 void SAL_CALL FileHandler::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
353 ::osl::MutexGuard aGuard( m_aMutex );
355 if ( m_aHandlerHelper.getIsInitialized() )
356 throw AlreadyInitializedException();
358 if ( _rArguments.getLength() != 1 )
359 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
361 Sequence< NamedValue > aSettings;
362 if ( _rArguments[0] >>= m_sFileURL )
364 // create( [in] string URL );
365 impl_doStringsubstitution_nothrow( m_sFileURL );
367 else if ( _rArguments[0] >>= aSettings )
369 // createWithSettings( [in] sequence< ::com::sun::star::beans::NamedValue > Settings )
370 ::comphelper::NamedValueCollection aTypedSettings( aSettings );
371 m_aHandlerHelper.initFromSettings( aTypedSettings );
373 if ( aTypedSettings.get_ensureType( "FileURL", m_sFileURL ) )
374 impl_doStringsubstitution_nothrow( m_sFileURL );
376 else
377 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
379 m_aHandlerHelper.setIsInitialized();
382 //--------------------------------------------------------------------
383 ::rtl::OUString SAL_CALL FileHandler::getImplementationName() throw(RuntimeException)
385 return getImplementationName_static();
388 //--------------------------------------------------------------------
389 ::sal_Bool SAL_CALL FileHandler::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
391 const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() );
392 for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray();
393 pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength();
394 ++pServiceNames
396 if ( _rServiceName == *pServiceNames )
397 return sal_True;
398 return sal_False;
401 //--------------------------------------------------------------------
402 Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames() throw(RuntimeException)
404 return getSupportedServiceNames_static();
407 //--------------------------------------------------------------------
408 ::rtl::OUString SAL_CALL FileHandler::getImplementationName_static()
410 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FileHandler" ) );
413 //--------------------------------------------------------------------
414 Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames_static()
416 Sequence< ::rtl::OUString > aServiceNames(1);
417 aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.FileHandler" ) );
418 return aServiceNames;
421 //--------------------------------------------------------------------
422 Reference< XInterface > FileHandler::Create( const Reference< XComponentContext >& _rxContext )
424 return *( new FileHandler( _rxContext ) );
427 //--------------------------------------------------------------------
428 void createRegistryInfo_FileHandler()
430 static OAutoRegistration< FileHandler > aAutoRegistration;
433 //........................................................................
434 } // namespace logging
435 //........................................................................