1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "ResourceFactoryManager.hxx"
21 #include <DrawController.hxx>
22 #include <tools/wldcrd.hxx>
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <com/sun/star/util/URLTransformer.hpp>
26 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <sal/log.hxx>
32 using namespace ::com::sun::star
;
33 using namespace ::com::sun::star::uno
;
34 using namespace ::com::sun::star::drawing::framework
;
39 namespace sd::framework
{
41 ResourceFactoryManager::ResourceFactoryManager (const rtl::Reference
<::sd::DrawController
>& rxManager
)
42 : mxControllerManager(rxManager
)
44 // Create the URL transformer.
45 const Reference
<uno::XComponentContext
>& xContext(::comphelper::getProcessComponentContext());
46 mxURLTransformer
= util::URLTransformer::create(xContext
);
49 ResourceFactoryManager::~ResourceFactoryManager()
51 for (auto& rXInterfaceResource
: maFactoryMap
)
53 Reference
<lang::XComponent
> xComponent (rXInterfaceResource
.second
, UNO_QUERY
);
54 rXInterfaceResource
.second
= nullptr;
56 xComponent
->dispose();
59 Reference
<lang::XComponent
> xComponent (mxURLTransformer
, UNO_QUERY
);
61 xComponent
->dispose();
64 void ResourceFactoryManager::AddFactory (
65 const OUString
& rsURL
,
66 const Reference
<XResourceFactory
>& rxFactory
)
68 if ( ! rxFactory
.is())
69 throw lang::IllegalArgumentException();
71 throw lang::IllegalArgumentException();
73 std::scoped_lock
aGuard (maMutex
);
75 if (rsURL
.indexOf('*') >= 0 || rsURL
.indexOf('?') >= 0)
77 // The URL is a URL pattern not a single URL.
78 maFactoryPatternList
.emplace_back(rsURL
, rxFactory
);
80 #if defined VERBOSE && VERBOSE>=1
81 SAL_INFO("sd","ResourceFactoryManager::AddFactory pattern " << rsURL
<< std::hex
<< rxFactory
.get());
86 maFactoryMap
[rsURL
] = rxFactory
;
88 #if defined VERBOSE && VERBOSE>=1
89 SAL_INFO("sd", "ResourceFactoryManager::AddFactory fixed " << rsURL
<< " 0x" << std::hex
<< rxFactory
.get());
94 void ResourceFactoryManager::RemoveFactoryForURL (
95 const OUString
& rsURL
)
98 throw lang::IllegalArgumentException();
100 std::scoped_lock
aGuard (maMutex
);
102 FactoryMap::iterator
iFactory (maFactoryMap
.find(rsURL
));
103 if (iFactory
!= maFactoryMap
.end())
105 maFactoryMap
.erase(iFactory
);
109 // The URL may be a pattern. Look that up.
110 auto iPattern
= std::find_if(maFactoryPatternList
.begin(), maFactoryPatternList
.end(),
111 [&rsURL
](const FactoryPatternList::value_type
& rPattern
) { return rPattern
.first
== rsURL
; });
112 if (iPattern
!= maFactoryPatternList
.end())
114 // Found the pattern. Remove it.
115 maFactoryPatternList
.erase(iPattern
);
120 void ResourceFactoryManager::RemoveFactoryForReference(
121 const Reference
<XResourceFactory
>& rxFactory
)
123 std::scoped_lock
aGuard (maMutex
);
125 // Collect a list with all keys that map to the given factory.
126 ::std::vector
<OUString
> aKeys
;
127 for (const auto& rFactory
: maFactoryMap
)
128 if (rFactory
.second
== rxFactory
)
129 aKeys
.push_back(rFactory
.first
);
131 // Remove the entries whose keys we just have collected.
132 for (const auto& rKey
: aKeys
)
133 maFactoryMap
.erase(rKey
);
135 // Remove the pattern entries whose factories are identical to the given
138 maFactoryPatternList
,
139 [&] (FactoryPatternList::value_type
const& it
) { return it
.second
== rxFactory
; });
142 Reference
<XResourceFactory
> ResourceFactoryManager::GetFactory (
143 const OUString
& rsCompleteURL
)
145 OUString
sURLBase (rsCompleteURL
);
146 if (mxURLTransformer
.is())
149 aURL
.Complete
= rsCompleteURL
;
150 if (mxURLTransformer
->parseStrict(aURL
))
151 sURLBase
= aURL
.Main
;
154 Reference
<XResourceFactory
> xFactory
= FindFactory(sURLBase
);
156 if ( ! xFactory
.is() && mxControllerManager
.is())
158 Reference
<XModuleController
> xModuleController(mxControllerManager
->getModuleController());
159 if (xModuleController
.is())
161 // Ask the module controller to provide a factory of the
162 // requested view type. Note that this can (and should) cause
163 // intermediate calls to AddFactory().
164 xModuleController
->requestResource(sURLBase
);
166 xFactory
= FindFactory(sURLBase
);
173 Reference
<XResourceFactory
> ResourceFactoryManager::FindFactory (const OUString
& rsURLBase
)
175 std::scoped_lock
aGuard (maMutex
);
176 FactoryMap::const_iterator
iFactory (maFactoryMap
.find(rsURLBase
));
177 if (iFactory
!= maFactoryMap
.end())
178 return iFactory
->second
;
181 // Check the URL patterns.
182 auto iPattern
= std::find_if(maFactoryPatternList
.begin(), maFactoryPatternList
.end(),
183 [&rsURLBase
](const FactoryPatternList::value_type
& rPattern
) {
184 WildCard
aWildCard (rPattern
.first
);
185 return aWildCard
.Matches(rsURLBase
);
187 if (iPattern
!= maFactoryPatternList
.end())
188 return iPattern
->second
;
193 } // end of namespace sd::framework
195 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */