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/.
10 #include "sal/config.h"
15 #include "osl/mutex.hxx"
16 #include "rtl/ref.hxx"
17 #include "rtl/ustring.hxx"
18 #include "unoidl/legacyprovider.hxx"
19 #include "unoidl/unoidl.hxx"
20 #include "unoidl/unoidlprovider.hxx"
26 class AggregatingModule
: public ModuleEntity
{
29 std::vector
< rtl::Reference
< Provider
> > const & providers
,
30 OUString
const & name
):
31 providers_(providers
), name_(name
)
35 virtual ~AggregatingModule() throw () {}
37 virtual std::vector
< OUString
> getMemberNames() const;
39 virtual rtl::Reference
< MapCursor
> createCursor() const;
41 std::vector
< rtl::Reference
< Provider
> > providers_
;
45 std::vector
< OUString
> AggregatingModule::getMemberNames() const {
46 std::set
< OUString
> names
;
47 for (std::vector
< rtl::Reference
< Provider
> >::const_iterator
i(
49 i
!= providers_
.end(); ++i
)
51 rtl::Reference
< Entity
> ent((*i
)->findEntity(name_
));
52 if (ent
.is() && ent
->getSort() == Entity::SORT_MODULE
) {
53 std::vector
< OUString
> ns(
54 static_cast< ModuleEntity
* >(ent
.get())->getMemberNames());
55 names
.insert(ns
.begin(), ns
.end());
58 return std::vector
< OUString
>(names
.begin(), names
.end());
61 class AggregatingCursor
: public MapCursor
{
64 std::vector
< rtl::Reference
< Provider
> > const & providers
,
65 OUString
const & name
):
66 providers_(providers
), name_(name
), iterator_(providers_
.begin())
70 virtual ~AggregatingCursor() throw () {}
72 virtual rtl::Reference
< Entity
> getNext(OUString
* name
);
76 std::vector
< rtl::Reference
< Provider
> > providers_
;
78 std::vector
< rtl::Reference
< Provider
> >::iterator iterator_
;
79 rtl::Reference
< MapCursor
> cursor_
;
80 std::set
< OUString
> seen_
;
83 rtl::Reference
< Entity
> AggregatingCursor::getNext(OUString
* name
) {
84 while (cursor_
.is()) {
86 rtl::Reference
< Entity
> ent(cursor_
->getNext(&n
));
88 if (seen_
.insert(n
).second
) {
92 return ent
->getSort() == Entity::SORT_MODULE
93 ? new AggregatingModule(
94 providers_
, (name_
.isEmpty() ? name_
: name_
+ ".") + n
)
102 return rtl::Reference
< Entity
>();
105 void AggregatingCursor::findCursor() {
106 for (; !cursor_
.is() && iterator_
!= providers_
.end(); ++iterator_
) {
107 if (name_
.isEmpty()) {
108 cursor_
= (*iterator_
)->createRootCursor();
110 rtl::Reference
< Entity
> ent((*iterator_
)->findEntity(name_
));
111 if (ent
.is() && ent
->getSort() == Entity::SORT_MODULE
) {
112 cursor_
= static_cast< ModuleEntity
* >(ent
.get())->
119 rtl::Reference
< MapCursor
> AggregatingModule::createCursor() const {
120 return new AggregatingCursor(providers_
, name_
);
125 NoSuchFileException::~NoSuchFileException() throw () {}
127 FileFormatException::~FileFormatException() throw () {}
129 Entity::~Entity() throw () {}
131 MapCursor::~MapCursor() throw () {}
133 ModuleEntity::~ModuleEntity() throw () {}
135 PublishableEntity::~PublishableEntity() throw () {}
137 EnumTypeEntity::~EnumTypeEntity() throw () {}
139 PlainStructTypeEntity::~PlainStructTypeEntity() throw () {}
141 PolymorphicStructTypeTemplateEntity::~PolymorphicStructTypeTemplateEntity()
145 ExceptionTypeEntity::~ExceptionTypeEntity() throw () {}
147 InterfaceTypeEntity::~InterfaceTypeEntity() throw () {}
149 TypedefEntity::~TypedefEntity() throw () {}
151 ConstantGroupEntity::~ConstantGroupEntity() throw () {}
153 SingleInterfaceBasedServiceEntity::~SingleInterfaceBasedServiceEntity() throw ()
156 AccumulationBasedServiceEntity::~AccumulationBasedServiceEntity() throw () {}
158 InterfaceBasedSingletonEntity::~InterfaceBasedSingletonEntity() throw () {}
160 ServiceBasedSingletonEntity::~ServiceBasedSingletonEntity() throw () {}
162 Provider::~Provider() throw () {}
164 rtl::Reference
< Provider
> loadProvider(
165 rtl::Reference
< Manager
> const & manager
, OUString
const & uri
)
168 return new UnoidlProvider(uri
);
169 } catch (FileFormatException
& e
) {
172 "FileFormatException \"" << e
.getDetail() << "\", retrying <" << uri
173 << "> as legacy format");
174 return new LegacyProvider(manager
, uri
);
178 void Manager::addProvider(rtl::Reference
< Provider
> const & provider
) {
179 assert(provider
.is());
180 osl::MutexGuard
g(mutex_
);
181 providers_
.push_back(provider
);
184 rtl::Reference
< Entity
> Manager::findEntity(rtl::OUString
const & name
) const {
185 //TODO: caching? (here or in cppuhelper::TypeManager?)
186 osl::MutexGuard
g(mutex_
);
187 for (std::vector
< rtl::Reference
< Provider
> >::const_iterator
i(
189 i
!= providers_
.end(); ++i
)
191 rtl::Reference
< Entity
> ent((*i
)->findEntity(name
));
196 return rtl::Reference
< Entity
>();
199 rtl::Reference
< MapCursor
> Manager::createCursor(rtl::OUString
const & name
)
202 return new AggregatingCursor(providers_
, name
);
205 Manager::~Manager() throw () {}
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */