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_configmgr.hxx"
25 #include "sal/config.h"
26 
27 #include "com/sun/star/beans/XPropertiesChangeListener.hpp"
28 #include "com/sun/star/beans/XPropertyChangeListener.hpp"
29 #include "com/sun/star/container/XContainerListener.hpp"
30 #include "com/sun/star/lang/DisposedException.hpp"
31 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
32 #include "com/sun/star/lang/XEventListener.hpp"
33 #include "com/sun/star/uno/Any.hxx"
34 #include "com/sun/star/uno/Exception.hpp"
35 #include "com/sun/star/uno/Reference.hxx"
36 #include "com/sun/star/uno/XInterface.hpp"
37 #include "com/sun/star/util/XChangesListener.hpp"
38 #include "cppuhelper/exc_hlp.hxx"
39 #include "osl/diagnose.hxx"
40 #include "rtl/string.h"
41 #include "rtl/ustrbuf.hxx"
42 #include "rtl/ustring.h"
43 #include "rtl/ustring.hxx"
44 
45 #include "broadcaster.hxx"
46 
47 namespace configmgr {
48 
49 namespace {
50 
51 namespace css = com::sun::star;
52 
appendMessage(rtl::OUStringBuffer & buffer,css::uno::Exception const & exception)53 void appendMessage(
54     rtl::OUStringBuffer & buffer, css::uno::Exception const & exception)
55 {
56     buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("; "));
57     buffer.append(exception.Message);
58 }
59 
60 }
61 
addDisposeNotification(css::uno::Reference<css::lang::XEventListener> const & listener,css::lang::EventObject const & event)62 void Broadcaster::addDisposeNotification(
63     css::uno::Reference< css::lang::XEventListener > const & listener,
64     css::lang::EventObject const & event)
65 {
66     disposeNotifications_.push_back(DisposeNotification(listener, event));
67 }
68 
addContainerElementReplacedNotification(css::uno::Reference<css::container::XContainerListener> const & listener,css::container::ContainerEvent const & event)69 void Broadcaster::addContainerElementReplacedNotification(
70     css::uno::Reference< css::container::XContainerListener > const & listener,
71     css::container::ContainerEvent const & event)
72 {
73     containerElementReplacedNotifications_.push_back(
74         ContainerNotification(listener, event));
75 }
76 
addContainerElementInsertedNotification(css::uno::Reference<css::container::XContainerListener> const & listener,css::container::ContainerEvent const & event)77 void Broadcaster::addContainerElementInsertedNotification(
78     css::uno::Reference< css::container::XContainerListener > const & listener,
79     css::container::ContainerEvent const & event)
80 {
81     containerElementInsertedNotifications_.push_back(
82         ContainerNotification(listener, event));
83 }
84 
addContainerElementRemovedNotification(css::uno::Reference<css::container::XContainerListener> const & listener,css::container::ContainerEvent const & event)85 void Broadcaster::addContainerElementRemovedNotification(
86     css::uno::Reference< css::container::XContainerListener > const & listener,
87     css::container::ContainerEvent const & event)
88 {
89     containerElementRemovedNotifications_.push_back(
90         ContainerNotification(listener, event));
91 }
92 
addPropertyChangeNotification(css::uno::Reference<css::beans::XPropertyChangeListener> const & listener,css::beans::PropertyChangeEvent const & event)93 void Broadcaster::addPropertyChangeNotification(
94     css::uno::Reference< css::beans::XPropertyChangeListener > const & listener,
95     css::beans::PropertyChangeEvent const & event)
96 {
97     propertyChangeNotifications_.push_back(
98         PropertyChangeNotification(listener, event));
99 }
100 
addPropertiesChangeNotification(css::uno::Reference<css::beans::XPropertiesChangeListener> const & listener,css::uno::Sequence<css::beans::PropertyChangeEvent> const & event)101 void Broadcaster::addPropertiesChangeNotification(
102     css::uno::Reference< css::beans::XPropertiesChangeListener > const &
103         listener,
104     css::uno::Sequence< css::beans::PropertyChangeEvent > const & event)
105 {
106     propertiesChangeNotifications_.push_back(
107         PropertiesChangeNotification(listener, event));
108 }
109 
addChangesNotification(css::uno::Reference<css::util::XChangesListener> const & listener,css::util::ChangesEvent const & event)110 void Broadcaster::addChangesNotification(
111     css::uno::Reference< css::util::XChangesListener > const & listener,
112     css::util::ChangesEvent const & event)
113 {
114     changesNotifications_.push_back(ChangesNotification(listener, event));
115 }
116 
send()117 void Broadcaster::send() {
118     css::uno::Any exception;
119     rtl::OUStringBuffer messages;
120     for (DisposeNotifications::iterator i(disposeNotifications_.begin());
121          i != disposeNotifications_.end(); ++i) {
122         try {
123             i->listener->disposing(i->event);
124         } catch (css::lang::DisposedException &) {
125         } catch (css::uno::Exception & e) {
126             exception = cppu::getCaughtException();
127             appendMessage(messages, e);
128         }
129     }
130     for (ContainerNotifications::iterator i(
131              containerElementInsertedNotifications_.begin());
132          i != containerElementInsertedNotifications_.end(); ++i)
133     {
134         try {
135             i->listener->elementInserted(i->event);
136         } catch (css::lang::DisposedException &) {
137         } catch (css::uno::Exception & e) {
138             exception = cppu::getCaughtException();
139             appendMessage(messages, e);
140         }
141     }
142     for (ContainerNotifications::iterator i(
143              containerElementRemovedNotifications_.begin());
144          i != containerElementRemovedNotifications_.end(); ++i)
145     {
146         try {
147             i->listener->elementRemoved(i->event);
148         } catch (css::lang::DisposedException &) {
149         } catch (css::uno::Exception & e) {
150             exception = cppu::getCaughtException();
151             appendMessage(messages, e);
152         }
153     }
154     for (ContainerNotifications::iterator i(
155              containerElementReplacedNotifications_.begin());
156          i != containerElementReplacedNotifications_.end(); ++i)
157     {
158         try {
159             i->listener->elementReplaced(i->event);
160         } catch (css::lang::DisposedException &) {
161         } catch (css::uno::Exception & e) {
162             exception = cppu::getCaughtException();
163             appendMessage(messages, e);
164         }
165     }
166     for (PropertyChangeNotifications::iterator i(
167              propertyChangeNotifications_.begin());
168          i != propertyChangeNotifications_.end(); ++i)
169     {
170         try {
171             i->listener->propertyChange(i->event);
172         } catch (css::lang::DisposedException &) {
173         } catch (css::uno::Exception & e) {
174             exception = cppu::getCaughtException();
175             appendMessage(messages, e);
176         }
177     }
178     for (PropertiesChangeNotifications::iterator i(
179              propertiesChangeNotifications_.begin());
180          i != propertiesChangeNotifications_.end(); ++i)
181     {
182         try {
183             i->listener->propertiesChange(i->event);
184         } catch (css::lang::DisposedException &) {
185         } catch (css::uno::Exception & e) {
186             exception = cppu::getCaughtException();
187             appendMessage(messages, e);
188         }
189     }
190     for (ChangesNotifications::iterator i(changesNotifications_.begin());
191          i != changesNotifications_.end(); ++i) {
192         try {
193             i->listener->changesOccurred(i->event);
194         } catch (css::lang::DisposedException &) {
195         } catch (css::uno::Exception & e) {
196             exception = cppu::getCaughtException();
197             appendMessage(messages, e);
198         }
199     }
200     if (exception.hasValue()) {
201         throw css::lang::WrappedTargetRuntimeException(
202             (rtl::OUString(
203                 RTL_CONSTASCII_USTRINGPARAM(
204                     "configmgr exceptions during listener notification")) +
205              messages.makeStringAndClear()),
206             css::uno::Reference< css::uno::XInterface >(),
207             exception);
208     }
209 }
210 
DisposeNotification(css::uno::Reference<css::lang::XEventListener> const & theListener,css::lang::EventObject const & theEvent)211 Broadcaster::DisposeNotification::DisposeNotification(
212     css::uno::Reference< css::lang::XEventListener > const & theListener,
213     css::lang::EventObject const & theEvent):
214     listener(theListener), event(theEvent)
215 {
216     OSL_ASSERT(theListener.is());
217 }
218 
ContainerNotification(css::uno::Reference<css::container::XContainerListener> const & theListener,css::container::ContainerEvent const & theEvent)219 Broadcaster::ContainerNotification::ContainerNotification(
220     css::uno::Reference< css::container::XContainerListener > const &
221         theListener,
222     css::container::ContainerEvent const & theEvent):
223     listener(theListener), event(theEvent)
224 {
225     OSL_ASSERT(theListener.is());
226 }
227 
PropertyChangeNotification(css::uno::Reference<css::beans::XPropertyChangeListener> const & theListener,css::beans::PropertyChangeEvent const & theEvent)228 Broadcaster::PropertyChangeNotification::PropertyChangeNotification(
229     css::uno::Reference< css::beans::XPropertyChangeListener > const &
230         theListener,
231     css::beans::PropertyChangeEvent const & theEvent):
232     listener(theListener), event(theEvent)
233 {
234     OSL_ASSERT(theListener.is());
235 }
236 
PropertiesChangeNotification(css::uno::Reference<css::beans::XPropertiesChangeListener> const & theListener,css::uno::Sequence<css::beans::PropertyChangeEvent> const & theEvent)237 Broadcaster::PropertiesChangeNotification::PropertiesChangeNotification(
238     css::uno::Reference< css::beans::XPropertiesChangeListener > const &
239         theListener,
240     css::uno::Sequence< css::beans::PropertyChangeEvent > const & theEvent):
241     listener(theListener), event(theEvent)
242 {
243     OSL_ASSERT(theListener.is());
244 }
245 
ChangesNotification(css::uno::Reference<css::util::XChangesListener> const & theListener,css::util::ChangesEvent const & theEvent)246 Broadcaster::ChangesNotification::ChangesNotification(
247     css::uno::Reference< css::util::XChangesListener > const & theListener,
248     css::util::ChangesEvent const & theEvent):
249     listener(theListener), event(theEvent)
250 {
251     OSL_ASSERT(theListener.is());
252 }
253 
254 }
255