1 /*************************************************************************
2 *
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 *
7 * OpenOffice.org - a multi-platform office productivity suite
8 *
9 * This file is part of OpenOffice.org.
10 *
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
14 *
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org.  If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
25 *
26 ************************************************************************/
27 
28 #include "precompiled_configmgr.hxx"
29 #include "sal/config.h"
30 
31 #include "com/sun/star/beans/XPropertiesChangeListener.hpp"
32 #include "com/sun/star/beans/XPropertyChangeListener.hpp"
33 #include "com/sun/star/container/XContainerListener.hpp"
34 #include "com/sun/star/lang/DisposedException.hpp"
35 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
36 #include "com/sun/star/lang/XEventListener.hpp"
37 #include "com/sun/star/uno/Any.hxx"
38 #include "com/sun/star/uno/Exception.hpp"
39 #include "com/sun/star/uno/Reference.hxx"
40 #include "com/sun/star/uno/XInterface.hpp"
41 #include "com/sun/star/util/XChangesListener.hpp"
42 #include "cppuhelper/exc_hlp.hxx"
43 #include "osl/diagnose.hxx"
44 #include "rtl/string.h"
45 #include "rtl/ustrbuf.hxx"
46 #include "rtl/ustring.h"
47 #include "rtl/ustring.hxx"
48 
49 #include "broadcaster.hxx"
50 
51 namespace configmgr {
52 
53 namespace {
54 
55 namespace css = com::sun::star;
56 
57 void appendMessage(
58     rtl::OUStringBuffer & buffer, css::uno::Exception const & exception)
59 {
60     buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("; "));
61     buffer.append(exception.Message);
62 }
63 
64 }
65 
66 void Broadcaster::addDisposeNotification(
67     css::uno::Reference< css::lang::XEventListener > const & listener,
68     css::lang::EventObject const & event)
69 {
70     disposeNotifications_.push_back(DisposeNotification(listener, event));
71 }
72 
73 void Broadcaster::addContainerElementReplacedNotification(
74     css::uno::Reference< css::container::XContainerListener > const & listener,
75     css::container::ContainerEvent const & event)
76 {
77     containerElementReplacedNotifications_.push_back(
78         ContainerNotification(listener, event));
79 }
80 
81 void Broadcaster::addContainerElementInsertedNotification(
82     css::uno::Reference< css::container::XContainerListener > const & listener,
83     css::container::ContainerEvent const & event)
84 {
85     containerElementInsertedNotifications_.push_back(
86         ContainerNotification(listener, event));
87 }
88 
89 void Broadcaster::addContainerElementRemovedNotification(
90     css::uno::Reference< css::container::XContainerListener > const & listener,
91     css::container::ContainerEvent const & event)
92 {
93     containerElementRemovedNotifications_.push_back(
94         ContainerNotification(listener, event));
95 }
96 
97 void Broadcaster::addPropertyChangeNotification(
98     css::uno::Reference< css::beans::XPropertyChangeListener > const & listener,
99     css::beans::PropertyChangeEvent const & event)
100 {
101     propertyChangeNotifications_.push_back(
102         PropertyChangeNotification(listener, event));
103 }
104 
105 void Broadcaster::addPropertiesChangeNotification(
106     css::uno::Reference< css::beans::XPropertiesChangeListener > const &
107         listener,
108     css::uno::Sequence< css::beans::PropertyChangeEvent > const & event)
109 {
110     propertiesChangeNotifications_.push_back(
111         PropertiesChangeNotification(listener, event));
112 }
113 
114 void Broadcaster::addChangesNotification(
115     css::uno::Reference< css::util::XChangesListener > const & listener,
116     css::util::ChangesEvent const & event)
117 {
118     changesNotifications_.push_back(ChangesNotification(listener, event));
119 }
120 
121 void Broadcaster::send() {
122     css::uno::Any exception;
123     rtl::OUStringBuffer messages;
124     for (DisposeNotifications::iterator i(disposeNotifications_.begin());
125          i != disposeNotifications_.end(); ++i) {
126         try {
127             i->listener->disposing(i->event);
128         } catch (css::lang::DisposedException &) {
129         } catch (css::uno::Exception & e) {
130             exception = cppu::getCaughtException();
131             appendMessage(messages, e);
132         }
133     }
134     for (ContainerNotifications::iterator i(
135              containerElementInsertedNotifications_.begin());
136          i != containerElementInsertedNotifications_.end(); ++i)
137     {
138         try {
139             i->listener->elementInserted(i->event);
140         } catch (css::lang::DisposedException &) {
141         } catch (css::uno::Exception & e) {
142             exception = cppu::getCaughtException();
143             appendMessage(messages, e);
144         }
145     }
146     for (ContainerNotifications::iterator i(
147              containerElementRemovedNotifications_.begin());
148          i != containerElementRemovedNotifications_.end(); ++i)
149     {
150         try {
151             i->listener->elementRemoved(i->event);
152         } catch (css::lang::DisposedException &) {
153         } catch (css::uno::Exception & e) {
154             exception = cppu::getCaughtException();
155             appendMessage(messages, e);
156         }
157     }
158     for (ContainerNotifications::iterator i(
159              containerElementReplacedNotifications_.begin());
160          i != containerElementReplacedNotifications_.end(); ++i)
161     {
162         try {
163             i->listener->elementReplaced(i->event);
164         } catch (css::lang::DisposedException &) {
165         } catch (css::uno::Exception & e) {
166             exception = cppu::getCaughtException();
167             appendMessage(messages, e);
168         }
169     }
170     for (PropertyChangeNotifications::iterator i(
171              propertyChangeNotifications_.begin());
172          i != propertyChangeNotifications_.end(); ++i)
173     {
174         try {
175             i->listener->propertyChange(i->event);
176         } catch (css::lang::DisposedException &) {
177         } catch (css::uno::Exception & e) {
178             exception = cppu::getCaughtException();
179             appendMessage(messages, e);
180         }
181     }
182     for (PropertiesChangeNotifications::iterator i(
183              propertiesChangeNotifications_.begin());
184          i != propertiesChangeNotifications_.end(); ++i)
185     {
186         try {
187             i->listener->propertiesChange(i->event);
188         } catch (css::lang::DisposedException &) {
189         } catch (css::uno::Exception & e) {
190             exception = cppu::getCaughtException();
191             appendMessage(messages, e);
192         }
193     }
194     for (ChangesNotifications::iterator i(changesNotifications_.begin());
195          i != changesNotifications_.end(); ++i) {
196         try {
197             i->listener->changesOccurred(i->event);
198         } catch (css::lang::DisposedException &) {
199         } catch (css::uno::Exception & e) {
200             exception = cppu::getCaughtException();
201             appendMessage(messages, e);
202         }
203     }
204     if (exception.hasValue()) {
205         throw css::lang::WrappedTargetRuntimeException(
206             (rtl::OUString(
207                 RTL_CONSTASCII_USTRINGPARAM(
208                     "configmgr exceptions during listener notification")) +
209              messages.makeStringAndClear()),
210             css::uno::Reference< css::uno::XInterface >(),
211             exception);
212     }
213 }
214 
215 Broadcaster::DisposeNotification::DisposeNotification(
216     css::uno::Reference< css::lang::XEventListener > const & theListener,
217     css::lang::EventObject const & theEvent):
218     listener(theListener), event(theEvent)
219 {
220     OSL_ASSERT(theListener.is());
221 }
222 
223 Broadcaster::ContainerNotification::ContainerNotification(
224     css::uno::Reference< css::container::XContainerListener > const &
225         theListener,
226     css::container::ContainerEvent const & theEvent):
227     listener(theListener), event(theEvent)
228 {
229     OSL_ASSERT(theListener.is());
230 }
231 
232 Broadcaster::PropertyChangeNotification::PropertyChangeNotification(
233     css::uno::Reference< css::beans::XPropertyChangeListener > const &
234         theListener,
235     css::beans::PropertyChangeEvent const & theEvent):
236     listener(theListener), event(theEvent)
237 {
238     OSL_ASSERT(theListener.is());
239 }
240 
241 Broadcaster::PropertiesChangeNotification::PropertiesChangeNotification(
242     css::uno::Reference< css::beans::XPropertiesChangeListener > const &
243         theListener,
244     css::uno::Sequence< css::beans::PropertyChangeEvent > const & theEvent):
245     listener(theListener), event(theEvent)
246 {
247     OSL_ASSERT(theListener.is());
248 }
249 
250 Broadcaster::ChangesNotification::ChangesNotification(
251     css::uno::Reference< css::util::XChangesListener > const & theListener,
252     css::util::ChangesEvent const & theEvent):
253     listener(theListener), event(theEvent)
254 {
255     OSL_ASSERT(theListener.is());
256 }
257 
258 }
259