1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_comphelper.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <comphelper/uieventslogger.hxx>
28*b1cdbd2cSJim Jagielski #include <boost/shared_ptr.hpp>
29*b1cdbd2cSJim Jagielski #include <com/sun/star/frame/XDesktop.hpp>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/frame/XTerminateListener.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XEventListener.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XMultiComponentFactory.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/logging/LogLevel.hpp>
35*b1cdbd2cSJim Jagielski #include <com/sun/star/logging/XCsvLogFormatter.hpp>
36*b1cdbd2cSJim Jagielski #include <com/sun/star/logging/XLogHandler.hpp>
37*b1cdbd2cSJim Jagielski #include <com/sun/star/logging/XLogger.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/logging/XLoggerPool.hpp>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/oooimprovement/XCoreController.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/Sequence.hxx>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XStringSubstitution.hpp>
42*b1cdbd2cSJim Jagielski #include <comphelper/configurationhelper.hxx>
43*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
44*b1cdbd2cSJim Jagielski #include <map>
45*b1cdbd2cSJim Jagielski #include <osl/file.hxx>
46*b1cdbd2cSJim Jagielski #include <osl/mutex.hxx>
47*b1cdbd2cSJim Jagielski #include <osl/time.h>
48*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
49*b1cdbd2cSJim Jagielski 
50*b1cdbd2cSJim Jagielski 
51*b1cdbd2cSJim Jagielski using namespace com::sun::star::beans;
52*b1cdbd2cSJim Jagielski using namespace com::sun::star::frame;
53*b1cdbd2cSJim Jagielski using namespace com::sun::star::lang;
54*b1cdbd2cSJim Jagielski using namespace com::sun::star::logging;
55*b1cdbd2cSJim Jagielski using namespace com::sun::star::oooimprovement;
56*b1cdbd2cSJim Jagielski using namespace com::sun::star::uno;
57*b1cdbd2cSJim Jagielski using namespace com::sun::star::util;
58*b1cdbd2cSJim Jagielski using namespace cppu;
59*b1cdbd2cSJim Jagielski using namespace osl;
60*b1cdbd2cSJim Jagielski using namespace rtl;
61*b1cdbd2cSJim Jagielski using namespace std;
62*b1cdbd2cSJim Jagielski 
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski namespace
65*b1cdbd2cSJim Jagielski {
lcl_SetupOriginAppAbbr(map<OUString,OUString> & abbrs)66*b1cdbd2cSJim Jagielski     static void lcl_SetupOriginAppAbbr(map<OUString, OUString>& abbrs)
67*b1cdbd2cSJim Jagielski     {
68*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("com.sun.star.text.TextDocument")] = OUString::createFromAscii("W"); // Writer
69*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument")] = OUString::createFromAscii("C"); // Calc
70*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("com.sun.star.presentation.PresentationDocument")] = OUString::createFromAscii("I"); // Impress
71*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("com.sun.star.drawing.DrawingDocument")] = OUString::createFromAscii("D"); // Draw
72*b1cdbd2cSJim Jagielski     };
73*b1cdbd2cSJim Jagielski 
lcl_SetupOriginWidgetAbbr(map<OUString,OUString> & abbrs)74*b1cdbd2cSJim Jagielski     static void lcl_SetupOriginWidgetAbbr(map<OUString,OUString>& abbrs)
75*b1cdbd2cSJim Jagielski     {
76*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("ButtonToolbarController")] = OUString::createFromAscii("0");
77*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("ComplexToolbarController")] = OUString::createFromAscii("1");
78*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("ControlMenuController")] = OUString::createFromAscii("2");
79*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("FontMenuController")] = OUString::createFromAscii("3");
80*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("FontSizeMenuController")] = OUString::createFromAscii("4");
81*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("FooterMenuController")] = OUString::createFromAscii("5");
82*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("GenericToolbarController")] = OUString::createFromAscii("6");
83*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("HeaderMenuController")] = OUString::createFromAscii("7");
84*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("LanguageSelectionMenuController")] = OUString::createFromAscii("8");
85*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("LangSelectionStatusbarController")] = OUString::createFromAscii("9");
86*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("MacrosMenuController")] = OUString::createFromAscii("10");
87*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("MenuBarManager")] = OUString::createFromAscii("11");
88*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("NewMenuController")] = OUString::createFromAscii("12");
89*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("ObjectMenuController")] = OUString::createFromAscii("13");
90*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("RecentFilesMenuController")] = OUString::createFromAscii("14");
91*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("ToolbarsMenuController")] = OUString::createFromAscii("15");
92*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("SfxToolBoxControl")] = OUString::createFromAscii("16");
93*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("SfxAsyncExec")] = OUString::createFromAscii("17");
94*b1cdbd2cSJim Jagielski         abbrs[OUString::createFromAscii("AcceleratorExecute")] = OUString::createFromAscii("18");
95*b1cdbd2cSJim Jagielski     };
96*b1cdbd2cSJim Jagielski }
97*b1cdbd2cSJim Jagielski 
98*b1cdbd2cSJim Jagielski namespace comphelper
99*b1cdbd2cSJim Jagielski {
100*b1cdbd2cSJim Jagielski     // declaration of implementation
101*b1cdbd2cSJim Jagielski     class UiEventsLogger_Impl;
102*b1cdbd2cSJim Jagielski     class UiEventsLogger_Impl : public UiEventsLogger
103*b1cdbd2cSJim Jagielski     {
104*b1cdbd2cSJim Jagielski         private:
105*b1cdbd2cSJim Jagielski             //typedefs and friends
106*b1cdbd2cSJim Jagielski             friend class UiEventsLogger;
107*b1cdbd2cSJim Jagielski             typedef UiEventsLogger_Impl* ptr;
108*b1cdbd2cSJim Jagielski 
109*b1cdbd2cSJim Jagielski             // instance methods and data
110*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl();
111*b1cdbd2cSJim Jagielski             void initializeLogger();
112*b1cdbd2cSJim Jagielski             void logDispatch(const ::com::sun::star::util::URL& url,
113*b1cdbd2cSJim Jagielski                 const Sequence<PropertyValue>& args);
114*b1cdbd2cSJim Jagielski             void logRotated();
115*b1cdbd2cSJim Jagielski             void logVcl(const ::rtl::OUString& parent_id,
116*b1cdbd2cSJim Jagielski                 sal_Int32 window_type,
117*b1cdbd2cSJim Jagielski                 const ::rtl::OUString& id,
118*b1cdbd2cSJim Jagielski                 const ::rtl::OUString& method,
119*b1cdbd2cSJim Jagielski                 const ::rtl::OUString& param);
120*b1cdbd2cSJim Jagielski             void rotate();
121*b1cdbd2cSJim Jagielski             void hotRotate();
122*b1cdbd2cSJim Jagielski             void prepareLogHandler();
123*b1cdbd2cSJim Jagielski             void checkIdleTimeout();
124*b1cdbd2cSJim Jagielski             OUString getCurrentPath();
125*b1cdbd2cSJim Jagielski             OUString getRotatedPath();
126*b1cdbd2cSJim Jagielski             void disposing();
127*b1cdbd2cSJim Jagielski 
128*b1cdbd2cSJim Jagielski             bool m_Active;
129*b1cdbd2cSJim Jagielski             TimeValue m_LastLogEventTime;
130*b1cdbd2cSJim Jagielski             const OUString m_LogPath;
131*b1cdbd2cSJim Jagielski             const TimeValue m_IdleTimeout;
132*b1cdbd2cSJim Jagielski             sal_Int32 m_SessionLogEventCount;
133*b1cdbd2cSJim Jagielski             Reference<XLogger> m_Logger;
134*b1cdbd2cSJim Jagielski             Reference<XLogHandler> m_LogHandler;
135*b1cdbd2cSJim Jagielski             Reference<XCsvLogFormatter> m_Formatter;
136*b1cdbd2cSJim Jagielski             map<OUString, OUString> m_OriginAppAbbr;
137*b1cdbd2cSJim Jagielski             map<OUString, OUString> m_OriginWidgetAbbr;
138*b1cdbd2cSJim Jagielski 
139*b1cdbd2cSJim Jagielski 
140*b1cdbd2cSJim Jagielski             // static methods and data
141*b1cdbd2cSJim Jagielski             static ptr getInstance();
142*b1cdbd2cSJim Jagielski             static void prepareMutex();
143*b1cdbd2cSJim Jagielski             static bool shouldActivate();
144*b1cdbd2cSJim Jagielski             static bool getEnabledFromCoreController();
145*b1cdbd2cSJim Jagielski             static bool getEnabledFromCfg();
146*b1cdbd2cSJim Jagielski             static TimeValue getIdleTimeoutFromCfg();
147*b1cdbd2cSJim Jagielski             static OUString getLogPathFromCfg();
148*b1cdbd2cSJim Jagielski             static sal_Int32 findIdx(const Sequence<PropertyValue>& args, const OUString& key);
149*b1cdbd2cSJim Jagielski 
150*b1cdbd2cSJim Jagielski             static ptr instance;
151*b1cdbd2cSJim Jagielski             static Mutex * singleton_mutex;
152*b1cdbd2cSJim Jagielski             static const sal_Int32 COLUMNS;
153*b1cdbd2cSJim Jagielski             static const OUString CFG_ENABLED;
154*b1cdbd2cSJim Jagielski             static const OUString CFG_IDLETIMEOUT;
155*b1cdbd2cSJim Jagielski             static const OUString CFG_LOGGING;
156*b1cdbd2cSJim Jagielski             static const OUString CFG_LOGPATH;
157*b1cdbd2cSJim Jagielski             static const OUString CFG_OOOIMPROVEMENT;
158*b1cdbd2cSJim Jagielski             static const OUString ETYPE_DISPATCH;
159*b1cdbd2cSJim Jagielski             static const OUString ETYPE_ROTATED;
160*b1cdbd2cSJim Jagielski             static const OUString ETYPE_VCL;
161*b1cdbd2cSJim Jagielski             static const OUString CSSL_CSVFORMATTER;
162*b1cdbd2cSJim Jagielski             static const OUString CSSL_FILEHANDLER;
163*b1cdbd2cSJim Jagielski             static const OUString CSSL_LOGGERPOOL;
164*b1cdbd2cSJim Jagielski             static const OUString CSSO_CORECONTROLLER;
165*b1cdbd2cSJim Jagielski             static const OUString CSST_JOBEXECUTOR;
166*b1cdbd2cSJim Jagielski             static const OUString CSSU_PATHSUB;
167*b1cdbd2cSJim Jagielski             static const OUString LOGGERNAME;
168*b1cdbd2cSJim Jagielski             static const OUString LOGORIGINAPP;
169*b1cdbd2cSJim Jagielski             static const OUString LOGORIGINWIDGET;
170*b1cdbd2cSJim Jagielski             static const OUString UNKNOWN_ORIGIN;
171*b1cdbd2cSJim Jagielski             static const OUString FN_CURRENTLOG;
172*b1cdbd2cSJim Jagielski             static const OUString FN_ROTATEDLOG;
173*b1cdbd2cSJim Jagielski             static const OUString LOGROTATE_EVENTNAME;
174*b1cdbd2cSJim Jagielski             static const OUString URL_UNO;
175*b1cdbd2cSJim Jagielski             static const OUString URL_SPECIAL;
176*b1cdbd2cSJim Jagielski             static const OUString URL_FILE;
177*b1cdbd2cSJim Jagielski     };
178*b1cdbd2cSJim Jagielski }
179*b1cdbd2cSJim Jagielski 
180*b1cdbd2cSJim Jagielski namespace comphelper
181*b1cdbd2cSJim Jagielski {
182*b1cdbd2cSJim Jagielski     // consts
183*b1cdbd2cSJim Jagielski     const sal_Int32 UiEventsLogger_Impl::COLUMNS = 9;
184*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CFG_ENABLED = OUString::createFromAscii("EnablingAllowed");
185*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CFG_IDLETIMEOUT = OUString::createFromAscii("IdleTimeout");
186*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CFG_LOGGING = OUString::createFromAscii("/org.openoffice.Office.Logging");
187*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CFG_LOGPATH = OUString::createFromAscii("LogPath");
188*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CFG_OOOIMPROVEMENT = OUString::createFromAscii("OOoImprovement");
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CSSL_CSVFORMATTER = OUString::createFromAscii("com.sun.star.logging.CsvFormatter");
191*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CSSL_FILEHANDLER = OUString::createFromAscii("com.sun.star.logging.FileHandler");
192*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CSSL_LOGGERPOOL = OUString::createFromAscii("com.sun.star.logging.LoggerPool");
193*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CSSO_CORECONTROLLER = OUString::createFromAscii("com.sun.star.oooimprovement.CoreController");
194*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::CSSU_PATHSUB = OUString::createFromAscii("com.sun.star.util.PathSubstitution");
195*b1cdbd2cSJim Jagielski 
196*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::ETYPE_DISPATCH = OUString::createFromAscii("dispatch");
197*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::ETYPE_ROTATED = OUString::createFromAscii("rotated");
198*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::ETYPE_VCL = OUString::createFromAscii("vcl");
199*b1cdbd2cSJim Jagielski 
200*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::LOGGERNAME = OUString::createFromAscii("org.openoffice.oooimprovement.Core.UiEventsLogger");
201*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::LOGORIGINWIDGET = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginWidget");
202*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::LOGORIGINAPP = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginApp");
203*b1cdbd2cSJim Jagielski 
204*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::UNKNOWN_ORIGIN = OUString::createFromAscii("unknown origin");
205*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::FN_CURRENTLOG = OUString::createFromAscii("Current");
206*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::FN_ROTATEDLOG = OUString::createFromAscii("OOoImprove");
207*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::LOGROTATE_EVENTNAME = OUString::createFromAscii("onOOoImprovementLogRotated");
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::URL_UNO = OUString::createFromAscii(".uno:");
210*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::URL_SPECIAL = OUString::createFromAscii(".special:");
211*b1cdbd2cSJim Jagielski     const OUString UiEventsLogger_Impl::URL_FILE = OUString::createFromAscii("file:");
212*b1cdbd2cSJim Jagielski 
213*b1cdbd2cSJim Jagielski 
214*b1cdbd2cSJim Jagielski     // public UiEventsLogger interface
isEnabled()215*b1cdbd2cSJim Jagielski     sal_Bool UiEventsLogger::isEnabled()
216*b1cdbd2cSJim Jagielski     {
217*b1cdbd2cSJim Jagielski         if ( UiEventsLogger_Impl::getEnabledFromCfg() )
218*b1cdbd2cSJim Jagielski         {
219*b1cdbd2cSJim Jagielski             try {
220*b1cdbd2cSJim Jagielski                 UiEventsLogger_Impl::prepareMutex();
221*b1cdbd2cSJim Jagielski                 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
222*b1cdbd2cSJim Jagielski                 return UiEventsLogger_Impl::getInstance()->m_Active;
223*b1cdbd2cSJim Jagielski             } catch(...) { return false; } // never throws
224*b1cdbd2cSJim Jagielski         } // if ( )
225*b1cdbd2cSJim Jagielski         return sal_False;
226*b1cdbd2cSJim Jagielski     }
227*b1cdbd2cSJim Jagielski 
getSessionLogEventCount()228*b1cdbd2cSJim Jagielski     sal_Int32 UiEventsLogger::getSessionLogEventCount()
229*b1cdbd2cSJim Jagielski     {
230*b1cdbd2cSJim Jagielski         try {
231*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::prepareMutex();
232*b1cdbd2cSJim Jagielski             Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
233*b1cdbd2cSJim Jagielski             return UiEventsLogger_Impl::getInstance()->m_SessionLogEventCount;
234*b1cdbd2cSJim Jagielski         } catch(...) { return 0; } // never throws
235*b1cdbd2cSJim Jagielski     }
236*b1cdbd2cSJim Jagielski 
appendDispatchOrigin(Sequence<PropertyValue> & args,const OUString & originapp,const OUString & originwidget)237*b1cdbd2cSJim Jagielski     void UiEventsLogger::appendDispatchOrigin(
238*b1cdbd2cSJim Jagielski         Sequence<PropertyValue>& args,
239*b1cdbd2cSJim Jagielski         const OUString& originapp,
240*b1cdbd2cSJim Jagielski         const OUString& originwidget)
241*b1cdbd2cSJim Jagielski     {
242*b1cdbd2cSJim Jagielski         sal_Int32 old_length = args.getLength();
243*b1cdbd2cSJim Jagielski         args.realloc(old_length+2);
244*b1cdbd2cSJim Jagielski         args[old_length].Name = UiEventsLogger_Impl::LOGORIGINAPP;
245*b1cdbd2cSJim Jagielski         args[old_length].Value = static_cast<Any>(originapp);
246*b1cdbd2cSJim Jagielski         args[old_length+1].Name = UiEventsLogger_Impl::LOGORIGINWIDGET;
247*b1cdbd2cSJim Jagielski         args[old_length+1].Value = static_cast<Any>(originwidget);
248*b1cdbd2cSJim Jagielski     }
249*b1cdbd2cSJim Jagielski 
purgeDispatchOrigin(const Sequence<PropertyValue> & args)250*b1cdbd2cSJim Jagielski     Sequence<PropertyValue> UiEventsLogger::purgeDispatchOrigin(
251*b1cdbd2cSJim Jagielski         const Sequence<PropertyValue>& args)
252*b1cdbd2cSJim Jagielski     {
253*b1cdbd2cSJim Jagielski         Sequence<PropertyValue> result(args.getLength());
254*b1cdbd2cSJim Jagielski         sal_Int32 target_idx=0;
255*b1cdbd2cSJim Jagielski         for(sal_Int32 source_idx=0; source_idx<args.getLength(); source_idx++)
256*b1cdbd2cSJim Jagielski             if(args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINAPP
257*b1cdbd2cSJim Jagielski                 && args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINWIDGET)
258*b1cdbd2cSJim Jagielski                 result[target_idx++] = args[source_idx];
259*b1cdbd2cSJim Jagielski         result.realloc(target_idx);
260*b1cdbd2cSJim Jagielski         return result;
261*b1cdbd2cSJim Jagielski     }
262*b1cdbd2cSJim Jagielski 
logDispatch(const URL & url,const Sequence<PropertyValue> & args)263*b1cdbd2cSJim Jagielski     void UiEventsLogger::logDispatch(
264*b1cdbd2cSJim Jagielski         const URL& url,
265*b1cdbd2cSJim Jagielski         const Sequence<PropertyValue>& args)
266*b1cdbd2cSJim Jagielski     {
267*b1cdbd2cSJim Jagielski         try {
268*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::prepareMutex();
269*b1cdbd2cSJim Jagielski             Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
270*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::getInstance()->logDispatch(url, args);
271*b1cdbd2cSJim Jagielski         } catch(...) { } // never throws
272*b1cdbd2cSJim Jagielski     }
273*b1cdbd2cSJim Jagielski 
logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method,const OUString & param)274*b1cdbd2cSJim Jagielski     void UiEventsLogger::logVcl(
275*b1cdbd2cSJim Jagielski         const OUString& parent_id,
276*b1cdbd2cSJim Jagielski         sal_Int32 window_type,
277*b1cdbd2cSJim Jagielski         const OUString& id,
278*b1cdbd2cSJim Jagielski         const OUString& method,
279*b1cdbd2cSJim Jagielski         const OUString& param)
280*b1cdbd2cSJim Jagielski     {
281*b1cdbd2cSJim Jagielski         try {
282*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::prepareMutex();
283*b1cdbd2cSJim Jagielski             Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
284*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::getInstance()->logVcl(parent_id, window_type, id, method, param);
285*b1cdbd2cSJim Jagielski         } catch(...) { } // never throws
286*b1cdbd2cSJim Jagielski     }
287*b1cdbd2cSJim Jagielski 
logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method,sal_Int32 param)288*b1cdbd2cSJim Jagielski     void UiEventsLogger::logVcl(
289*b1cdbd2cSJim Jagielski         const OUString& parent_id,
290*b1cdbd2cSJim Jagielski         sal_Int32 window_type,
291*b1cdbd2cSJim Jagielski         const OUString& id,
292*b1cdbd2cSJim Jagielski         const OUString& method,
293*b1cdbd2cSJim Jagielski         sal_Int32 param)
294*b1cdbd2cSJim Jagielski     {
295*b1cdbd2cSJim Jagielski         OUStringBuffer buf;
296*b1cdbd2cSJim Jagielski         UiEventsLogger::logVcl(parent_id, window_type, id, method, buf.append(param).makeStringAndClear());
297*b1cdbd2cSJim Jagielski     }
298*b1cdbd2cSJim Jagielski 
logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method)299*b1cdbd2cSJim Jagielski     void UiEventsLogger::logVcl(
300*b1cdbd2cSJim Jagielski         const OUString& parent_id,
301*b1cdbd2cSJim Jagielski         sal_Int32 window_type,
302*b1cdbd2cSJim Jagielski         const OUString& id,
303*b1cdbd2cSJim Jagielski         const OUString& method)
304*b1cdbd2cSJim Jagielski     {
305*b1cdbd2cSJim Jagielski         OUString empty;
306*b1cdbd2cSJim Jagielski         UiEventsLogger::logVcl(parent_id, window_type, id, method, empty);
307*b1cdbd2cSJim Jagielski     }
308*b1cdbd2cSJim Jagielski 
disposing()309*b1cdbd2cSJim Jagielski     void UiEventsLogger::disposing()
310*b1cdbd2cSJim Jagielski     {
311*b1cdbd2cSJim Jagielski         // we dont want to create an instance just to dispose it
312*b1cdbd2cSJim Jagielski         UiEventsLogger_Impl::prepareMutex();
313*b1cdbd2cSJim Jagielski         Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
314*b1cdbd2cSJim Jagielski         if(UiEventsLogger_Impl::instance!=UiEventsLogger_Impl::ptr())
315*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::getInstance()->disposing();
316*b1cdbd2cSJim Jagielski     }
317*b1cdbd2cSJim Jagielski 
reinit()318*b1cdbd2cSJim Jagielski     void UiEventsLogger::reinit()
319*b1cdbd2cSJim Jagielski     {
320*b1cdbd2cSJim Jagielski         UiEventsLogger_Impl::prepareMutex();
321*b1cdbd2cSJim Jagielski         Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
322*b1cdbd2cSJim Jagielski         if(UiEventsLogger_Impl::instance)
323*b1cdbd2cSJim Jagielski         {
324*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::instance->disposing();
325*b1cdbd2cSJim Jagielski             delete UiEventsLogger_Impl::instance;
326*b1cdbd2cSJim Jagielski             UiEventsLogger_Impl::instance = NULL;
327*b1cdbd2cSJim Jagielski         }
328*b1cdbd2cSJim Jagielski     }
329*b1cdbd2cSJim Jagielski 
330*b1cdbd2cSJim Jagielski     // private UiEventsLogger_Impl methods
UiEventsLogger_Impl()331*b1cdbd2cSJim Jagielski     UiEventsLogger_Impl::UiEventsLogger_Impl()
332*b1cdbd2cSJim Jagielski         : m_Active(UiEventsLogger_Impl::shouldActivate())
333*b1cdbd2cSJim Jagielski         , m_LogPath(UiEventsLogger_Impl::getLogPathFromCfg())
334*b1cdbd2cSJim Jagielski         , m_IdleTimeout(UiEventsLogger_Impl::getIdleTimeoutFromCfg())
335*b1cdbd2cSJim Jagielski         , m_SessionLogEventCount(0)
336*b1cdbd2cSJim Jagielski     {
337*b1cdbd2cSJim Jagielski         lcl_SetupOriginAppAbbr(m_OriginAppAbbr);
338*b1cdbd2cSJim Jagielski         lcl_SetupOriginWidgetAbbr(m_OriginWidgetAbbr);
339*b1cdbd2cSJim Jagielski         m_LastLogEventTime.Seconds = m_LastLogEventTime.Nanosec = 0;
340*b1cdbd2cSJim Jagielski         if(m_Active) rotate();
341*b1cdbd2cSJim Jagielski         if(m_Active) initializeLogger();
342*b1cdbd2cSJim Jagielski     }
343*b1cdbd2cSJim Jagielski 
logDispatch(const URL & url,const Sequence<PropertyValue> & args)344*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::logDispatch(
345*b1cdbd2cSJim Jagielski         const URL& url,
346*b1cdbd2cSJim Jagielski         const Sequence<PropertyValue>& args)
347*b1cdbd2cSJim Jagielski     {
348*b1cdbd2cSJim Jagielski         if(!m_Active) return;
349*b1cdbd2cSJim Jagielski         if(!url.Complete.match(URL_UNO)
350*b1cdbd2cSJim Jagielski             && !url.Complete.match(URL_FILE)
351*b1cdbd2cSJim Jagielski             && !url.Complete.match(URL_SPECIAL))
352*b1cdbd2cSJim Jagielski         {
353*b1cdbd2cSJim Jagielski             return;
354*b1cdbd2cSJim Jagielski         }
355*b1cdbd2cSJim Jagielski         checkIdleTimeout();
356*b1cdbd2cSJim Jagielski 
357*b1cdbd2cSJim Jagielski         Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
358*b1cdbd2cSJim Jagielski         logdata[0] = ETYPE_DISPATCH;
359*b1cdbd2cSJim Jagielski         sal_Int32 originapp_idx = findIdx(args, LOGORIGINAPP);
360*b1cdbd2cSJim Jagielski         if(originapp_idx!=-1)
361*b1cdbd2cSJim Jagielski         {
362*b1cdbd2cSJim Jagielski             OUString app;
363*b1cdbd2cSJim Jagielski             args[originapp_idx].Value >>= app;
364*b1cdbd2cSJim Jagielski             map<OUString, OUString>::iterator abbr_it = m_OriginAppAbbr.find(app);
365*b1cdbd2cSJim Jagielski             if(abbr_it != m_OriginAppAbbr.end())
366*b1cdbd2cSJim Jagielski                 app = abbr_it->second;
367*b1cdbd2cSJim Jagielski             logdata[1] = app;
368*b1cdbd2cSJim Jagielski         }
369*b1cdbd2cSJim Jagielski         else
370*b1cdbd2cSJim Jagielski             logdata[1] = UNKNOWN_ORIGIN;
371*b1cdbd2cSJim Jagielski         sal_Int32 originwidget_idx = findIdx(args, LOGORIGINWIDGET);
372*b1cdbd2cSJim Jagielski         if(originwidget_idx!=-1)
373*b1cdbd2cSJim Jagielski         {
374*b1cdbd2cSJim Jagielski             OUString widget;
375*b1cdbd2cSJim Jagielski             args[originwidget_idx].Value >>= widget;
376*b1cdbd2cSJim Jagielski             map<OUString, OUString>::iterator widget_it = m_OriginWidgetAbbr.find(widget);
377*b1cdbd2cSJim Jagielski             if(widget_it != m_OriginWidgetAbbr.end())
378*b1cdbd2cSJim Jagielski                 widget = widget_it->second;
379*b1cdbd2cSJim Jagielski             logdata[2] = widget;
380*b1cdbd2cSJim Jagielski         }
381*b1cdbd2cSJim Jagielski         else
382*b1cdbd2cSJim Jagielski             logdata[2] = UNKNOWN_ORIGIN;
383*b1cdbd2cSJim Jagielski         if(url.Complete.match(URL_FILE))
384*b1cdbd2cSJim Jagielski             logdata[3] = URL_FILE;
385*b1cdbd2cSJim Jagielski         else
386*b1cdbd2cSJim Jagielski             logdata[3] = url.Main;
387*b1cdbd2cSJim Jagielski         OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
388*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
389*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
390*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
391*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
392*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
393*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
394*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
395*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
396*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
397*b1cdbd2cSJim Jagielski         m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
398*b1cdbd2cSJim Jagielski         m_SessionLogEventCount++;
399*b1cdbd2cSJim Jagielski     }
400*b1cdbd2cSJim Jagielski 
logRotated()401*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::logRotated()
402*b1cdbd2cSJim Jagielski     {
403*b1cdbd2cSJim Jagielski         Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
404*b1cdbd2cSJim Jagielski         logdata[0] = ETYPE_ROTATED;
405*b1cdbd2cSJim Jagielski         OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
406*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
407*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
408*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
409*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
410*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
411*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
412*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
413*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
414*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
415*b1cdbd2cSJim Jagielski         m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
416*b1cdbd2cSJim Jagielski     }
417*b1cdbd2cSJim Jagielski 
logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method,const OUString & param)418*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::logVcl(
419*b1cdbd2cSJim Jagielski         const OUString& parent_id,
420*b1cdbd2cSJim Jagielski         sal_Int32 window_type,
421*b1cdbd2cSJim Jagielski         const OUString& id,
422*b1cdbd2cSJim Jagielski         const OUString& method,
423*b1cdbd2cSJim Jagielski         const OUString& param)
424*b1cdbd2cSJim Jagielski     {
425*b1cdbd2cSJim Jagielski         if(!m_Active) return;
426*b1cdbd2cSJim Jagielski         checkIdleTimeout();
427*b1cdbd2cSJim Jagielski 
428*b1cdbd2cSJim Jagielski         OUStringBuffer buf;
429*b1cdbd2cSJim Jagielski         Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
430*b1cdbd2cSJim Jagielski         logdata[0] = ETYPE_VCL;
431*b1cdbd2cSJim Jagielski         logdata[4] = parent_id;
432*b1cdbd2cSJim Jagielski         logdata[5] = buf.append(window_type).makeStringAndClear();
433*b1cdbd2cSJim Jagielski         logdata[6] = id;
434*b1cdbd2cSJim Jagielski         logdata[7] = method;
435*b1cdbd2cSJim Jagielski         logdata[8] = param;
436*b1cdbd2cSJim Jagielski         OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
437*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
438*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
439*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
440*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
441*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
442*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
443*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
444*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
445*b1cdbd2cSJim Jagielski             OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
446*b1cdbd2cSJim Jagielski         m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
447*b1cdbd2cSJim Jagielski         m_SessionLogEventCount++;
448*b1cdbd2cSJim Jagielski     }
449*b1cdbd2cSJim Jagielski 
rotate()450*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::rotate()
451*b1cdbd2cSJim Jagielski     {
452*b1cdbd2cSJim Jagielski         FileBase::RC result = File::move(getCurrentPath(), getRotatedPath());
453*b1cdbd2cSJim Jagielski         if(result!=FileBase::E_None && result!=FileBase::E_NOENT)
454*b1cdbd2cSJim Jagielski             m_Active = false;
455*b1cdbd2cSJim Jagielski     }
456*b1cdbd2cSJim Jagielski 
hotRotate()457*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::hotRotate()
458*b1cdbd2cSJim Jagielski     {
459*b1cdbd2cSJim Jagielski         logRotated();
460*b1cdbd2cSJim Jagielski         m_Logger->removeLogHandler(m_LogHandler);
461*b1cdbd2cSJim Jagielski         m_LogHandler = NULL;
462*b1cdbd2cSJim Jagielski         rotate();
463*b1cdbd2cSJim Jagielski         prepareLogHandler();
464*b1cdbd2cSJim Jagielski         if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is())
465*b1cdbd2cSJim Jagielski         {
466*b1cdbd2cSJim Jagielski             m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY));
467*b1cdbd2cSJim Jagielski             m_LogHandler->setLevel(LogLevel::ALL);
468*b1cdbd2cSJim Jagielski             m_Logger->addLogHandler(m_LogHandler);
469*b1cdbd2cSJim Jagielski         }
470*b1cdbd2cSJim Jagielski         else
471*b1cdbd2cSJim Jagielski             m_Active = false;
472*b1cdbd2cSJim Jagielski     }
473*b1cdbd2cSJim Jagielski 
prepareLogHandler()474*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::prepareLogHandler()
475*b1cdbd2cSJim Jagielski     {
476*b1cdbd2cSJim Jagielski         Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
477*b1cdbd2cSJim Jagielski 
478*b1cdbd2cSJim Jagielski         Sequence<Any> init_args = Sequence<Any>(1);
479*b1cdbd2cSJim Jagielski         init_args[0] = static_cast<Any>(getCurrentPath());
480*b1cdbd2cSJim Jagielski         Reference< XInterface > temp =
481*b1cdbd2cSJim Jagielski             sm->createInstanceWithArguments(CSSL_FILEHANDLER, init_args);
482*b1cdbd2cSJim Jagielski         m_LogHandler = Reference<XLogHandler>(temp, UNO_QUERY);
483*b1cdbd2cSJim Jagielski     }
484*b1cdbd2cSJim Jagielski 
checkIdleTimeout()485*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::checkIdleTimeout()
486*b1cdbd2cSJim Jagielski     {
487*b1cdbd2cSJim Jagielski         TimeValue now;
488*b1cdbd2cSJim Jagielski         osl_getSystemTime(&now);
489*b1cdbd2cSJim Jagielski         if(now.Seconds - m_LastLogEventTime.Seconds > m_IdleTimeout.Seconds && m_SessionLogEventCount>0)
490*b1cdbd2cSJim Jagielski             hotRotate();
491*b1cdbd2cSJim Jagielski         m_LastLogEventTime = now;
492*b1cdbd2cSJim Jagielski     }
493*b1cdbd2cSJim Jagielski 
getCurrentPath()494*b1cdbd2cSJim Jagielski     OUString UiEventsLogger_Impl::getCurrentPath()
495*b1cdbd2cSJim Jagielski     {
496*b1cdbd2cSJim Jagielski         OUStringBuffer current_path(m_LogPath);
497*b1cdbd2cSJim Jagielski         current_path.appendAscii("/");
498*b1cdbd2cSJim Jagielski         current_path.append(FN_CURRENTLOG);
499*b1cdbd2cSJim Jagielski         current_path.appendAscii(".csv");
500*b1cdbd2cSJim Jagielski         return current_path.makeStringAndClear();
501*b1cdbd2cSJim Jagielski     }
502*b1cdbd2cSJim Jagielski 
getRotatedPath()503*b1cdbd2cSJim Jagielski     OUString UiEventsLogger_Impl::getRotatedPath()
504*b1cdbd2cSJim Jagielski     {
505*b1cdbd2cSJim Jagielski         OUStringBuffer rotated_path(m_LogPath);
506*b1cdbd2cSJim Jagielski         rotated_path.appendAscii("/");
507*b1cdbd2cSJim Jagielski         rotated_path.append(FN_ROTATEDLOG);
508*b1cdbd2cSJim Jagielski         rotated_path.appendAscii("-");
509*b1cdbd2cSJim Jagielski         {
510*b1cdbd2cSJim Jagielski             // ISO 8601
511*b1cdbd2cSJim Jagielski             char tsrotated_pathfer[20];
512*b1cdbd2cSJim Jagielski             oslDateTime now;
513*b1cdbd2cSJim Jagielski             TimeValue now_tv;
514*b1cdbd2cSJim Jagielski             osl_getSystemTime(&now_tv);
515*b1cdbd2cSJim Jagielski             osl_getDateTimeFromTimeValue(&now_tv, &now);
516*b1cdbd2cSJim Jagielski             const size_t rotated_pathfer_size = sizeof(tsrotated_pathfer);
517*b1cdbd2cSJim Jagielski             snprintf(tsrotated_pathfer, rotated_pathfer_size, "%04i-%02i-%02iT%02i_%02i_%02i",
518*b1cdbd2cSJim Jagielski                 now.Year,
519*b1cdbd2cSJim Jagielski                 now.Month,
520*b1cdbd2cSJim Jagielski                 now.Day,
521*b1cdbd2cSJim Jagielski                 now.Hours,
522*b1cdbd2cSJim Jagielski                 now.Minutes,
523*b1cdbd2cSJim Jagielski                 now.Seconds);
524*b1cdbd2cSJim Jagielski             rotated_path.appendAscii(tsrotated_pathfer);
525*b1cdbd2cSJim Jagielski             rotated_path.appendAscii(".csv");
526*b1cdbd2cSJim Jagielski         }
527*b1cdbd2cSJim Jagielski         return rotated_path.makeStringAndClear();
528*b1cdbd2cSJim Jagielski     }
529*b1cdbd2cSJim Jagielski 
initializeLogger()530*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::initializeLogger()
531*b1cdbd2cSJim Jagielski     {
532*b1cdbd2cSJim Jagielski         Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
533*b1cdbd2cSJim Jagielski 
534*b1cdbd2cSJim Jagielski         // getting the Core Uno proxy object
535*b1cdbd2cSJim Jagielski         // It will call disposing and make sure we clear all our references
536*b1cdbd2cSJim Jagielski         {
537*b1cdbd2cSJim Jagielski             Reference<XTerminateListener> xCore(
538*b1cdbd2cSJim Jagielski                 sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.Core")),
539*b1cdbd2cSJim Jagielski                 UNO_QUERY);
540*b1cdbd2cSJim Jagielski             Reference<XDesktop> xDesktop(
541*b1cdbd2cSJim Jagielski                 sm->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")),
542*b1cdbd2cSJim Jagielski                 UNO_QUERY);
543*b1cdbd2cSJim Jagielski             if(!(xCore.is() && xDesktop.is()))
544*b1cdbd2cSJim Jagielski             {
545*b1cdbd2cSJim Jagielski                 m_Active = false;
546*b1cdbd2cSJim Jagielski                 return;
547*b1cdbd2cSJim Jagielski             }
548*b1cdbd2cSJim Jagielski             xDesktop->addTerminateListener(xCore);
549*b1cdbd2cSJim Jagielski         }
550*b1cdbd2cSJim Jagielski         // getting the LoggerPool
551*b1cdbd2cSJim Jagielski         Reference<XLoggerPool> pool;
552*b1cdbd2cSJim Jagielski         {
553*b1cdbd2cSJim Jagielski             Reference<XInterface> temp =
554*b1cdbd2cSJim Jagielski                 sm->createInstance(CSSL_LOGGERPOOL);
555*b1cdbd2cSJim Jagielski             pool = Reference<XLoggerPool>(temp, UNO_QUERY);
556*b1cdbd2cSJim Jagielski         }
557*b1cdbd2cSJim Jagielski 
558*b1cdbd2cSJim Jagielski         // getting the Logger
559*b1cdbd2cSJim Jagielski         m_Logger = pool->getNamedLogger(LOGGERNAME);
560*b1cdbd2cSJim Jagielski 
561*b1cdbd2cSJim Jagielski         // getting the FileHandler
562*b1cdbd2cSJim Jagielski         prepareLogHandler();
563*b1cdbd2cSJim Jagielski 
564*b1cdbd2cSJim Jagielski         // getting the Formatter
565*b1cdbd2cSJim Jagielski         {
566*b1cdbd2cSJim Jagielski             Reference<XInterface> temp =
567*b1cdbd2cSJim Jagielski                 sm->createInstance(CSSL_CSVFORMATTER);
568*b1cdbd2cSJim Jagielski             m_Formatter = Reference<XCsvLogFormatter>(temp, UNO_QUERY);
569*b1cdbd2cSJim Jagielski         }
570*b1cdbd2cSJim Jagielski 
571*b1cdbd2cSJim Jagielski         if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is())
572*b1cdbd2cSJim Jagielski         {
573*b1cdbd2cSJim Jagielski             Sequence<OUString> columns = Sequence<OUString>(COLUMNS);
574*b1cdbd2cSJim Jagielski             columns[0] = OUString::createFromAscii("eventtype");
575*b1cdbd2cSJim Jagielski             columns[1] = OUString::createFromAscii("originapp");
576*b1cdbd2cSJim Jagielski             columns[2] = OUString::createFromAscii("originwidget");
577*b1cdbd2cSJim Jagielski             columns[3] = OUString::createFromAscii("uno url");
578*b1cdbd2cSJim Jagielski             columns[4] = OUString::createFromAscii("parent id");
579*b1cdbd2cSJim Jagielski             columns[5] = OUString::createFromAscii("window type");
580*b1cdbd2cSJim Jagielski             columns[6] = OUString::createFromAscii("id");
581*b1cdbd2cSJim Jagielski             columns[7] = OUString::createFromAscii("method");
582*b1cdbd2cSJim Jagielski             columns[8] = OUString::createFromAscii("parameter");
583*b1cdbd2cSJim Jagielski             m_Formatter->setColumnnames(columns);
584*b1cdbd2cSJim Jagielski             m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY));
585*b1cdbd2cSJim Jagielski             m_Logger->setLevel(LogLevel::ALL);
586*b1cdbd2cSJim Jagielski             m_LogHandler->setLevel(LogLevel::ALL);
587*b1cdbd2cSJim Jagielski             m_Logger->addLogHandler(m_LogHandler);
588*b1cdbd2cSJim Jagielski         }
589*b1cdbd2cSJim Jagielski         else
590*b1cdbd2cSJim Jagielski             m_Active = false;
591*b1cdbd2cSJim Jagielski     }
592*b1cdbd2cSJim Jagielski 
593*b1cdbd2cSJim Jagielski     // private static UiEventsLogger_Impl
shouldActivate()594*b1cdbd2cSJim Jagielski     bool UiEventsLogger_Impl::shouldActivate()
595*b1cdbd2cSJim Jagielski     {
596*b1cdbd2cSJim Jagielski         return getEnabledFromCfg() && getEnabledFromCoreController();
597*b1cdbd2cSJim Jagielski     }
598*b1cdbd2cSJim Jagielski 
getLogPathFromCfg()599*b1cdbd2cSJim Jagielski     OUString UiEventsLogger_Impl::getLogPathFromCfg()
600*b1cdbd2cSJim Jagielski     {
601*b1cdbd2cSJim Jagielski         OUString result;
602*b1cdbd2cSJim Jagielski         Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
603*b1cdbd2cSJim Jagielski 
604*b1cdbd2cSJim Jagielski         ConfigurationHelper::readDirectKey(
605*b1cdbd2cSJim Jagielski             sm,
606*b1cdbd2cSJim Jagielski             CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_LOGPATH,
607*b1cdbd2cSJim Jagielski             ConfigurationHelper::E_READONLY
608*b1cdbd2cSJim Jagielski         ) >>= result;
609*b1cdbd2cSJim Jagielski 
610*b1cdbd2cSJim Jagielski         Reference<XStringSubstitution> path_sub(
611*b1cdbd2cSJim Jagielski             sm->createInstance(CSSU_PATHSUB),
612*b1cdbd2cSJim Jagielski             UNO_QUERY);
613*b1cdbd2cSJim Jagielski         if(path_sub.is())
614*b1cdbd2cSJim Jagielski             result = path_sub->substituteVariables(result, sal_False);
615*b1cdbd2cSJim Jagielski         return result;
616*b1cdbd2cSJim Jagielski     }
617*b1cdbd2cSJim Jagielski 
getIdleTimeoutFromCfg()618*b1cdbd2cSJim Jagielski     TimeValue UiEventsLogger_Impl::getIdleTimeoutFromCfg()
619*b1cdbd2cSJim Jagielski     {
620*b1cdbd2cSJim Jagielski         sal_Int32 timeoutminutes = 360;
621*b1cdbd2cSJim Jagielski         Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
622*b1cdbd2cSJim Jagielski 
623*b1cdbd2cSJim Jagielski         ConfigurationHelper::readDirectKey(
624*b1cdbd2cSJim Jagielski             sm,
625*b1cdbd2cSJim Jagielski             CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_IDLETIMEOUT,
626*b1cdbd2cSJim Jagielski             ConfigurationHelper::E_READONLY
627*b1cdbd2cSJim Jagielski         ) >>= timeoutminutes;
628*b1cdbd2cSJim Jagielski         TimeValue result;
629*b1cdbd2cSJim Jagielski         result.Seconds = static_cast<sal_uInt32>(timeoutminutes)*60;
630*b1cdbd2cSJim Jagielski         result.Nanosec = 0;
631*b1cdbd2cSJim Jagielski         return result;
632*b1cdbd2cSJim Jagielski     }
633*b1cdbd2cSJim Jagielski 
getEnabledFromCfg()634*b1cdbd2cSJim Jagielski     bool UiEventsLogger_Impl::getEnabledFromCfg()
635*b1cdbd2cSJim Jagielski     {
636*b1cdbd2cSJim Jagielski         sal_Bool result = false;
637*b1cdbd2cSJim Jagielski         Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
638*b1cdbd2cSJim Jagielski         ConfigurationHelper::readDirectKey(
639*b1cdbd2cSJim Jagielski             sm,
640*b1cdbd2cSJim Jagielski             CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_ENABLED,
641*b1cdbd2cSJim Jagielski             ::comphelper::ConfigurationHelper::E_READONLY
642*b1cdbd2cSJim Jagielski         ) >>= result;
643*b1cdbd2cSJim Jagielski         return result;
644*b1cdbd2cSJim Jagielski     }
645*b1cdbd2cSJim Jagielski 
getEnabledFromCoreController()646*b1cdbd2cSJim Jagielski     bool UiEventsLogger_Impl::getEnabledFromCoreController()
647*b1cdbd2cSJim Jagielski     {
648*b1cdbd2cSJim Jagielski         Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
649*b1cdbd2cSJim Jagielski         Reference<XCoreController> core_c(
650*b1cdbd2cSJim Jagielski             sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.CoreController")),
651*b1cdbd2cSJim Jagielski             UNO_QUERY);
652*b1cdbd2cSJim Jagielski         if(!core_c.is()) return false;
653*b1cdbd2cSJim Jagielski         return core_c->enablingUiEventsLoggerAllowed(1);
654*b1cdbd2cSJim Jagielski     }
655*b1cdbd2cSJim Jagielski 
656*b1cdbd2cSJim Jagielski     UiEventsLogger_Impl::ptr UiEventsLogger_Impl::instance = UiEventsLogger_Impl::ptr();
getInstance()657*b1cdbd2cSJim Jagielski     UiEventsLogger_Impl::ptr UiEventsLogger_Impl::getInstance()
658*b1cdbd2cSJim Jagielski     {
659*b1cdbd2cSJim Jagielski         if(instance == NULL)
660*b1cdbd2cSJim Jagielski             instance = UiEventsLogger_Impl::ptr(new UiEventsLogger_Impl());
661*b1cdbd2cSJim Jagielski         return instance;
662*b1cdbd2cSJim Jagielski     }
663*b1cdbd2cSJim Jagielski 
664*b1cdbd2cSJim Jagielski     Mutex * UiEventsLogger_Impl::singleton_mutex = NULL;
prepareMutex()665*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::prepareMutex()
666*b1cdbd2cSJim Jagielski     {
667*b1cdbd2cSJim Jagielski         if(singleton_mutex == NULL)
668*b1cdbd2cSJim Jagielski         {
669*b1cdbd2cSJim Jagielski             Guard<Mutex> global_guard(Mutex::getGlobalMutex());
670*b1cdbd2cSJim Jagielski             if(singleton_mutex == NULL)
671*b1cdbd2cSJim Jagielski                 singleton_mutex = new Mutex();
672*b1cdbd2cSJim Jagielski         }
673*b1cdbd2cSJim Jagielski     }
674*b1cdbd2cSJim Jagielski 
findIdx(const Sequence<PropertyValue> & args,const OUString & key)675*b1cdbd2cSJim Jagielski     sal_Int32 UiEventsLogger_Impl::findIdx(const Sequence<PropertyValue>& args, const OUString& key)
676*b1cdbd2cSJim Jagielski     {
677*b1cdbd2cSJim Jagielski         for(sal_Int32 i=0; i<args.getLength(); i++)
678*b1cdbd2cSJim Jagielski             if(args[i].Name == key)
679*b1cdbd2cSJim Jagielski                 return i;
680*b1cdbd2cSJim Jagielski         return -1;
681*b1cdbd2cSJim Jagielski     }
682*b1cdbd2cSJim Jagielski 
disposing()683*b1cdbd2cSJim Jagielski     void UiEventsLogger_Impl::disposing()
684*b1cdbd2cSJim Jagielski     {
685*b1cdbd2cSJim Jagielski         m_Active = false;
686*b1cdbd2cSJim Jagielski         m_Logger.clear() ;
687*b1cdbd2cSJim Jagielski         m_LogHandler.clear();
688*b1cdbd2cSJim Jagielski         m_Formatter.clear();
689*b1cdbd2cSJim Jagielski     }
690*b1cdbd2cSJim Jagielski }
691