12a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
32a97ec55SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
42a97ec55SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
52a97ec55SAndrew Rist  * distributed with this work for additional information
62a97ec55SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
72a97ec55SAndrew Rist  * to you under the Apache License, Version 2.0 (the
82a97ec55SAndrew Rist  * "License"); you may not use this file except in compliance
92a97ec55SAndrew Rist  * with the License.  You may obtain a copy of the License at
102a97ec55SAndrew Rist  *
112a97ec55SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
122a97ec55SAndrew Rist  *
132a97ec55SAndrew Rist  * Unless required by applicable law or agreed to in writing,
142a97ec55SAndrew Rist  * software distributed under the License is distributed on an
152a97ec55SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162a97ec55SAndrew Rist  * KIND, either express or implied.  See the License for the
172a97ec55SAndrew Rist  * specific language governing permissions and limitations
182a97ec55SAndrew Rist  * under the License.
192a97ec55SAndrew Rist  *
202a97ec55SAndrew Rist  *************************************************************/
212a97ec55SAndrew Rist 
222a97ec55SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_extensions.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "loggerconfig.hxx"
28*197bf4dcSAriel Constenla-Haile #include <stdio.h>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir /** === begin UNO includes === **/
31cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
33cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
34cdf0e10cSrcweir #include <com/sun/star/util/XChangesBatch.hpp>
35cdf0e10cSrcweir #include <com/sun/star/logging/LogLevel.hpp>
36cdf0e10cSrcweir #include <com/sun/star/lang/NullPointerException.hpp>
37cdf0e10cSrcweir #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
38cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
39cdf0e10cSrcweir #include <com/sun/star/logging/XLogHandler.hpp>
40cdf0e10cSrcweir #include <com/sun/star/logging/XLogFormatter.hpp>
41cdf0e10cSrcweir /** === end UNO includes === **/
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <tools/diagnose_ex.h>
44*197bf4dcSAriel Constenla-Haile #include <osl/process.h>
45*197bf4dcSAriel Constenla-Haile #include <rtl/ustrbuf.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include <comphelper/componentcontext.hxx>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #include <cppuhelper/component_context.hxx>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #include <vector>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir //........................................................................
54cdf0e10cSrcweir namespace logging
55cdf0e10cSrcweir {
56cdf0e10cSrcweir //........................................................................
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 	/** === begin UNO using === **/
59cdf0e10cSrcweir     using ::com::sun::star::uno::Reference;
60cdf0e10cSrcweir     using ::com::sun::star::logging::XLogger;
61cdf0e10cSrcweir     using ::com::sun::star::lang::XMultiServiceFactory;
62cdf0e10cSrcweir     using ::com::sun::star::uno::Sequence;
63cdf0e10cSrcweir     using ::com::sun::star::uno::Any;
64cdf0e10cSrcweir     using ::com::sun::star::container::XNameContainer;
65cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_QUERY_THROW;
66cdf0e10cSrcweir     using ::com::sun::star::lang::XSingleServiceFactory;
67cdf0e10cSrcweir     using ::com::sun::star::uno::XInterface;
68cdf0e10cSrcweir     using ::com::sun::star::util::XChangesBatch;
69cdf0e10cSrcweir     using ::com::sun::star::uno::makeAny;
70cdf0e10cSrcweir     using ::com::sun::star::lang::NullPointerException;
71cdf0e10cSrcweir     using ::com::sun::star::uno::Exception;
72cdf0e10cSrcweir     using ::com::sun::star::lang::ServiceNotRegisteredException;
73cdf0e10cSrcweir     using ::com::sun::star::beans::NamedValue;
74cdf0e10cSrcweir     using ::com::sun::star::logging::XLogHandler;
75cdf0e10cSrcweir     using ::com::sun::star::logging::XLogFormatter;
76cdf0e10cSrcweir     using ::com::sun::star::container::XNameAccess;
77cdf0e10cSrcweir     using ::com::sun::star::uno::XComponentContext;
78cdf0e10cSrcweir 	/** === end UNO using === **/
79cdf0e10cSrcweir     namespace LogLevel = ::com::sun::star::logging::LogLevel;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     namespace
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir 	    //----------------------------------------------------------------
84cdf0e10cSrcweir         typedef void (*SettingTranslation)( const Reference< XLogger >&, const ::rtl::OUString&, Any& );
85cdf0e10cSrcweir 
86cdf0e10cSrcweir         //----------------------------------------------------------------
lcl_substituteFileHandlerURLVariables_nothrow(const Reference<XLogger> & _rxLogger,::rtl::OUString & _inout_rFileURL)87cdf0e10cSrcweir         void    lcl_substituteFileHandlerURLVariables_nothrow( const Reference< XLogger >& _rxLogger, ::rtl::OUString& _inout_rFileURL )
88cdf0e10cSrcweir         {
89cdf0e10cSrcweir             struct Variable
90cdf0e10cSrcweir             {
91cdf0e10cSrcweir                 const sal_Char*         pVariablePattern;
92cdf0e10cSrcweir                 const sal_Int32         nPatternLength;
93cdf0e10cSrcweir                 rtl_TextEncoding        eEncoding;
94cdf0e10cSrcweir                 const ::rtl::OUString   sVariableValue;
95cdf0e10cSrcweir 
96cdf0e10cSrcweir                 Variable( const sal_Char* _pVariablePattern,  const sal_Int32 _nPatternLength, rtl_TextEncoding _eEncoding,
97cdf0e10cSrcweir                         const ::rtl::OUString& _rVariableValue )
98cdf0e10cSrcweir                     :pVariablePattern( _pVariablePattern )
99cdf0e10cSrcweir                     ,nPatternLength( _nPatternLength )
100cdf0e10cSrcweir                     ,eEncoding( _eEncoding )
101cdf0e10cSrcweir                     ,sVariableValue( _rVariableValue )
102cdf0e10cSrcweir                 {
103cdf0e10cSrcweir                 }
104cdf0e10cSrcweir             };
105cdf0e10cSrcweir 
106cdf0e10cSrcweir             ::rtl::OUString sLoggerName;
107cdf0e10cSrcweir             try { sLoggerName = _rxLogger->getName(); }
108cdf0e10cSrcweir             catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
109cdf0e10cSrcweir 
110*197bf4dcSAriel Constenla-Haile             TimeValue aTimeValue;
111*197bf4dcSAriel Constenla-Haile             oslDateTime aDateTime;
112*197bf4dcSAriel Constenla-Haile             OSL_VERIFY( osl_getSystemTime( &aTimeValue ) );
113*197bf4dcSAriel Constenla-Haile             OSL_VERIFY( osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime ) );
114*197bf4dcSAriel Constenla-Haile 
115*197bf4dcSAriel Constenla-Haile             char buffer[ 30 ];
116*197bf4dcSAriel Constenla-Haile             const size_t buffer_size = sizeof( buffer );
117*197bf4dcSAriel Constenla-Haile 
118*197bf4dcSAriel Constenla-Haile             snprintf( buffer, buffer_size, "%04i-%02i-%02i",
119*197bf4dcSAriel Constenla-Haile                       (int)aDateTime.Year,
120*197bf4dcSAriel Constenla-Haile                       (int)aDateTime.Month,
121*197bf4dcSAriel Constenla-Haile                       (int)aDateTime.Day );
122*197bf4dcSAriel Constenla-Haile             rtl::OUString sDate = rtl::OUString::createFromAscii( buffer );
123*197bf4dcSAriel Constenla-Haile 
124*197bf4dcSAriel Constenla-Haile             snprintf( buffer, buffer_size, "%02i-%02i-%02i.%03i",
125*197bf4dcSAriel Constenla-Haile                 (int)aDateTime.Hours,
126*197bf4dcSAriel Constenla-Haile                 (int)aDateTime.Minutes,
127*197bf4dcSAriel Constenla-Haile                 (int)aDateTime.Seconds,
128*197bf4dcSAriel Constenla-Haile                 ::sal::static_int_cast< sal_Int16 >( aDateTime.NanoSeconds / 10000000 ) );
129*197bf4dcSAriel Constenla-Haile             rtl::OUString sTime = rtl::OUString::createFromAscii( buffer );
130*197bf4dcSAriel Constenla-Haile 
131*197bf4dcSAriel Constenla-Haile             rtl::OUStringBuffer aBuff;
132*197bf4dcSAriel Constenla-Haile             aBuff.append( sDate );
133*197bf4dcSAriel Constenla-Haile             aBuff.append( sal_Unicode( '.' ) );
134*197bf4dcSAriel Constenla-Haile             aBuff.append( sTime );
135*197bf4dcSAriel Constenla-Haile             rtl::OUString sDateTime = aBuff.makeStringAndClear();
136*197bf4dcSAriel Constenla-Haile 
137*197bf4dcSAriel Constenla-Haile             oslProcessIdentifier aProcessId = 0;
138*197bf4dcSAriel Constenla-Haile             oslProcessInfo info;
139*197bf4dcSAriel Constenla-Haile             info.Size = sizeof (oslProcessInfo);
140*197bf4dcSAriel Constenla-Haile             if ( osl_getProcessInfo ( 0, osl_Process_IDENTIFIER, &info ) == osl_Process_E_None)
141*197bf4dcSAriel Constenla-Haile                 aProcessId = info.Ident;
142*197bf4dcSAriel Constenla-Haile             rtl::OUString aPID = rtl::OUString::valueOf( sal_Int64( aProcessId ) );
143*197bf4dcSAriel Constenla-Haile 
144cdf0e10cSrcweir             Variable aVariables[] =
145cdf0e10cSrcweir             {
146*197bf4dcSAriel Constenla-Haile                 Variable( RTL_CONSTASCII_USTRINGPARAM( "$(loggername)" ), sLoggerName ),
147*197bf4dcSAriel Constenla-Haile                 Variable( RTL_CONSTASCII_USTRINGPARAM( "$(date)" ), sDate ),
148*197bf4dcSAriel Constenla-Haile                 Variable( RTL_CONSTASCII_USTRINGPARAM( "$(time)" ), sTime ),
149*197bf4dcSAriel Constenla-Haile                 Variable( RTL_CONSTASCII_USTRINGPARAM( "$(datetime)" ), sDateTime ),
150*197bf4dcSAriel Constenla-Haile                 Variable( RTL_CONSTASCII_USTRINGPARAM( "$(pid)" ), aPID )
151cdf0e10cSrcweir             };
152cdf0e10cSrcweir 
153cdf0e10cSrcweir             for ( size_t i = 0; i < sizeof( aVariables ) / sizeof( aVariables[0] ); ++i )
154cdf0e10cSrcweir             {
155cdf0e10cSrcweir                 ::rtl::OUString sPattern( aVariables[i].pVariablePattern, aVariables[i].nPatternLength, aVariables[i].eEncoding );
156cdf0e10cSrcweir                 sal_Int32 nVariableIndex = _inout_rFileURL.indexOf( sPattern );
157cdf0e10cSrcweir                 if  (   ( nVariableIndex == 0 )
158cdf0e10cSrcweir                     ||  (   ( nVariableIndex > 0 )
159cdf0e10cSrcweir                         &&  ( sPattern[ nVariableIndex - 1 ] != '$' )
160cdf0e10cSrcweir                         )
161cdf0e10cSrcweir                     )
162cdf0e10cSrcweir                 {
163cdf0e10cSrcweir                     // found an (unescaped) variable
164cdf0e10cSrcweir                     _inout_rFileURL = _inout_rFileURL.replaceAt( nVariableIndex, sPattern.getLength(), aVariables[i].sVariableValue );
165cdf0e10cSrcweir                 }
166cdf0e10cSrcweir             }
167cdf0e10cSrcweir         }
168cdf0e10cSrcweir 
169cdf0e10cSrcweir         //----------------------------------------------------------------
lcl_transformFileHandlerSettings_nothrow(const Reference<XLogger> & _rxLogger,const::rtl::OUString & _rSettingName,Any & _inout_rSettingValue)170cdf0e10cSrcweir         void    lcl_transformFileHandlerSettings_nothrow( const Reference< XLogger >& _rxLogger, const ::rtl::OUString& _rSettingName, Any& _inout_rSettingValue )
171cdf0e10cSrcweir         {
172cdf0e10cSrcweir             if ( !_rSettingName.equalsAscii( "FileURL" ) )
173cdf0e10cSrcweir                 // not interested in this setting
174cdf0e10cSrcweir                 return;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir             ::rtl::OUString sURL;
177cdf0e10cSrcweir             OSL_VERIFY( _inout_rSettingValue >>= sURL );
178cdf0e10cSrcweir             lcl_substituteFileHandlerURLVariables_nothrow( _rxLogger, sURL );
179cdf0e10cSrcweir             _inout_rSettingValue <<= sURL;
180cdf0e10cSrcweir         }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 	    //----------------------------------------------------------------
lcl_createInstanceFromSetting_throw(const::comphelper::ComponentContext & _rContext,const Reference<XLogger> & _rxLogger,const Reference<XNameAccess> & _rxLoggerSettings,const sal_Char * _pServiceNameAsciiNodeName,const sal_Char * _pServiceSettingsAsciiNodeName,SettingTranslation _pSettingTranslation=NULL)183cdf0e10cSrcweir         Reference< XInterface > lcl_createInstanceFromSetting_throw(
184cdf0e10cSrcweir                 const ::comphelper::ComponentContext& _rContext,
185cdf0e10cSrcweir                 const Reference< XLogger >& _rxLogger,
186cdf0e10cSrcweir                 const Reference< XNameAccess >& _rxLoggerSettings,
187cdf0e10cSrcweir                 const sal_Char* _pServiceNameAsciiNodeName,
188cdf0e10cSrcweir                 const sal_Char* _pServiceSettingsAsciiNodeName,
189cdf0e10cSrcweir                 SettingTranslation _pSettingTranslation = NULL
190cdf0e10cSrcweir             )
191cdf0e10cSrcweir         {
192cdf0e10cSrcweir             Reference< XInterface > xInstance;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir             // read the settings for the to-be-created service
195cdf0e10cSrcweir             Reference< XNameAccess > xServiceSettingsNode( _rxLoggerSettings->getByName(
196cdf0e10cSrcweir                 ::rtl::OUString::createFromAscii( _pServiceSettingsAsciiNodeName ) ), UNO_QUERY_THROW );
197cdf0e10cSrcweir 
198cdf0e10cSrcweir             Sequence< ::rtl::OUString > aSettingNames( xServiceSettingsNode->getElementNames() );
199cdf0e10cSrcweir             size_t nServiceSettingCount( aSettingNames.getLength() );
200cdf0e10cSrcweir             Sequence< NamedValue > aSettings( nServiceSettingCount );
201cdf0e10cSrcweir             if ( nServiceSettingCount )
202cdf0e10cSrcweir             {
203cdf0e10cSrcweir                 const ::rtl::OUString* pSettingNames = aSettingNames.getConstArray();
204cdf0e10cSrcweir                 const ::rtl::OUString* pSettingNamesEnd = aSettingNames.getConstArray() + aSettingNames.getLength();
205cdf0e10cSrcweir                 NamedValue* pSetting = aSettings.getArray();
206cdf0e10cSrcweir 
207cdf0e10cSrcweir                 for (   ;
208cdf0e10cSrcweir                         pSettingNames != pSettingNamesEnd;
209cdf0e10cSrcweir                         ++pSettingNames, ++pSetting
210cdf0e10cSrcweir                     )
211cdf0e10cSrcweir                 {
212cdf0e10cSrcweir                     pSetting->Name = *pSettingNames;
213cdf0e10cSrcweir                     pSetting->Value = xServiceSettingsNode->getByName( *pSettingNames );
214cdf0e10cSrcweir 
215cdf0e10cSrcweir                     if ( _pSettingTranslation )
216cdf0e10cSrcweir                         (_pSettingTranslation)( _rxLogger, pSetting->Name, pSetting->Value );
217cdf0e10cSrcweir                 }
218cdf0e10cSrcweir             }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir             ::rtl::OUString sServiceName;
221cdf0e10cSrcweir             _rxLoggerSettings->getByName( ::rtl::OUString::createFromAscii( _pServiceNameAsciiNodeName ) ) >>= sServiceName;
222cdf0e10cSrcweir             if ( sServiceName.getLength() )
223cdf0e10cSrcweir             {
224cdf0e10cSrcweir                 bool bSuccess = false;
225cdf0e10cSrcweir                 if ( aSettings.getLength() )
226cdf0e10cSrcweir                 {
227cdf0e10cSrcweir                     Sequence< Any > aConstructionArgs(1);
228cdf0e10cSrcweir                     aConstructionArgs[0] <<= aSettings;
229cdf0e10cSrcweir                     bSuccess = _rContext.createComponentWithArguments( sServiceName, aConstructionArgs, xInstance );
230cdf0e10cSrcweir                 }
231cdf0e10cSrcweir                 else
232cdf0e10cSrcweir                 {
233cdf0e10cSrcweir                     bSuccess = _rContext.createComponent( sServiceName, xInstance );
234cdf0e10cSrcweir                 }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir                 if ( !bSuccess )
237cdf0e10cSrcweir                     throw ServiceNotRegisteredException( sServiceName, NULL );
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir             return xInstance;
241cdf0e10cSrcweir         }
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 	//--------------------------------------------------------------------
initializeLoggerFromConfiguration(const::comphelper::ComponentContext & _rContext,const Reference<XLogger> & _rxLogger)245cdf0e10cSrcweir     void initializeLoggerFromConfiguration( const ::comphelper::ComponentContext& _rContext, const Reference< XLogger >& _rxLogger )
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         try
248cdf0e10cSrcweir         {
249cdf0e10cSrcweir             if ( !_rxLogger.is() )
250cdf0e10cSrcweir                 throw NullPointerException();
251cdf0e10cSrcweir 
252cdf0e10cSrcweir             // the configuration provider
253cdf0e10cSrcweir             Reference< XMultiServiceFactory > xConfigProvider;
254cdf0e10cSrcweir             ::rtl::OUString sConfigProvServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
255cdf0e10cSrcweir             if ( !_rContext.createComponent( sConfigProvServiceName, xConfigProvider ) )
256cdf0e10cSrcweir                 throw ServiceNotRegisteredException( sConfigProvServiceName, _rxLogger );
257cdf0e10cSrcweir 
258cdf0e10cSrcweir             // write access to the "Settings" node (which includes settings for all loggers)
259cdf0e10cSrcweir             Sequence< Any > aArguments(1);
260cdf0e10cSrcweir             aArguments[0] <<= NamedValue(
261cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ),
262cdf0e10cSrcweir                 makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Logging/Settings" ) ) )
263cdf0e10cSrcweir             );
264cdf0e10cSrcweir             Reference< XNameContainer > xAllSettings( xConfigProvider->createInstanceWithArguments(
265cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ),
266cdf0e10cSrcweir                 aArguments
267cdf0e10cSrcweir             ), UNO_QUERY_THROW );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir             ::rtl::OUString sLoggerName( _rxLogger->getName() );
270cdf0e10cSrcweir             if ( !xAllSettings->hasByName( sLoggerName ) )
271cdf0e10cSrcweir             {
272cdf0e10cSrcweir                 // no node yet for this logger. Create default settings.
273cdf0e10cSrcweir                 Reference< XSingleServiceFactory > xNodeFactory( xAllSettings, UNO_QUERY_THROW );
274cdf0e10cSrcweir                 Reference< XInterface > xLoggerSettings( xNodeFactory->createInstance(), UNO_QUERY_THROW );
275cdf0e10cSrcweir                 xAllSettings->insertByName( sLoggerName, makeAny( xLoggerSettings ) );
276cdf0e10cSrcweir                 Reference< XChangesBatch > xChanges( xAllSettings, UNO_QUERY_THROW );
277cdf0e10cSrcweir                 xChanges->commitChanges();
278cdf0e10cSrcweir             }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir             // actually read and forward the settings
281cdf0e10cSrcweir             Reference< XNameAccess > xLoggerSettings( xAllSettings->getByName( sLoggerName ), UNO_QUERY_THROW );
282cdf0e10cSrcweir 
283cdf0e10cSrcweir             // the log level
284cdf0e10cSrcweir             sal_Int32 nLogLevel( LogLevel::OFF );
285cdf0e10cSrcweir             OSL_VERIFY( xLoggerSettings->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LogLevel" ) ) ) >>= nLogLevel );
286cdf0e10cSrcweir             _rxLogger->setLevel( nLogLevel );
287cdf0e10cSrcweir 
288cdf0e10cSrcweir             // the default handler, if any
289cdf0e10cSrcweir             Reference< XInterface > xUntyped( lcl_createInstanceFromSetting_throw( _rContext, _rxLogger, xLoggerSettings, "DefaultHandler", "HandlerSettings", &lcl_transformFileHandlerSettings_nothrow ) );
290cdf0e10cSrcweir             if ( !xUntyped.is() )
291cdf0e10cSrcweir                 // no handler -> we're done
292cdf0e10cSrcweir                 return;
293cdf0e10cSrcweir             Reference< XLogHandler > xHandler( xUntyped, UNO_QUERY_THROW );
294cdf0e10cSrcweir             _rxLogger->addLogHandler( xHandler );
295cdf0e10cSrcweir 
296cdf0e10cSrcweir             // The newly created handler might have an own (default) level. Ensure that it uses
297cdf0e10cSrcweir             // the same level as the logger.
298cdf0e10cSrcweir             xHandler->setLevel( nLogLevel );
299cdf0e10cSrcweir 
300cdf0e10cSrcweir             // the default formatter for the handler
301cdf0e10cSrcweir             xUntyped = lcl_createInstanceFromSetting_throw( _rContext, _rxLogger, xLoggerSettings, "DefaultFormatter", "FormatterSettings" );
302cdf0e10cSrcweir             if ( !xUntyped.is() )
303cdf0e10cSrcweir                 // no formatter -> we're done
304cdf0e10cSrcweir                 return;
305cdf0e10cSrcweir             Reference< XLogFormatter > xFormatter( xUntyped, UNO_QUERY_THROW );
306cdf0e10cSrcweir             xHandler->setFormatter( xFormatter );
307cdf0e10cSrcweir 
308cdf0e10cSrcweir             // TODO: we could first create the formatter, then the handler. This would allow
309cdf0e10cSrcweir             // passing the formatter as value in the component context, so the handler would
310cdf0e10cSrcweir             // not create an own default formatter
311cdf0e10cSrcweir         }
312cdf0e10cSrcweir         catch( const Exception& )
313cdf0e10cSrcweir         {
314cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir     }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir //........................................................................
319cdf0e10cSrcweir } // namespace logging
320cdf0e10cSrcweir //........................................................................
321