1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25  ************************************************************************/
26 
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_extensions.hxx"
29 
30 #include "onlogrotate_job.hxx"
31 #include "config.hxx"
32 #include "logpacker.hxx"
33 #include "logstorage.hxx"
34 #include "soaprequest.hxx"
35 #include "soapsender.hxx"
36 
37 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
38 #include <com/sun/star/frame/XDesktop.hpp>
39 #include <com/sun/star/frame/XTerminateListener.hpp>
40 #include <osl/conditn.hxx>
41 #include <osl/thread.hxx>
42 #include <osl/time.h>
43 #include <cppuhelper/implbase1.hxx>
44 #include <memory>
45 
46 
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::task;
50 using namespace ::com::sun::star::uno;
51 using ::com::sun::star::frame::XTerminateListener;
52 using ::com::sun::star::frame::XDesktop;
53 using ::com::sun::star::ucb::XSimpleFileAccess;
54 using ::rtl::OUString;
55 using ::std::vector;
56 
57 namespace
58 {
59     using namespace oooimprovement;
60 
61     static void packLogs(const Reference<XMultiServiceFactory>& sf)
62     {
63         try
64         {
65             Config config(sf);
66             LogPacker log_packer(sf);
67             vector<OUString> csvfiles = LogStorage(sf).getUnzippedLogFiles();
68             for(
69                 vector<OUString>::iterator item = csvfiles.begin();
70                 item!=csvfiles.end();
71                 item++)
72                 config.incrementEventCount(log_packer.pack(*item));
73         } catch(...) {};
74     };
75 
76     static void uploadLogs(const Reference<XMultiServiceFactory>& sf)
77     {
78         try
79         {
80             Config config(sf);
81             Reference<XSimpleFileAccess> file_access(
82                 sf->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")),
83                 UNO_QUERY_THROW);
84             SoapSender sender(sf, config.getSoapUrl());
85             OUString soap_id = config.getSoapId();
86             vector<OUString> zipfiles = LogStorage(sf).getZippedLogFiles();
87             for(
88                 vector<OUString>::iterator item = zipfiles.begin();
89                 item!=zipfiles.end();
90                 item++)
91             {
92                 if(config.incrementFailedAttempts(1) > 25)
93                 {
94                     config.giveupUploading();
95                     LogStorage(sf).clear();
96                     return;
97                 }
98                 sender.send(SoapRequest(sf, soap_id, *item));
99                 config.incrementReportCount(1);
100                 file_access->kill(*item);
101                 config.resetFailedAttempts();
102             }
103         } catch(...) {};
104     }
105 
106     class OnLogRotateThread : public ::osl::Thread
107     {
108         public:
109             OnLogRotateThread(Reference<XMultiServiceFactory> sf);
110             virtual void SAL_CALL run();
111             void stop();
112 
113         private:
114             Reference<XMultiServiceFactory> m_ServiceFactory;
115             ::osl::Condition m_Stop;
116     };
117 
118     OnLogRotateThread::OnLogRotateThread(Reference<XMultiServiceFactory> sf)
119         : m_ServiceFactory(sf)
120     {
121         OSL_ASSERT(sf.is());
122     }
123 
124     void SAL_CALL OnLogRotateThread::run()
125     {
126         TimeValue wait_intervall = {30,0};
127         if (m_Stop.wait(&wait_intervall) == ::osl::Condition::result_timeout)
128         {
129             try
130             {
131                 if(Config(m_ServiceFactory).getInvitationAccepted())
132                 {
133                     packLogs(m_ServiceFactory);
134                     uploadLogs(m_ServiceFactory);
135                 }
136                 else
137                     LogStorage(m_ServiceFactory).clear();
138             }
139             catch(...) {}
140         }
141     }
142 
143     void OnLogRotateThread::stop()
144     {
145         m_Stop.set();
146     }
147 
148     class OnLogRotateThreadWatcher : public ::cppu::WeakImplHelper1<XTerminateListener>
149     {
150         public:
151             OnLogRotateThreadWatcher(Reference<XMultiServiceFactory> sf)
152                 : m_Thread(new OnLogRotateThread(sf))
153             {
154                 m_Thread->create();
155             }
156             virtual ~OnLogRotateThreadWatcher()
157             {
158                 m_Thread->stop();
159                 m_Thread->join();
160             };
161 
162             // XTerminateListener
163             virtual void SAL_CALL queryTermination(const EventObject&) throw(RuntimeException)
164                 { };
165             virtual void SAL_CALL notifyTermination(const EventObject&) throw(RuntimeException)
166             {
167                 m_Thread->stop();
168                 m_Thread->join();
169             };
170             // XEventListener
171             virtual void SAL_CALL disposing(const EventObject&) throw(RuntimeException)
172             {
173                 m_Thread->stop();
174                 m_Thread->join();
175             };
176         private:
177             ::std::auto_ptr<OnLogRotateThread> m_Thread;
178     };
179 }
180 
181 namespace oooimprovement
182 {
183     OnLogRotateJob::OnLogRotateJob(const Reference<XComponentContext>& context)
184         : m_ServiceFactory(Reference<XMultiServiceFactory>(
185             context->getServiceManager()->createInstanceWithContext(
186                 OUString::createFromAscii("com.sun.star.lang.XMultiServiceFactory"), context),
187             UNO_QUERY))
188     { }
189 
190     OnLogRotateJob::OnLogRotateJob(const Reference<XMultiServiceFactory>& sf)
191         : m_ServiceFactory(sf)
192     { }
193 
194     OnLogRotateJob::~OnLogRotateJob()
195     { }
196 
197     void SAL_CALL OnLogRotateJob::executeAsync(
198         const Sequence<NamedValue>&,
199         const Reference<XJobListener>& listener)
200         throw(RuntimeException)
201     {
202         Reference<XDesktop> xDesktop(
203             m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")),
204             UNO_QUERY);
205         if(xDesktop.is())
206             xDesktop->addTerminateListener(Reference<XTerminateListener>(new OnLogRotateThreadWatcher(m_ServiceFactory)));
207         Any result;
208         listener->jobFinished(Reference<XAsyncJob>(this), result);
209     }
210 
211     sal_Bool SAL_CALL OnLogRotateJob::supportsService(const OUString& service_name) throw(RuntimeException)
212     {
213         const Sequence<OUString> service_names(getSupportedServiceNames());
214         for (sal_Int32 idx = service_names.getLength()-1; idx>=0; --idx)
215             if(service_name == service_names[idx]) return sal_True;
216         return sal_False;
217     }
218 
219     OUString SAL_CALL OnLogRotateJob::getImplementationName() throw(RuntimeException)
220     { return getImplementationName_static(); }
221 
222     Sequence<OUString> SAL_CALL OnLogRotateJob::getSupportedServiceNames() throw(RuntimeException)
223     { return getSupportedServiceNames_static(); }
224 
225     OUString SAL_CALL OnLogRotateJob::getImplementationName_static()
226     { return OUString::createFromAscii("com.sun.star.comp.extensions.oooimprovement.OnLogRotateJob"); }
227 
228     Sequence<OUString> SAL_CALL OnLogRotateJob::getSupportedServiceNames_static()
229     {
230         Sequence<OUString> aServiceNames(1);
231         aServiceNames[0] = OUString::createFromAscii("com.sun.star.task.AsyncJob");
232         return aServiceNames;
233     }
234 
235     Reference<XInterface> OnLogRotateJob::Create(const Reference<XComponentContext>& context)
236     { return *(new OnLogRotateJob(context)); }
237 
238     Reference<XInterface> OnLogRotateJob::Create(const Reference<XMultiServiceFactory>& sf)
239     { return *(new OnLogRotateJob(sf)); }
240 }
241