1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 
27 #include "log_module.hxx"
28 #include "methodguard.hxx"
29 #include "loghandler.hxx"
30 
31 /** === begin UNO includes === **/
32 #include <com/sun/star/logging/XConsoleHandler.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/logging/LogLevel.hpp>
35 #include <com/sun/star/lang/XInitialization.hpp>
36 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
37 #include <com/sun/star/lang/IllegalArgumentException.hpp>
38 #include <com/sun/star/beans/NamedValue.hpp>
39 /** === end UNO includes === **/
40 
41 #include <tools/diagnose_ex.h>
42 
43 #include <comphelper/componentcontext.hxx>
44 
45 #include <cppuhelper/compbase3.hxx>
46 #include <cppuhelper/basemutex.hxx>
47 
48 #include <stdio.h>
49 
50 //........................................................................
51 namespace logging
52 {
53 //........................................................................
54 
55 	/** === begin UNO using === **/
56     using ::com::sun::star::logging::XConsoleHandler;
57     using ::com::sun::star::lang::XServiceInfo;
58     using ::com::sun::star::uno::Reference;
59     using ::com::sun::star::uno::XComponentContext;
60     using ::com::sun::star::uno::RuntimeException;
61     using ::com::sun::star::logging::XLogFormatter;
62     using ::com::sun::star::uno::Sequence;
63     using ::com::sun::star::logging::LogRecord;
64     using ::com::sun::star::uno::UNO_QUERY_THROW;
65     using ::com::sun::star::uno::Exception;
66     using ::com::sun::star::uno::Any;
67     using ::com::sun::star::uno::XInterface;
68     using ::com::sun::star::lang::XInitialization;
69     using ::com::sun::star::ucb::AlreadyInitializedException;
70     using ::com::sun::star::lang::IllegalArgumentException;
71     using ::com::sun::star::beans::NamedValue;
72 	/** === end UNO using === **/
73     namespace LogLevel = ::com::sun::star::logging::LogLevel;
74 
75 	//====================================================================
76 	//= ConsoleHandler - declaration
77 	//====================================================================
78 	//--------------------------------------------------------------------
79     typedef ::cppu::WeakComponentImplHelper3    <   XConsoleHandler
80                                                 ,   XServiceInfo
81                                                 ,   XInitialization
82                                                 >   ConsoleHandler_Base;
83     class ConsoleHandler    :public ::cppu::BaseMutex
84                             ,public ConsoleHandler_Base
85 	{
86     private:
87         ::comphelper::ComponentContext  m_aContext;
88         LogHandlerHelper                m_aHandlerHelper;
89         sal_Int32                       m_nThreshold;
90 
91     protected:
92         ConsoleHandler( const Reference< XComponentContext >& _rxContext );
93         virtual ~ConsoleHandler();
94 
95         // XConsoleHandler
96         virtual ::sal_Int32 SAL_CALL getThreshold() throw (RuntimeException);
97         virtual void SAL_CALL setThreshold( ::sal_Int32 _threshold ) throw (RuntimeException);
98 
99         // XLogHandler
100         virtual ::rtl::OUString SAL_CALL getEncoding() throw (RuntimeException);
101         virtual void SAL_CALL setEncoding( const ::rtl::OUString& _encoding ) throw (RuntimeException);
102         virtual Reference< XLogFormatter > SAL_CALL getFormatter() throw (RuntimeException);
103         virtual void SAL_CALL setFormatter( const Reference< XLogFormatter >& _formatter ) throw (RuntimeException);
104         virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException);
105         virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException);
106         virtual void SAL_CALL flush(  ) throw (RuntimeException);
107         virtual ::sal_Bool SAL_CALL publish( const LogRecord& Record ) throw (RuntimeException);
108 
109         // XInitialization
110         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);
111 
112         // XServiceInfo
113 		virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
114         virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException);
115         virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
116 
117         // OComponentHelper
118         virtual void SAL_CALL disposing();
119 
120     public:
121         // XServiceInfo - static version
122 		static ::rtl::OUString SAL_CALL getImplementationName_static();
123         static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static();
124         static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext );
125 
126     public:
127         typedef ComponentMethodGuard< ConsoleHandler > MethodGuard;
128         void    enterMethod( MethodGuard::Access );
129         void    leaveMethod( MethodGuard::Access );
130 	};
131 
132     //====================================================================
133 	//= ConsoleHandler - implementation
134 	//====================================================================
135 	//--------------------------------------------------------------------
ConsoleHandler(const Reference<XComponentContext> & _rxContext)136     ConsoleHandler::ConsoleHandler( const Reference< XComponentContext >& _rxContext )
137         :ConsoleHandler_Base( m_aMutex )
138         ,m_aContext( _rxContext )
139         ,m_aHandlerHelper( _rxContext, m_aMutex, rBHelper )
140         ,m_nThreshold( LogLevel::SEVERE )
141     {
142     }
143 
144     //--------------------------------------------------------------------
~ConsoleHandler()145     ConsoleHandler::~ConsoleHandler()
146     {
147         if ( !rBHelper.bDisposed )
148         {
149             acquire();
150             dispose();
151         }
152     }
153 
154     //--------------------------------------------------------------------
disposing()155     void SAL_CALL ConsoleHandler::disposing()
156     {
157         m_aHandlerHelper.setFormatter( NULL );
158     }
159 
160     //--------------------------------------------------------------------
enterMethod(MethodGuard::Access)161     void ConsoleHandler::enterMethod( MethodGuard::Access )
162     {
163         m_aHandlerHelper.enterMethod();
164     }
165 
166     //--------------------------------------------------------------------
leaveMethod(MethodGuard::Access)167     void ConsoleHandler::leaveMethod( MethodGuard::Access )
168     {
169         m_aMutex.release();
170     }
171 
172     //--------------------------------------------------------------------
getThreshold()173     ::sal_Int32 SAL_CALL ConsoleHandler::getThreshold() throw (RuntimeException)
174     {
175         MethodGuard aGuard( *this );
176         return m_nThreshold;
177     }
178 
179     //--------------------------------------------------------------------
setThreshold(::sal_Int32 _threshold)180     void SAL_CALL ConsoleHandler::setThreshold( ::sal_Int32 _threshold ) throw (RuntimeException)
181     {
182         MethodGuard aGuard( *this );
183         m_nThreshold = _threshold;
184     }
185 
186     //--------------------------------------------------------------------
getEncoding()187     ::rtl::OUString SAL_CALL ConsoleHandler::getEncoding() throw (RuntimeException)
188     {
189         MethodGuard aGuard( *this );
190         ::rtl::OUString sEncoding;
191         OSL_VERIFY( m_aHandlerHelper.getEncoding( sEncoding ) );
192         return sEncoding;
193     }
194 
195     //--------------------------------------------------------------------
setEncoding(const::rtl::OUString & _rEncoding)196     void SAL_CALL ConsoleHandler::setEncoding( const ::rtl::OUString& _rEncoding ) throw (RuntimeException)
197     {
198         MethodGuard aGuard( *this );
199         OSL_VERIFY( m_aHandlerHelper.setEncoding( _rEncoding ) );
200     }
201 
202     //--------------------------------------------------------------------
getFormatter()203     Reference< XLogFormatter > SAL_CALL ConsoleHandler::getFormatter() throw (RuntimeException)
204     {
205         MethodGuard aGuard( *this );
206         return m_aHandlerHelper.getFormatter();
207     }
208 
209     //--------------------------------------------------------------------
setFormatter(const Reference<XLogFormatter> & _rxFormatter)210     void SAL_CALL ConsoleHandler::setFormatter( const Reference< XLogFormatter >& _rxFormatter ) throw (RuntimeException)
211     {
212         MethodGuard aGuard( *this );
213         m_aHandlerHelper.setFormatter( _rxFormatter );
214     }
215 
216     //--------------------------------------------------------------------
getLevel()217     ::sal_Int32 SAL_CALL ConsoleHandler::getLevel() throw (RuntimeException)
218     {
219         MethodGuard aGuard( *this );
220         return m_aHandlerHelper.getLevel();
221     }
222 
223     //--------------------------------------------------------------------
setLevel(::sal_Int32 _nLevel)224     void SAL_CALL ConsoleHandler::setLevel( ::sal_Int32 _nLevel ) throw (RuntimeException)
225     {
226         MethodGuard aGuard( *this );
227         m_aHandlerHelper.setLevel( _nLevel );
228     }
229 
230     //--------------------------------------------------------------------
flush()231     void SAL_CALL ConsoleHandler::flush(  ) throw (RuntimeException)
232     {
233         MethodGuard aGuard( *this );
234         fflush( stdout );
235         fflush( stderr );
236     }
237 
238     //--------------------------------------------------------------------
publish(const LogRecord & _rRecord)239     ::sal_Bool SAL_CALL ConsoleHandler::publish( const LogRecord& _rRecord ) throw (RuntimeException)
240     {
241         MethodGuard aGuard( *this );
242 
243         ::rtl::OString sEntry;
244         if ( !m_aHandlerHelper.formatForPublishing( _rRecord, sEntry ) )
245             return sal_False;
246 
247         if ( _rRecord.Level >= m_nThreshold )
248             fprintf( stderr, sEntry.getStr() );
249         else
250             fprintf( stdout, sEntry.getStr() );
251 
252         return sal_True;
253     }
254 
255     //--------------------------------------------------------------------
initialize(const Sequence<Any> & _rArguments)256     void SAL_CALL ConsoleHandler::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
257     {
258         ::osl::MutexGuard aGuard( m_aMutex );
259 
260         if ( m_aHandlerHelper.getIsInitialized() )
261             throw AlreadyInitializedException();
262 
263         if ( _rArguments.getLength() == 0 )
264         {   // create() - nothing to init
265             m_aHandlerHelper.setIsInitialized();
266             return;
267         }
268 
269         if ( _rArguments.getLength() != 1 )
270             throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
271 
272         Sequence< NamedValue > aSettings;
273         if ( !( _rArguments[0] >>= aSettings ) )
274             throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
275 
276         // createWithSettings( [in] sequence< ::com::sun::star::beans::NamedValue > Settings )
277         ::comphelper::NamedValueCollection aTypedSettings( aSettings );
278         m_aHandlerHelper.initFromSettings( aTypedSettings );
279 
280         aTypedSettings.get_ensureType( "Threshold", m_nThreshold );
281 
282         m_aHandlerHelper.setIsInitialized();
283     }
284 
285     //--------------------------------------------------------------------
getImplementationName()286     ::rtl::OUString SAL_CALL ConsoleHandler::getImplementationName() throw(RuntimeException)
287     {
288         return getImplementationName_static();
289     }
290 
291     //--------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)292     ::sal_Bool SAL_CALL ConsoleHandler::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
293     {
294         const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() );
295         for (   const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray();
296                 pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength();
297                 ++pServiceNames
298             )
299             if ( _rServiceName == *pServiceNames )
300                 return sal_True;
301         return sal_False;
302     }
303 
304     //--------------------------------------------------------------------
getSupportedServiceNames()305     Sequence< ::rtl::OUString > SAL_CALL ConsoleHandler::getSupportedServiceNames() throw(RuntimeException)
306     {
307         return getSupportedServiceNames_static();
308     }
309 
310     //--------------------------------------------------------------------
getImplementationName_static()311     ::rtl::OUString SAL_CALL ConsoleHandler::getImplementationName_static()
312     {
313         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.ConsoleHandler" ) );
314     }
315 
316     //--------------------------------------------------------------------
getSupportedServiceNames_static()317     Sequence< ::rtl::OUString > SAL_CALL ConsoleHandler::getSupportedServiceNames_static()
318     {
319         Sequence< ::rtl::OUString > aServiceNames(1);
320         aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.ConsoleHandler" ) );
321         return aServiceNames;
322     }
323 
324     //--------------------------------------------------------------------
Create(const Reference<XComponentContext> & _rxContext)325     Reference< XInterface > ConsoleHandler::Create( const Reference< XComponentContext >& _rxContext )
326     {
327         return *( new ConsoleHandler( _rxContext ) );
328     }
329 
330     //--------------------------------------------------------------------
createRegistryInfo_ConsoleHandler()331     void createRegistryInfo_ConsoleHandler()
332     {
333         static OAutoRegistration< ConsoleHandler > aAutoRegistration;
334     }
335 
336 //........................................................................
337 } // namespace logging
338 //........................................................................
339