Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "log_module.hxx"
31 : : #include "methodguard.hxx"
32 : : #include "loghandler.hxx"
33 : :
34 : : #include <com/sun/star/logging/XLogHandler.hpp>
35 : : #include <com/sun/star/lang/XServiceInfo.hpp>
36 : : #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
37 : : #include <com/sun/star/lang/XInitialization.hpp>
38 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
39 : : #include <com/sun/star/util/PathSubstitution.hpp>
40 : : #include <com/sun/star/util/XStringSubstitution.hpp>
41 : :
42 : : #include <tools/diagnose_ex.h>
43 : :
44 : : #include <comphelper/componentcontext.hxx>
45 : :
46 : : #include <cppuhelper/compbase3.hxx>
47 : : #include <cppuhelper/basemutex.hxx>
48 : :
49 : : #include <osl/thread.h>
50 : : #include <osl/file.hxx>
51 : :
52 : : #include <rtl/strbuf.hxx>
53 : :
54 : : #include <memory>
55 : :
56 : : //........................................................................
57 : : namespace logging
58 : : {
59 : : //........................................................................
60 : :
61 : : /** === begin UNO using === **/
62 : : using ::com::sun::star::uno::Reference;
63 : : using ::com::sun::star::logging::LogRecord;
64 : : using ::com::sun::star::uno::RuntimeException;
65 : : using ::com::sun::star::logging::XLogFormatter;
66 : : using ::com::sun::star::uno::Sequence;
67 : : using ::com::sun::star::uno::XInterface;
68 : : using ::com::sun::star::uno::XComponentContext;
69 : : using ::com::sun::star::logging::XLogHandler;
70 : : using ::com::sun::star::lang::XServiceInfo;
71 : : using ::com::sun::star::ucb::AlreadyInitializedException;
72 : : using ::com::sun::star::lang::XInitialization;
73 : : using ::com::sun::star::uno::Any;
74 : : using ::com::sun::star::uno::Exception;
75 : : using ::com::sun::star::lang::IllegalArgumentException;
76 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
77 : : using ::com::sun::star::util::PathSubstitution;
78 : : using ::com::sun::star::util::XStringSubstitution;
79 : : using ::com::sun::star::beans::NamedValue;
80 : : /** === end UNO using === **/
81 : :
82 : : //====================================================================
83 : : //= FileHandler - declaration
84 : : //====================================================================
85 : : typedef ::cppu::WeakComponentImplHelper3 < XLogHandler
86 : : , XServiceInfo
87 : : , XInitialization
88 : : > FileHandler_Base;
89 : : class FileHandler :public ::cppu::BaseMutex
90 : : ,public FileHandler_Base
91 : : {
92 : : private:
93 : : enum FileValidity
94 : : {
95 : : /// never attempted to open the file
96 : : eUnknown,
97 : : /// file is valid
98 : : eValid,
99 : : /// file is invalid
100 : : eInvalid
101 : : };
102 : :
103 : : private:
104 : : ::comphelper::ComponentContext m_aContext;
105 : : LogHandlerHelper m_aHandlerHelper;
106 : : ::rtl::OUString m_sFileURL;
107 : : ::std::auto_ptr< ::osl::File > m_pFile;
108 : : FileValidity m_eFileValidity;
109 : :
110 : : protected:
111 : : FileHandler( const Reference< XComponentContext >& _rxContext );
112 : : virtual ~FileHandler();
113 : :
114 : : // XLogHandler
115 : : virtual ::rtl::OUString SAL_CALL getEncoding() throw (RuntimeException);
116 : : virtual void SAL_CALL setEncoding( const ::rtl::OUString& _encoding ) throw (RuntimeException);
117 : : virtual Reference< XLogFormatter > SAL_CALL getFormatter() throw (RuntimeException);
118 : : virtual void SAL_CALL setFormatter( const Reference< XLogFormatter >& _formatter ) throw (RuntimeException);
119 : : virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException);
120 : : virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException);
121 : : virtual void SAL_CALL flush( ) throw (RuntimeException);
122 : : virtual ::sal_Bool SAL_CALL publish( const LogRecord& Record ) throw (RuntimeException);
123 : :
124 : : // XInitialization
125 : : 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);
126 : :
127 : : // XServiceInfo
128 : : virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
129 : : virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException);
130 : : virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
131 : :
132 : : // OComponentHelper
133 : : virtual void SAL_CALL disposing();
134 : :
135 : : public:
136 : : // XServiceInfo - static version
137 : : static ::rtl::OUString SAL_CALL getImplementationName_static();
138 : : static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static();
139 : : static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext );
140 : :
141 : : public:
142 : : typedef ComponentMethodGuard< FileHandler > MethodGuard;
143 : : void enterMethod( MethodGuard::Access );
144 : : void leaveMethod( MethodGuard::Access );
145 : :
146 : : private:
147 : : /** prepares our output file for writing
148 : : */
149 : : bool impl_prepareFile_nothrow();
150 : :
151 : : /// writes the given string to our file
152 : : void impl_writeString_nothrow( const ::rtl::OString& _rEntry );
153 : :
154 : : /** does string substitution on a (usually externally provided) file url
155 : : */
156 : : void impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL );
157 : : };
158 : :
159 : : //====================================================================
160 : : //= FileHandler - implementation
161 : : //====================================================================
162 : : //--------------------------------------------------------------------
163 : 9 : FileHandler::FileHandler( const Reference< XComponentContext >& _rxContext )
164 : : :FileHandler_Base( m_aMutex )
165 : : ,m_aContext( _rxContext )
166 : : ,m_aHandlerHelper( _rxContext, m_aMutex, rBHelper )
167 : : ,m_sFileURL( )
168 : : ,m_pFile( )
169 [ + - ][ + - ]: 9 : ,m_eFileValidity( eUnknown )
170 : : {
171 : 9 : }
172 : :
173 : : //--------------------------------------------------------------------
174 [ # # ][ # # ]: 0 : FileHandler::~FileHandler()
[ # # ][ # # ]
175 : : {
176 [ # # ]: 0 : if ( !rBHelper.bDisposed )
177 : : {
178 : 0 : acquire();
179 [ # # ]: 0 : dispose();
180 : : }
181 [ # # ]: 0 : }
182 : :
183 : : //--------------------------------------------------------------------
184 : 0 : bool FileHandler::impl_prepareFile_nothrow()
185 : : {
186 [ # # ]: 0 : if ( m_eFileValidity == eUnknown )
187 : : {
188 [ # # ]: 0 : m_pFile.reset( new ::osl::File( m_sFileURL ) );
189 : : // check whether the log file already exists
190 : 0 : ::osl::DirectoryItem aFileItem;
191 [ # # ]: 0 : ::osl::DirectoryItem::get( m_sFileURL, aFileItem );
192 : 0 : ::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
193 [ # # ][ # # ]: 0 : if ( ::osl::FileBase::E_None == aFileItem.getFileStatus( aStatus ) )
194 [ # # ]: 0 : ::osl::File::remove( m_sFileURL );
195 : :
196 [ # # ]: 0 : ::osl::FileBase::RC res = m_pFile->open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
197 : : m_eFileValidity = res == ::osl::FileBase::E_None
198 : : ? eValid
199 [ # # ]: 0 : : eInvalid;
200 : : #if OSL_DEBUG_LEVEL > 0
201 : : if ( m_eFileValidity == eInvalid )
202 : : {
203 : : ::rtl::OStringBuffer sMessage;
204 : : sMessage.append( "FileHandler::impl_prepareFile_nothrow: could not open the designated log file:" );
205 : : sMessage.append( "\nURL: " );
206 : : sMessage.append( ::rtl::OString( m_sFileURL.getStr(), m_sFileURL.getLength(), osl_getThreadTextEncoding() ) );
207 : : sMessage.append( "\nerror code: " );
208 : : sMessage.append( (sal_Int32)res );
209 : : OSL_FAIL( sMessage.makeStringAndClear().getStr() );
210 : : }
211 : : #endif
212 [ # # ]: 0 : if ( m_eFileValidity == eValid )
213 : : {
214 : 0 : ::rtl::OString sHead;
215 [ # # ][ # # ]: 0 : if ( m_aHandlerHelper.getEncodedHead( sHead ) )
216 [ # # ]: 0 : impl_writeString_nothrow( sHead );
217 [ # # ]: 0 : }
218 : : }
219 : :
220 : 0 : return m_eFileValidity == eValid;
221 : : }
222 : :
223 : : //--------------------------------------------------------------------
224 : 0 : void FileHandler::impl_writeString_nothrow( const ::rtl::OString& _rEntry )
225 : : {
226 : : OSL_PRECOND( m_pFile.get(), "FileHandler::impl_writeString_nothrow: no file!" );
227 : :
228 : 0 : sal_uInt64 nBytesToWrite( _rEntry.getLength() );
229 : 0 : sal_uInt64 nBytesWritten( 0 );
230 : : #if OSL_DEBUG_LEVEL > 0
231 : : ::osl::FileBase::RC res =
232 : : #endif
233 [ # # ]: 0 : m_pFile->write( _rEntry.getStr(), nBytesToWrite, nBytesWritten );
234 : : OSL_ENSURE( ( res == ::osl::FileBase::E_None ) && ( nBytesWritten == nBytesToWrite ),
235 : : "FileHandler::impl_writeString_nothrow: could not write the log entry!" );
236 : 0 : }
237 : :
238 : : //--------------------------------------------------------------------
239 : 9 : void FileHandler::impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL )
240 : : {
241 : : try
242 : : {
243 [ + - ][ + - ]: 9 : Reference< XStringSubstitution > xStringSubst(PathSubstitution::create(m_aContext.getUNOContext()));
244 [ + - ][ # # ]: 9 : _inout_rURL = xStringSubst->substituteVariables( _inout_rURL, true );
[ + - ]
245 : : }
246 : 0 : catch( const Exception& )
247 : : {
248 : : DBG_UNHANDLED_EXCEPTION();
249 : : }
250 : 9 : }
251 : :
252 : : //--------------------------------------------------------------------
253 : 0 : void SAL_CALL FileHandler::disposing()
254 : : {
255 [ # # ]: 0 : if ( m_eFileValidity == eValid )
256 : : {
257 : 0 : ::rtl::OString sTail;
258 [ # # ][ # # ]: 0 : if ( m_aHandlerHelper.getEncodedTail( sTail ) )
259 [ # # ]: 0 : impl_writeString_nothrow( sTail );
260 : : }
261 : :
262 : 0 : m_pFile.reset( NULL );
263 [ # # ]: 0 : m_aHandlerHelper.setFormatter( NULL );
264 : 0 : }
265 : :
266 : : //--------------------------------------------------------------------
267 : 18 : void FileHandler::enterMethod( MethodGuard::Access )
268 : : {
269 : 18 : m_aHandlerHelper.enterMethod();
270 : 18 : }
271 : :
272 : : //--------------------------------------------------------------------
273 : 18 : void FileHandler::leaveMethod( MethodGuard::Access )
274 : : {
275 : 18 : m_aMutex.release();
276 : 18 : }
277 : :
278 : : //--------------------------------------------------------------------
279 : 0 : ::rtl::OUString SAL_CALL FileHandler::getEncoding() throw (RuntimeException)
280 : : {
281 [ # # ]: 0 : MethodGuard aGuard( *this );
282 : 0 : ::rtl::OUString sEncoding;
283 [ # # ]: 0 : OSL_VERIFY( m_aHandlerHelper.getEncoding( sEncoding ) );
284 [ # # ]: 0 : return sEncoding;
285 : : }
286 : :
287 : : //--------------------------------------------------------------------
288 : 0 : void SAL_CALL FileHandler::setEncoding( const ::rtl::OUString& _rEncoding ) throw (RuntimeException)
289 : : {
290 [ # # ]: 0 : MethodGuard aGuard( *this );
291 [ # # ][ # # ]: 0 : OSL_VERIFY( m_aHandlerHelper.setEncoding( _rEncoding ) );
292 : 0 : }
293 : :
294 : : //--------------------------------------------------------------------
295 : 0 : Reference< XLogFormatter > SAL_CALL FileHandler::getFormatter() throw (RuntimeException)
296 : : {
297 [ # # ]: 0 : MethodGuard aGuard( *this );
298 [ # # ][ # # ]: 0 : return m_aHandlerHelper.getFormatter();
299 : : }
300 : :
301 : : //--------------------------------------------------------------------
302 : 9 : void SAL_CALL FileHandler::setFormatter( const Reference< XLogFormatter >& _rxFormatter ) throw (RuntimeException)
303 : : {
304 [ + - ]: 9 : MethodGuard aGuard( *this );
305 [ + - ][ + - ]: 9 : m_aHandlerHelper.setFormatter( _rxFormatter );
306 : 9 : }
307 : :
308 : : //--------------------------------------------------------------------
309 : 0 : ::sal_Int32 SAL_CALL FileHandler::getLevel() throw (RuntimeException)
310 : : {
311 [ # # ]: 0 : MethodGuard aGuard( *this );
312 [ # # ]: 0 : return m_aHandlerHelper.getLevel();
313 : : }
314 : :
315 : : //--------------------------------------------------------------------
316 : 9 : void SAL_CALL FileHandler::setLevel( ::sal_Int32 _nLevel ) throw (RuntimeException)
317 : : {
318 [ + - ]: 9 : MethodGuard aGuard( *this );
319 [ + - ]: 9 : m_aHandlerHelper.setLevel( _nLevel );
320 : 9 : }
321 : :
322 : : //--------------------------------------------------------------------
323 : 0 : void SAL_CALL FileHandler::flush( ) throw (RuntimeException)
324 : : {
325 [ # # ]: 0 : MethodGuard aGuard( *this );
326 [ # # ]: 0 : if(!m_pFile.get())
327 : : {
328 : : OSL_PRECOND(false, "FileHandler::flush: no file!");
329 : 0 : return;
330 : : }
331 : : #if OSL_DEBUG_LEVEL > 0
332 : : ::osl::FileBase::RC res =
333 : : #endif
334 [ # # ][ # # ]: 0 : m_pFile->sync();
335 [ # # ]: 0 : OSL_ENSURE(res == ::osl::FileBase::E_None, "FileHandler::flush: Could not sync logfile to filesystem.");
336 : : }
337 : :
338 : : //--------------------------------------------------------------------
339 : 0 : ::sal_Bool SAL_CALL FileHandler::publish( const LogRecord& _rRecord ) throw (RuntimeException)
340 : : {
341 [ # # ]: 0 : MethodGuard aGuard( *this );
342 : :
343 [ # # ][ # # ]: 0 : if ( !impl_prepareFile_nothrow() )
344 : 0 : return sal_False;
345 : :
346 : 0 : ::rtl::OString sEntry;
347 [ # # ][ # # ]: 0 : if ( !m_aHandlerHelper.formatForPublishing( _rRecord, sEntry ) )
348 : 0 : return sal_False;
349 : :
350 [ # # ]: 0 : impl_writeString_nothrow( sEntry );
351 [ # # ]: 0 : return sal_True;
352 : : }
353 : :
354 : : //--------------------------------------------------------------------
355 : 9 : void SAL_CALL FileHandler::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
356 : : {
357 [ + - ]: 9 : ::osl::MutexGuard aGuard( m_aMutex );
358 : :
359 [ - + ]: 9 : if ( m_aHandlerHelper.getIsInitialized() )
360 [ # # ]: 0 : throw AlreadyInitializedException();
361 : :
362 [ - + ]: 9 : if ( _rArguments.getLength() != 1 )
363 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
364 : :
365 [ + - ]: 9 : Sequence< NamedValue > aSettings;
366 [ - + ]: 9 : if ( _rArguments[0] >>= m_sFileURL )
367 : : {
368 : : // create( [in] string URL );
369 [ # # ]: 0 : impl_doStringsubstitution_nothrow( m_sFileURL );
370 : : }
371 [ + - ][ + - ]: 9 : else if ( _rArguments[0] >>= aSettings )
372 : : {
373 : : // createWithSettings( [in] sequence< ::com::sun::star::beans::NamedValue > Settings )
374 [ + - ]: 9 : ::comphelper::NamedValueCollection aTypedSettings( aSettings );
375 [ + - ]: 9 : m_aHandlerHelper.initFromSettings( aTypedSettings );
376 : :
377 [ + - ][ + - ]: 9 : if ( aTypedSettings.get_ensureType( "FileURL", m_sFileURL ) )
378 [ + - ][ + - ]: 9 : impl_doStringsubstitution_nothrow( m_sFileURL );
379 : : }
380 : : else
381 [ # # ][ # # ]: 0 : throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
382 : :
383 [ + - ][ + - ]: 9 : m_aHandlerHelper.setIsInitialized();
384 : 9 : }
385 : :
386 : : //--------------------------------------------------------------------
387 : 0 : ::rtl::OUString SAL_CALL FileHandler::getImplementationName() throw(RuntimeException)
388 : : {
389 : 0 : return getImplementationName_static();
390 : : }
391 : :
392 : : //--------------------------------------------------------------------
393 : 0 : ::sal_Bool SAL_CALL FileHandler::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
394 : : {
395 [ # # ]: 0 : const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() );
396 [ # # ]: 0 : for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray();
397 : 0 : pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength();
398 : : ++pServiceNames
399 : : )
400 [ # # ]: 0 : if ( _rServiceName == *pServiceNames )
401 : 0 : return sal_True;
402 [ # # ]: 0 : return sal_False;
403 : : }
404 : :
405 : : //--------------------------------------------------------------------
406 : 0 : Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames() throw(RuntimeException)
407 : : {
408 : 0 : return getSupportedServiceNames_static();
409 : : }
410 : :
411 : : //--------------------------------------------------------------------
412 : 9 : ::rtl::OUString SAL_CALL FileHandler::getImplementationName_static()
413 : : {
414 : 9 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FileHandler" ) );
415 : : }
416 : :
417 : : //--------------------------------------------------------------------
418 : 9 : Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames_static()
419 : : {
420 : 9 : Sequence< ::rtl::OUString > aServiceNames(1);
421 [ + - ][ + - ]: 9 : aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.FileHandler" ) );
422 : 9 : return aServiceNames;
423 : : }
424 : :
425 : : //--------------------------------------------------------------------
426 : 9 : Reference< XInterface > FileHandler::Create( const Reference< XComponentContext >& _rxContext )
427 : : {
428 [ + - ]: 9 : return *( new FileHandler( _rxContext ) );
429 : : }
430 : :
431 : : //--------------------------------------------------------------------
432 : 27 : void createRegistryInfo_FileHandler()
433 : : {
434 [ + + ][ + - ]: 27 : static OAutoRegistration< FileHandler > aAutoRegistration;
[ + - ][ # # ]
435 : 27 : }
436 : :
437 : : //........................................................................
438 : : } // namespace logging
439 : : //........................................................................
440 : :
441 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|