LibreOffice Module filter (master) 1
cacheupdatelistener.cxx
Go to the documentation of this file.
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
22#include "configflush.hxx"
23
24#include <com/sun/star/util/XChangesNotifier.hpp>
25#include <com/sun/star/util/XRefreshable.hpp>
27#include <rtl/ustring.hxx>
29#include <utility>
30
31
32namespace filter::config{
33
35 css::uno::Reference< css::uno::XInterface > xConfigAccess,
36 FilterCache::EItemType eConfigType)
37 : m_rCache(rFilterCache)
38 , m_xConfig(std::move(xConfigAccess))
39 , m_eConfigType(eConfigType)
40{
41}
42
44{
45}
46
48{
49 // SAFE ->
50 std::unique_lock aLock(m_aMutex);
51 css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
52 aLock.unlock();
53 // <- SAFE
54
55 if (!xNotifier.is())
56 return;
57
58 css::uno::Reference< css::util::XChangesListener > xThis(this);
59 xNotifier->addChangesListener(xThis);
60}
61
62
64{
65 // SAFE ->
66 std::unique_lock aLock(m_aMutex);
67 css::uno::Reference< css::util::XChangesNotifier > xNotifier(m_xConfig, css::uno::UNO_QUERY);
68 aLock.unlock();
69 // <- SAFE
70
71 if (!xNotifier.is())
72 return;
73
74 css::uno::Reference< css::util::XChangesListener > xThis(this);
75 xNotifier->removeChangesListener(xThis);
76}
77
78
79void SAL_CALL CacheUpdateListener::changesOccurred(const css::util::ChangesEvent& aEvent)
80{
81 // SAFE ->
82 std::unique_lock aLock(m_aMutex);
83
84 // disposed ?
85 if ( ! m_xConfig.is())
86 return;
87
89
90 aLock.unlock();
91 // <- SAFE
92
93 std::vector<OUString> lChangedItems;
94 sal_Int32 c = aEvent.Changes.getLength();
95 sal_Int32 i = 0;
96
97 for (i=0; i<c; ++i)
98 {
99 const css::util::ElementChange& aChange = aEvent.Changes[i];
100
101 OUString sOrgPath ;
102 OUString sTempPath;
103
104 OUString sProperty;
105 OUString sNode ;
106 OUString sLocale ;
107
108 /* at least we must be able to retrieve 2 path elements
109 But sometimes the original path can contain 3 of them ... in case
110 a localized value was changed.
111 =>
112 1) Filters/Filter["filtername"]/Property
113 2) Filters/Filter["filtername"]/LocalizedProperty/Locale
114 */
115
116 aChange.Accessor >>= sOrgPath;
117 if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sLocale))
118 continue;
119 sOrgPath = sTempPath;
120 if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sProperty))
121 {
122 sNode = sLocale;
123 sProperty.clear();
124 sLocale.clear();
125 }
126 else
127 {
128 sOrgPath = sTempPath;
129 if ( ! ::utl::splitLastFromConfigurationPath(sOrgPath, sTempPath, sNode))
130 {
131 sNode = sProperty;
132 sProperty = sLocale;
133 sLocale.clear();
134 }
135 }
136
137 if ( sNode.isEmpty() )
138 continue;
139
140 auto pIt = ::std::find(lChangedItems.cbegin(), lChangedItems.cend(), sNode);
141 if (pIt == lChangedItems.cend())
142 lChangedItems.push_back(sNode);
143 }
144
145 bool bNotifyRefresh = false;
146 for (auto const& changedItem : lChangedItems)
147 {
148 try
149 {
150 m_rCache.refreshItem(eType, changedItem);
151 }
152 catch(const css::container::NoSuchElementException&)
153 {
154 // can be ignored! Because we must be aware that
155 // sItem was removed from the configuration and we forced an update of the cache.
156 // But we know, that the cache is up-to-date know and has thrown this exception afterwards .-)
157 }
158 // NO FLUSH! Otherwise we start a never ending story here .-)
159 bNotifyRefresh = true;
160 }
161
162 // notify sfx cache about the changed filter cache .-)
163 if (bNotifyRefresh)
164 {
165 rtl::Reference< ConfigFlush > xRefreshBroadcaster = new ConfigFlush();
166 xRefreshBroadcaster->refresh();
167 }
168}
169
170
171void SAL_CALL CacheUpdateListener::disposing(const css::lang::EventObject& aEvent)
172{
173 // SAFE ->
174 std::unique_lock aLock(m_aMutex);
175 if (aEvent.Source == m_xConfig)
176 m_xConfig.clear();
177 // <- SAFE
178}
179
180} // namespace filter::config
181
182/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
css::uno::Reference< css::uno::XInterface > m_xConfig
holds the configuration access, where we listen alive.
virtual ~CacheUpdateListener() override
standard dtor.
FilterCache::EItemType m_eConfigType
every instance of this update listener listen on a special sub set of the filter configuration.
CacheUpdateListener(FilterCache &rFilterCache, css::uno::Reference< css::uno::XInterface > xConfigAccess, FilterCache::EItemType eConfigType)
initialize new instance of this class.
FilterCache & m_rCache
reference to the singleton(!) filter cache implementation, which should be updated by this thread.
virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent &aEvent) override
virtual void SAL_CALL disposing(const css::lang::EventObject &aEvent) override
supports registration of XRefreshListener on the global filter configuration.
Definition: configflush.hxx:40
implements a cache, which contains all elements of our filter and type detection configuration.
Definition: filtercache.hxx:61
void refreshItem(EItemType eType, const OUString &sItem)
TODO document me ...
EItemType
identify the type of a container item.
Definition: filtercache.hxx:74
DocumentType eType
int i
Definition: gentoken.py:48