LibreOffice Module framework (master) 1
protocolhandlercache.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/*TODO
21 - change "singleton" behaviour by using new helper ::comhelper::SingletonRef
22 - rename method exist() to existHandlerForURL() or similar one
23 - may it's a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?!
24*/
25
27#include <classes/converter.hxx>
28
29#include <tools/wldcrd.hxx>
31#include <sal/log.hxx>
32#include <vcl/svapp.hxx>
33
34constexpr OUStringLiteral SETNAME_HANDLER = u"HandlerSet"; // name of configuration set inside package
35
36namespace framework{
37
52namespace {
53
54PatternHash::const_iterator findPatternKey(PatternHash const * hash, const OUString& sURL)
55{
56 return std::find_if(hash->begin(), hash->end(),
57 [&sURL](const PatternHash::value_type& rEntry) {
58 WildCard aPattern(rEntry.first);
59 return aPattern.Matches(sURL);
60 });
61}
62
63}
64
71std::optional<HandlerHash> HandlerCache::s_pHandler;
72std::optional<PatternHash> HandlerCache::s_pPattern;
73sal_Int32 HandlerCache::m_nRefCount = 0;
74HandlerCFGAccess* HandlerCache::s_pConfig = nullptr;
75
84{
85 SolarMutexGuard aGuard;
86
87 if (m_nRefCount==0)
88 {
89 s_pHandler.emplace();
90 s_pPattern.emplace();
93 s_pConfig->setCache(this);
94 }
95
97}
98
105{
106 SolarMutexGuard aGuard;
107
108 if( m_nRefCount==1)
109 {
110 s_pConfig->setCache(nullptr);
111
112 delete s_pConfig;
113 s_pConfig = nullptr;
114 s_pHandler.reset();
115 s_pPattern.reset();
116 }
117
118 --m_nRefCount;
119}
120
126bool HandlerCache::search( const OUString& sURL, ProtocolHandler* pReturn ) const
127{
128 bool bFound = false;
129
130 SolarMutexGuard aGuard;
131
132 PatternHash::const_iterator pItem = findPatternKey(s_pPattern ? &*s_pPattern : nullptr, sURL);
133 if (pItem != s_pPattern->end())
134 {
135 *pReturn = (*s_pHandler)[pItem->second];
136 bFound = true;
137 }
138
139 return bFound;
140}
141
148bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
149{
150 return search( aURL.Complete, pReturn );
151}
152
154{
155 SolarMutexGuard aGuard;
156
157 s_pHandler = std::move(aHandler);
158 s_pPattern = std::move(aPattern);
159}
160
169HandlerCFGAccess::HandlerCFGAccess( const OUString& sPackage )
170 : ConfigItem(sPackage)
171 , m_pCache(nullptr)
172{
173 css::uno::Sequence< OUString > lListenPaths { SETNAME_HANDLER };
174 EnableNotification(lListenPaths);
175}
176
188void HandlerCFGAccess::read( HandlerHash& rHandlerHash, PatternHash& rPatternHash )
189{
190 // list of all uno implementation names without encoding
191 css::uno::Sequence< OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::ConfigNameFormat::LocalPath );
192 sal_Int32 nSourceCount = lNames.getLength();
193 sal_Int32 nTargetCount = nSourceCount;
194 // list of all full qualified path names of configuration entries
195 css::uno::Sequence< OUString > lFullNames ( nTargetCount );
196 auto lFullNamesRange = asNonConstRange(lFullNames);
197 // expand names to full path names
198 sal_Int32 nSource=0;
199 sal_Int32 nTarget=0;
200 for( nSource=0; nSource<nSourceCount; ++nSource )
201 {
202 lFullNamesRange[nTarget] =
205 lNames[nSource] +
208
209 ++nTarget;
210 }
211
212 // get values at all
213 css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
214 SAL_WARN_IF( lFullNames.getLength()!=lValues.getLength(), "fwk", "HandlerCFGAccess::read(): Miss some configuration values of handler set!" );
215
216 // fill structures
217 nSource = 0;
218 for( nTarget=0; nTarget<nTargetCount; ++nTarget )
219 {
220 // create it new for every loop to guarantee a real empty object!
221 ProtocolHandler aHandler;
222 aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
223
224 // unpack all values of this handler
225 css::uno::Sequence< OUString > lTemp;
226 lValues[nTarget] >>= lTemp;
228
229 // register his pattern into the performance search hash
230 for (auto const& item : aHandler.m_lProtocols)
231 {
232 rPatternHash[item] = lNames[nSource];
233 }
234
235 // insert the handler info into the normal handler cache
236 rHandlerHash[lNames[nSource]] = aHandler;
237 ++nSource;
238 }
239}
240
241void HandlerCFGAccess::Notify(const css::uno::Sequence< OUString >& /*lPropertyNames*/)
242{
243 HandlerHash aHandler;
244 PatternHash aPattern;
245
246 read(aHandler, aPattern);
247 if (m_pCache)
248 m_pCache->takeOver(std::move(aHandler), std::move(aPattern));
249}
250
252{
253}
254
255} // namespace framework
256
257/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static std::vector< OUString > convert_seqOUString2OUStringList(const css::uno::Sequence< OUString > &lSource)
converts a sequence of unicode strings into a vector of such items
Definition: converter.cxx:44
implements configuration access for handler configuration @descr We use the ConfigItem mechanism to r...
virtual void Notify(const css::uno::Sequence< OUString > &lPropertyNames) override
virtual void ImplCommit() override
void setCache(HandlerCache *pCache)
void read(HandlerHash &rHandlerHash, PatternHash &rPatternHash)
use base class mechanism to fill given structures @descr User use us as a wrapper between configurati...
HandlerCFGAccess(const OUString &sPackage)
dtor of the config access class @descr It opens the configuration package automatically by using base...
static HandlerCFGAccess * s_pConfig
informs about config updates
static sal_Int32 m_nRefCount
ref count to construct/destruct internal member lists on demand by using singleton mechanism
HandlerCache()
ctor of the cache of all registered protocol handler @descr It tries to open the right configuration ...
void takeOver(HandlerHash aHandler, PatternHash aPattern)
static std::optional< PatternHash > s_pPattern
maps URL pattern to handler names
static std::optional< HandlerHash > s_pHandler
list of all registered handler registered by her uno implementation names
bool search(const OUString &sURL, ProtocolHandler *pReturn) const
dtor of the cache @descr It frees all used memory.
~HandlerCache()
dtor of the cache @descr It frees all used memory.
bool EnableNotification(const css::uno::Sequence< OUString > &rNames, bool bEnableInternalNotification=false)
static css::uno::Sequence< css::uno::Any > GetProperties(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const css::uno::Sequence< OUString > &rNames, bool bAllLocales)
static css::uno::Sequence< OUString > GetNodeNames(css::uno::Reference< css::container::XHierarchicalNameAccess > const &xHierarchyAccess, const OUString &rNode, ConfigNameFormat eFormat)
URL aURL
float u
FilterCache * m_pCache
#define SAL_WARN_IF(condition, area, stream)
std::unordered_map< OUString, OUString > PatternHash
This hash use registered pattern of all protocol handlers as keys and provide her uno implementation ...
std::unordered_map< OUString, ProtocolHandler > HandlerHash
This hash holds protocol handler structs by her names.
constexpr OUStringLiteral PACKAGENAME_PROTOCOLHANDLER
constexpr OUStringLiteral SETNAME_HANDLER
#define PROPERTY_PROTOCOLS
#define CFG_PATH_SEPARATOR
name of our configuration package
Programmer can register his own services to handle different protocols.
std::vector< OUString > m_lProtocols
list of URL pattern which defines the protocols which this handler is registered for
OUString m_sUNOName
the uno implementation name of this handler