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_filter.hxx"
26
27 #include "cacheupdatelistener.hxx"
28 #include "constant.hxx"
29
30 //_______________________________________________
31 // includes
32 #include <com/sun/star/util/XChangesNotifier.hpp>
33 #include <com/sun/star/util/XRefreshable.hpp>
34 #include <salhelper/singletonref.hxx>
35 #include <unotools/configpathes.hxx>
36 #include <rtl/ustring.hxx>
37
38 //_______________________________________________
39 // namespace
40
41 namespace filter{
42 namespace config{
43
44 namespace css = ::com::sun::star;
45
46 //_______________________________________________
47 // definitions
48
49 /*-----------------------------------------------
50 05.03.2004 08:36
51 -----------------------------------------------*/
CacheUpdateListener(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const css::uno::Reference<css::uno::XInterface> & xConfigAccess,FilterCache::EItemType eConfigType)52 CacheUpdateListener::CacheUpdateListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
53 const css::uno::Reference< css::uno::XInterface >& xConfigAccess,
54 FilterCache::EItemType eConfigType )
55 : BaseLock ( )
56 , m_xSMGR (xSMGR )
57 , m_rCache ( )
58 , m_xConfig (xConfigAccess)
59 , m_eConfigType(eConfigType )
60 {
61 }
62
63 /*-----------------------------------------------
64 05.03.2004 08:37
65 -----------------------------------------------*/
~CacheUpdateListener()66 CacheUpdateListener::~CacheUpdateListener()
67 {
68 }
69
70 /*-----------------------------------------------
71 07.03.2004 07:59
72 -----------------------------------------------*/
startListening()73 void CacheUpdateListener::startListening()
74 {
75 // SAFE ->
76 ::osl::ResettableMutexGuard aLock(m_aLock);
77 css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
78 aLock.clear();
79 // <- SAFE
80
81 if (!xNotifier.is())
82 return;
83
84 css::uno::Reference< css::util::XChangesListener > xThis(static_cast< css::util::XChangesListener* >(this), css::uno::UNO_QUERY_THROW);
85 xNotifier->addChangesListener(xThis);
86
87 /*
88 css::uno::Reference< css::container::XContainer > xNotifier(xConfigAccess, css::uno::UNO_QUERY);
89 if (!xNotifier.is())
90 return;
91
92 css::uno::Reference< css::container::XContainerListener > xThis(static_cast< css::container::XContainerListener* >(this), css::uno::UNO_QUERY);
93 xNotifier->addContainerListener(xThis);
94 */
95 }
96
97 /*-----------------------------------------------
98 07.03.2004 07:59
99 -----------------------------------------------*/
stopListening()100 void CacheUpdateListener::stopListening()
101 {
102 // SAFE ->
103 ::osl::ResettableMutexGuard aLock(m_aLock);
104 css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
105 aLock.clear();
106 // <- SAFE
107
108 if (!xNotifier.is())
109 return;
110
111 css::uno::Reference< css::util::XChangesListener > xThis(static_cast< css::util::XChangesListener* >(this), css::uno::UNO_QUERY);
112 xNotifier->removeChangesListener(xThis);
113
114 /*
115 css::uno::Reference< css::container::XContainer > xNotifier(xConfigAccess, css::uno::UNO_QUERY);
116 if (!xNotifier.is())
117 return;
118
119 css::uno::Reference< css::container::XContainerListener > xThis(static_cast< css::container::XContainerListener* >(this), css::uno::UNO_QUERY);
120 xNotifier->removeContainerListener(xThis);
121 */
122 }
123
124 /*-----------------------------------------------
125 07.03.2004 08:17
126 -----------------------------------------------*/
changesOccurred(const css::util::ChangesEvent & aEvent)127 void SAL_CALL CacheUpdateListener::changesOccurred(const css::util::ChangesEvent& aEvent)
128 throw(css::uno::RuntimeException)
129 {
130 // SAFE ->
131 ::osl::ResettableMutexGuard aLock(m_aLock);
132
133 // disposed ?
134 if ( ! m_xConfig.is())
135 return;
136
137 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
138 FilterCache::EItemType eType = m_eConfigType;
139
140 aLock.clear();
141 // <- SAFE
142
143 OUStringList lChangedItems;
144 sal_Int32 c = aEvent.Changes.getLength();
145 sal_Int32 i = 0;
146
147 for (i=0; i<c; ++i)
148 {
149 const css::util::ElementChange& aChange = aEvent.Changes[i];
150
151 ::rtl::OUString sOrgPath ;
152 ::rtl::OUString sTempPath;
153
154 ::rtl::OUString sProperty;
155 ::rtl::OUString sNode ;
156 ::rtl::OUString sLocale ;
157
158 /* at least we must be able to retrieve 2 path elements
159 But sometimes the original path can contain 3 of them ... in case
160 a localized value was changed.
161 =>
162 1) Filters/Filter["filtername"]/Property
163 2) Filters/Filter["filtername"]/LocalizedProperty/Locale
164 */
165
166 aChange.Accessor >>= sOrgPath;
167 if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sLocale))
168 continue;
169 sOrgPath = sTempPath;
170 if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sProperty))
171 {
172 sNode = sLocale;
173 sProperty = ::rtl::OUString();
174 sLocale = ::rtl::OUString();
175 }
176 else
177 {
178 sOrgPath = sTempPath;
179 if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sNode))
180 {
181 sNode = sProperty;
182 sProperty = sLocale;
183 sLocale = ::rtl::OUString();
184 }
185 }
186
187 if ( ! sNode.getLength() )
188 continue;
189
190 OUStringList::const_iterator pIt = ::std::find(lChangedItems.begin(), lChangedItems.end(), sNode);
191 if (pIt == lChangedItems.end())
192 lChangedItems.push_back(sNode);
193 }
194
195 sal_Bool bNotifyRefresh = sal_False;
196 OUStringList::const_iterator pIt;
197 for ( pIt = lChangedItems.begin();
198 pIt != lChangedItems.end() ;
199 ++pIt )
200 {
201 const ::rtl::OUString& sItem = *pIt;
202 try
203 {
204 m_rCache->refreshItem(eType, sItem);
205 }
206 catch(const css::container::NoSuchElementException&)
207 {
208 // can be ignored! Because we must be aware that
209 // sItem was removed from the condfiguration and we forced an update of the cache.
210 // But we know, that the cache is up-to-date know and has thrown this exception afterwards .-)
211 }
212 // NO FLUSH! Otherwise we start a never ending story here .-)
213 bNotifyRefresh = sal_True;
214 }
215
216 // notify sfx cache about the changed filter cache .-)
217 if (bNotifyRefresh)
218 {
219 css::uno::Reference< css::util::XRefreshable > xRefreshBroadcaster(
220 xSMGR->createInstance(SERVICE_FILTERCONFIGREFRESH),
221 css::uno::UNO_QUERY);
222 if (xRefreshBroadcaster.is())
223 xRefreshBroadcaster->refresh();
224 }
225 }
226
227 /*-----------------------------------------------
228 05.03.2004 08:44
229 -----------------------------------------------*/
disposing(const css::lang::EventObject & aEvent)230 void SAL_CALL CacheUpdateListener::disposing(const css::lang::EventObject& aEvent)
231 throw(css::uno::RuntimeException)
232 {
233 // SAFE ->
234 ::osl::ResettableMutexGuard aLock(m_aLock);
235 if (aEvent.Source == m_xConfig)
236 m_xConfig.clear();
237 aLock.clear();
238 // <- SAFE
239 }
240
241 } // namespace config
242 } // namespace filter
243