Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "cacheupdatelistener.hxx"
22 : #include "constant.hxx"
23 :
24 : #include <com/sun/star/util/XChangesNotifier.hpp>
25 : #include <com/sun/star/util/XRefreshable.hpp>
26 : #include <salhelper/singletonref.hxx>
27 : #include <unotools/configpaths.hxx>
28 : #include <rtl/ustring.hxx>
29 :
30 :
31 : namespace filter{
32 : namespace config{
33 :
34 26 : CacheUpdateListener::CacheUpdateListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR,
35 : FilterCache &rFilterCache,
36 : const css::uno::Reference< css::uno::XInterface >& xConfigAccess,
37 : FilterCache::EItemType eConfigType)
38 : : BaseLock()
39 : , m_xSMGR(xSMGR)
40 : , m_rCache(rFilterCache)
41 : , m_xConfig(xConfigAccess)
42 26 : , m_eConfigType(eConfigType)
43 : {
44 26 : }
45 :
46 52 : CacheUpdateListener::~CacheUpdateListener()
47 : {
48 52 : }
49 :
50 26 : void CacheUpdateListener::startListening()
51 : {
52 : // SAFE ->
53 26 : ::osl::ResettableMutexGuard aLock(m_aLock);
54 26 : css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
55 26 : aLock.clear();
56 : // <- SAFE
57 :
58 26 : if (!xNotifier.is())
59 26 : return;
60 :
61 26 : css::uno::Reference< css::util::XChangesListener > xThis(static_cast< css::util::XChangesListener* >(this), css::uno::UNO_QUERY_THROW);
62 26 : xNotifier->addChangesListener(xThis);
63 : }
64 :
65 :
66 :
67 26 : void CacheUpdateListener::stopListening()
68 : {
69 : // SAFE ->
70 26 : ::osl::ResettableMutexGuard aLock(m_aLock);
71 26 : css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
72 26 : aLock.clear();
73 : // <- SAFE
74 :
75 26 : if (!xNotifier.is())
76 26 : return;
77 :
78 26 : css::uno::Reference< css::util::XChangesListener > xThis(static_cast< css::util::XChangesListener* >(this), css::uno::UNO_QUERY);
79 26 : xNotifier->removeChangesListener(xThis);
80 : }
81 :
82 :
83 :
84 0 : void SAL_CALL CacheUpdateListener::changesOccurred(const css::util::ChangesEvent& aEvent)
85 : throw(css::uno::RuntimeException)
86 : {
87 : // SAFE ->
88 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
89 :
90 : // disposed ?
91 0 : if ( ! m_xConfig.is())
92 0 : return;
93 :
94 0 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
95 0 : FilterCache::EItemType eType = m_eConfigType;
96 :
97 0 : aLock.clear();
98 : // <- SAFE
99 :
100 0 : OUStringList lChangedItems;
101 0 : sal_Int32 c = aEvent.Changes.getLength();
102 0 : sal_Int32 i = 0;
103 :
104 0 : for (i=0; i<c; ++i)
105 : {
106 0 : const css::util::ElementChange& aChange = aEvent.Changes[i];
107 :
108 0 : ::rtl::OUString sOrgPath ;
109 0 : ::rtl::OUString sTempPath;
110 :
111 0 : ::rtl::OUString sProperty;
112 0 : ::rtl::OUString sNode ;
113 0 : ::rtl::OUString sLocale ;
114 :
115 : /* at least we must be able to retrieve 2 path elements
116 : But sometimes the original path can contain 3 of them ... in case
117 : a localized value was changed.
118 : =>
119 : 1) Filters/Filter["filtername"]/Property
120 : 2) Filters/Filter["filtername"]/LocalizedProperty/Locale
121 : */
122 :
123 0 : aChange.Accessor >>= sOrgPath;
124 0 : if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sLocale))
125 0 : continue;
126 0 : sOrgPath = sTempPath;
127 0 : if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sProperty))
128 : {
129 0 : sNode = sLocale;
130 0 : sProperty = ::rtl::OUString();
131 0 : sLocale = ::rtl::OUString();
132 : }
133 : else
134 : {
135 0 : sOrgPath = sTempPath;
136 0 : if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sNode))
137 : {
138 0 : sNode = sProperty;
139 0 : sProperty = sLocale;
140 0 : sLocale = ::rtl::OUString();
141 : }
142 : }
143 :
144 0 : if ( sNode.isEmpty() )
145 0 : continue;
146 :
147 0 : OUStringList::const_iterator pIt = ::std::find(lChangedItems.begin(), lChangedItems.end(), sNode);
148 0 : if (pIt == lChangedItems.end())
149 0 : lChangedItems.push_back(sNode);
150 0 : }
151 :
152 0 : sal_Bool bNotifyRefresh = sal_False;
153 0 : OUStringList::const_iterator pIt;
154 0 : for ( pIt = lChangedItems.begin();
155 0 : pIt != lChangedItems.end() ;
156 : ++pIt )
157 : {
158 0 : const ::rtl::OUString& sItem = *pIt;
159 : try
160 : {
161 0 : m_rCache.refreshItem(eType, sItem);
162 : }
163 0 : catch(const css::container::NoSuchElementException&)
164 : {
165 : // can be ignored! Because we must be aware that
166 : // sItem was removed from the configuration and we forced an update of the cache.
167 : // But we know, that the cache is up-to-date know and has thrown this exception afterwards .-)
168 : }
169 : // NO FLUSH! Otherwise we start a never ending story here .-)
170 0 : bNotifyRefresh = sal_True;
171 : }
172 :
173 : // notify sfx cache about the changed filter cache .-)
174 0 : if (bNotifyRefresh)
175 : {
176 : css::uno::Reference< css::util::XRefreshable > xRefreshBroadcaster(
177 0 : xSMGR->createInstance(SERVICE_FILTERCONFIGREFRESH),
178 0 : css::uno::UNO_QUERY);
179 0 : if (xRefreshBroadcaster.is())
180 0 : xRefreshBroadcaster->refresh();
181 0 : }
182 : }
183 :
184 :
185 :
186 0 : void SAL_CALL CacheUpdateListener::disposing(const css::lang::EventObject& aEvent)
187 : throw(css::uno::RuntimeException)
188 : {
189 : // SAFE ->
190 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
191 0 : if (aEvent.Source == m_xConfig)
192 0 : m_xConfig.clear();
193 0 : aLock.clear();
194 : // <- SAFE
195 0 : }
196 :
197 : } // namespace config
198 : } // namespace filter
199 :
200 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|