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 "onlogrotate_job.hxx"
28 #include "config.hxx"
29 #include "logpacker.hxx"
30 #include "logstorage.hxx"
31 #include "soaprequest.hxx"
32 #include "soapsender.hxx"
33 
34 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
35 #include <com/sun/star/frame/XDesktop.hpp>
36 #include <com/sun/star/frame/XTerminateListener.hpp>
37 #include <osl/conditn.hxx>
38 #include <osl/thread.hxx>
39 #include <osl/time.h>
40 #include <cppuhelper/implbase1.hxx>
41 #include <memory>
42 
43 
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::task;
47 using namespace ::com::sun::star::uno;
48 using ::com::sun::star::frame::XTerminateListener;
49 using ::com::sun::star::frame::XDesktop;
50 using ::com::sun::star::ucb::XSimpleFileAccess;
51 using ::rtl::OUString;
52 using ::std::vector;
53 
54 namespace
55 {
56     using namespace oooimprovement;
57 
packLogs(const Reference<XMultiServiceFactory> & sf)58     static void packLogs(const Reference<XMultiServiceFactory>& sf)
59     {
60         try
61         {
62             Config config(sf);
63             LogPacker log_packer(sf);
64             vector<OUString> csvfiles = LogStorage(sf).getUnzippedLogFiles();
65             for(
66                 vector<OUString>::iterator item = csvfiles.begin();
67                 item!=csvfiles.end();
68                 item++)
69                 config.incrementEventCount(log_packer.pack(*item));
70         } catch(...) {};
71     };
72 
uploadLogs(const Reference<XMultiServiceFactory> & sf)73     static void uploadLogs(const Reference<XMultiServiceFactory>& sf)
74     {
75         try
76         {
77             Config config(sf);
78             Reference<XSimpleFileAccess> file_access(
79                 sf->createInstance(OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess")),
80                 UNO_QUERY_THROW);
81             SoapSender sender(sf, config.getSoapUrl());
82             OUString soap_id = config.getSoapId();
83             vector<OUString> zipfiles = LogStorage(sf).getZippedLogFiles();
84             for(
85                 vector<OUString>::iterator item = zipfiles.begin();
86                 item!=zipfiles.end();
87                 item++)
88             {
89                 if(config.incrementFailedAttempts(1) > 25)
90                 {
91                     config.giveupUploading();
92                     LogStorage(sf).clear();
93                     return;
94                 }
95                 sender.send(SoapRequest(sf, soap_id, *item));
96                 config.incrementReportCount(1);
97                 file_access->kill(*item);
98                 config.resetFailedAttempts();
99             }
100         } catch(...) {};
101     }
102 
103     class OnLogRotateThread : public ::osl::Thread
104     {
105         public:
106             OnLogRotateThread(Reference<XMultiServiceFactory> sf);
107             virtual void SAL_CALL run();
108             void stop();
109 
110         private:
111             Reference<XMultiServiceFactory> m_ServiceFactory;
112             ::osl::Condition m_Stop;
113     };
114 
OnLogRotateThread(Reference<XMultiServiceFactory> sf)115     OnLogRotateThread::OnLogRotateThread(Reference<XMultiServiceFactory> sf)
116         : m_ServiceFactory(sf)
117     {
118         OSL_ASSERT(sf.is());
119     }
120 
run()121     void SAL_CALL OnLogRotateThread::run()
122     {
123         TimeValue wait_intervall = {30,0};
124         if (m_Stop.wait(&wait_intervall) == ::osl::Condition::result_timeout)
125         {
126             try
127             {
128                 if(Config(m_ServiceFactory).getInvitationAccepted())
129                 {
130                     packLogs(m_ServiceFactory);
131                     uploadLogs(m_ServiceFactory);
132                 }
133                 else
134                     LogStorage(m_ServiceFactory).clear();
135             }
136             catch(...) {}
137         }
138     }
139 
stop()140     void OnLogRotateThread::stop()
141     {
142         m_Stop.set();
143     }
144 
145     class OnLogRotateThreadWatcher : public ::cppu::WeakImplHelper1<XTerminateListener>
146     {
147         public:
OnLogRotateThreadWatcher(Reference<XMultiServiceFactory> sf)148             OnLogRotateThreadWatcher(Reference<XMultiServiceFactory> sf)
149                 : m_Thread(new OnLogRotateThread(sf))
150             {
151                 m_Thread->create();
152             }
~OnLogRotateThreadWatcher()153             virtual ~OnLogRotateThreadWatcher()
154             {
155                 m_Thread->stop();
156                 m_Thread->join();
157             };
158 
159             // XTerminateListener
queryTermination(const EventObject &)160             virtual void SAL_CALL queryTermination(const EventObject&) throw(RuntimeException)
161                 { };
notifyTermination(const EventObject &)162             virtual void SAL_CALL notifyTermination(const EventObject&) throw(RuntimeException)
163             {
164                 m_Thread->stop();
165                 m_Thread->join();
166             };
167             // XEventListener
disposing(const EventObject &)168             virtual void SAL_CALL disposing(const EventObject&) throw(RuntimeException)
169             {
170                 m_Thread->stop();
171                 m_Thread->join();
172             };
173         private:
174             ::std::auto_ptr<OnLogRotateThread> m_Thread;
175     };
176 }
177 
178 namespace oooimprovement
179 {
OnLogRotateJob(const Reference<XComponentContext> & context)180     OnLogRotateJob::OnLogRotateJob(const Reference<XComponentContext>& context)
181         : m_ServiceFactory(Reference<XMultiServiceFactory>(
182             context->getServiceManager()->createInstanceWithContext(
183                 OUString::createFromAscii("com.sun.star.lang.XMultiServiceFactory"), context),
184             UNO_QUERY))
185     { }
186 
OnLogRotateJob(const Reference<XMultiServiceFactory> & sf)187     OnLogRotateJob::OnLogRotateJob(const Reference<XMultiServiceFactory>& sf)
188         : m_ServiceFactory(sf)
189     { }
190 
~OnLogRotateJob()191     OnLogRotateJob::~OnLogRotateJob()
192     { }
193 
executeAsync(const Sequence<NamedValue> &,const Reference<XJobListener> & listener)194     void SAL_CALL OnLogRotateJob::executeAsync(
195         const Sequence<NamedValue>&,
196         const Reference<XJobListener>& listener)
197         throw(RuntimeException)
198     {
199         Reference<XDesktop> xDesktop(
200             m_ServiceFactory->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")),
201             UNO_QUERY);
202         if(xDesktop.is())
203             xDesktop->addTerminateListener(Reference<XTerminateListener>(new OnLogRotateThreadWatcher(m_ServiceFactory)));
204         Any result;
205         listener->jobFinished(Reference<XAsyncJob>(this), result);
206     }
207 
supportsService(const OUString & service_name)208     sal_Bool SAL_CALL OnLogRotateJob::supportsService(const OUString& service_name) throw(RuntimeException)
209     {
210         const Sequence<OUString> service_names(getSupportedServiceNames());
211         for (sal_Int32 idx = service_names.getLength()-1; idx>=0; --idx)
212             if(service_name == service_names[idx]) return sal_True;
213         return sal_False;
214     }
215 
getImplementationName()216     OUString SAL_CALL OnLogRotateJob::getImplementationName() throw(RuntimeException)
217     { return getImplementationName_static(); }
218 
getSupportedServiceNames()219     Sequence<OUString> SAL_CALL OnLogRotateJob::getSupportedServiceNames() throw(RuntimeException)
220     { return getSupportedServiceNames_static(); }
221 
getImplementationName_static()222     OUString SAL_CALL OnLogRotateJob::getImplementationName_static()
223     { return OUString::createFromAscii("com.sun.star.comp.extensions.oooimprovement.OnLogRotateJob"); }
224 
getSupportedServiceNames_static()225     Sequence<OUString> SAL_CALL OnLogRotateJob::getSupportedServiceNames_static()
226     {
227         Sequence<OUString> aServiceNames(1);
228         aServiceNames[0] = OUString::createFromAscii("com.sun.star.task.AsyncJob");
229         return aServiceNames;
230     }
231 
Create(const Reference<XComponentContext> & context)232     Reference<XInterface> OnLogRotateJob::Create(const Reference<XComponentContext>& context)
233     { return *(new OnLogRotateJob(context)); }
234 
Create(const Reference<XMultiServiceFactory> & sf)235     Reference<XInterface> OnLogRotateJob::Create(const Reference<XMultiServiceFactory>& sf)
236     { return *(new OnLogRotateJob(sf)); }
237 }
238