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 #include "precompiled_sd.hxx"
25
26 #include "ChangeRequestQueueProcessor.hxx"
27 #include "ConfigurationTracer.hxx"
28
29 #include "framework/ConfigurationController.hxx"
30 #include "ConfigurationUpdater.hxx"
31
32 #include <vcl/svapp.hxx>
33 #include <com/sun/star/container/XNamed.hpp>
34 #include <com/sun/star/drawing/framework/XConfiguration.hpp>
35 #include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp>
36
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::drawing::framework;
40
41 #undef VERBOSE
42 //#define VERBOSE 1
43
44 namespace {
45
46 #ifdef VERBOSE
47
TraceRequest(const Reference<XConfigurationChangeRequest> & rxRequest)48 void TraceRequest (const Reference<XConfigurationChangeRequest>& rxRequest)
49 {
50 Reference<container::XNamed> xNamed (rxRequest, UNO_QUERY);
51 if (xNamed.is())
52 OSL_TRACE(" %s\n",
53 ::rtl::OUStringToOString(xNamed->getName(), RTL_TEXTENCODING_UTF8).getStr());
54 }
55
56 #endif
57
58 } // end of anonymous namespace
59
60
61 namespace sd { namespace framework {
62
ChangeRequestQueueProcessor(const::rtl::Reference<ConfigurationController> & rpConfigurationController,const::boost::shared_ptr<ConfigurationUpdater> & rpConfigurationUpdater)63 ChangeRequestQueueProcessor::ChangeRequestQueueProcessor (
64 const ::rtl::Reference<ConfigurationController>& rpConfigurationController,
65 const ::boost::shared_ptr<ConfigurationUpdater>& rpConfigurationUpdater)
66 : maMutex(),
67 maQueue(),
68 mnUserEventId(0),
69 mxConfiguration(),
70 mpConfigurationController(rpConfigurationController),
71 mpConfigurationUpdater(rpConfigurationUpdater)
72 {
73 }
74
75
76
77
~ChangeRequestQueueProcessor(void)78 ChangeRequestQueueProcessor::~ChangeRequestQueueProcessor (void)
79 {
80 if (mnUserEventId != 0)
81 Application::RemoveUserEvent(mnUserEventId);
82 }
83
84
85
86
SetConfiguration(const Reference<XConfiguration> & rxConfiguration)87 void ChangeRequestQueueProcessor::SetConfiguration (
88 const Reference<XConfiguration>& rxConfiguration)
89 {
90 ::osl::MutexGuard aGuard (maMutex);
91
92 mxConfiguration = rxConfiguration;
93 StartProcessing();
94 }
95
96
97
98
AddRequest(const Reference<XConfigurationChangeRequest> & rxRequest)99 void ChangeRequestQueueProcessor::AddRequest (
100 const Reference<XConfigurationChangeRequest>& rxRequest)
101 {
102 ::osl::MutexGuard aGuard (maMutex);
103
104 #ifdef VERBOSE
105 if (maQueue.empty())
106 {
107 OSL_TRACE("Adding requests to empty queue\n");
108 ConfigurationTracer::TraceConfiguration(
109 mxConfiguration, "current configuration of queue processor");
110 }
111 OSL_TRACE("Adding request\n");
112 TraceRequest(rxRequest);
113 #endif
114
115 maQueue.push_back(rxRequest);
116 StartProcessing();
117 }
118
119
120
121
StartProcessing(void)122 void ChangeRequestQueueProcessor::StartProcessing (void)
123 {
124 ::osl::MutexGuard aGuard (maMutex);
125
126 if (mnUserEventId == 0
127 && mxConfiguration.is()
128 && ! maQueue.empty())
129 {
130 #ifdef VERBOSE
131 OSL_TRACE("ChangeRequestQueueProcessor scheduling processing\n");
132 #endif
133 mnUserEventId = Application::PostUserEvent(
134 LINK(this,ChangeRequestQueueProcessor,ProcessEvent));
135 }
136 }
137
138
139
140
IMPL_LINK(ChangeRequestQueueProcessor,ProcessEvent,void *,pUnused)141 IMPL_LINK(ChangeRequestQueueProcessor, ProcessEvent, void*, pUnused)
142 {
143 (void)pUnused;
144
145 ::osl::MutexGuard aGuard (maMutex);
146
147 mnUserEventId = 0;
148
149 ProcessOneEvent();
150
151 if ( ! maQueue.empty())
152 {
153 // Schedule the processing of the next event.
154 StartProcessing();
155 }
156
157 return 0;
158 }
159
160
161
162
ProcessOneEvent(void)163 void ChangeRequestQueueProcessor::ProcessOneEvent (void)
164 {
165 ::osl::MutexGuard aGuard (maMutex);
166
167 #ifdef VERBOSE
168 OSL_TRACE("ProcessOneEvent\n");
169 #endif
170
171 if (mxConfiguration.is()
172 && ! maQueue.empty())
173 {
174 // Get and remove the first entry from the queue.
175 Reference<XConfigurationChangeRequest> xRequest (maQueue.front());
176 maQueue.pop_front();
177
178 // Execute the change request.
179 if (xRequest.is())
180 {
181 #ifdef VERBOSE
182 TraceRequest(xRequest);
183 #endif
184 xRequest->execute(mxConfiguration);
185 }
186
187 if (maQueue.empty())
188 {
189 #ifdef VERBOSE
190 OSL_TRACE("All requests are processed\n");
191 #endif
192 // The queue is empty so tell the ConfigurationManager to update
193 // its state.
194 if (mpConfigurationUpdater.get() != NULL)
195 {
196 #ifdef VERBOSE
197 ConfigurationTracer::TraceConfiguration (
198 mxConfiguration, "updating to configuration");
199 #endif
200 mpConfigurationUpdater->RequestUpdate(mxConfiguration);
201 }
202 }
203 }
204 }
205
206
207
208
IsEmpty(void) const209 bool ChangeRequestQueueProcessor::IsEmpty (void) const
210 {
211 return maQueue.empty();
212 }
213
214
215
216
ProcessUntilEmpty(void)217 void ChangeRequestQueueProcessor::ProcessUntilEmpty (void)
218 {
219 while ( ! IsEmpty())
220 ProcessOneEvent();
221 }
222
223
224
225
Clear(void)226 void ChangeRequestQueueProcessor::Clear (void)
227 {
228 ::osl::MutexGuard aGuard (maMutex);
229 maQueue.clear();
230 }
231
232
233 } } // end of namespace sd::framework::configuration
234