bump product version to 4.1.6.2
[LibreOffice.git] / unoidl / source / unoidl.cxx
blobc55e02be01fcec58c3b316ed2ed3b08ce89d176e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include "sal/config.h"
12 #include <set>
13 #include <vector>
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"
22 namespace unoidl {
24 namespace {
26 class AggregatingModule: public ModuleEntity {
27 public:
28 AggregatingModule(
29 std::vector< rtl::Reference< Provider > > const & providers,
30 OUString const & name):
31 providers_(providers), name_(name)
34 private:
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_;
42 OUString name_;
45 std::vector< OUString > AggregatingModule::getMemberNames() const {
46 std::set< OUString > names;
47 for (std::vector< rtl::Reference< Provider > >::const_iterator i(
48 providers_.begin());
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 {
62 public:
63 AggregatingCursor(
64 std::vector< rtl::Reference< Provider > > const & providers,
65 OUString const & name):
66 providers_(providers), name_(name), iterator_(providers_.begin())
67 { findCursor(); }
69 private:
70 virtual ~AggregatingCursor() throw () {}
72 virtual rtl::Reference< Entity > getNext(OUString * name);
74 void findCursor();
76 std::vector< rtl::Reference< Provider > > providers_;
77 OUString name_;
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()) {
85 OUString n;
86 rtl::Reference< Entity > ent(cursor_->getNext(&n));
87 if (ent.is()) {
88 if (seen_.insert(n).second) {
89 if (name != 0) {
90 *name = n;
92 return ent->getSort() == Entity::SORT_MODULE
93 ? new AggregatingModule(
94 providers_, (name_.isEmpty() ? name_ : name_ + ".") + n)
95 : ent;
97 } else {
98 cursor_.clear();
99 findCursor();
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();
109 } else {
110 rtl::Reference< Entity > ent((*iterator_)->findEntity(name_));
111 if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
112 cursor_ = static_cast< ModuleEntity * >(ent.get())->
113 createCursor();
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()
142 throw ()
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)
167 try {
168 return new UnoidlProvider(uri);
169 } catch (FileFormatException & e) {
170 SAL_INFO(
171 "unoidl",
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(
188 providers_.begin());
189 i != providers_.end(); ++i)
191 rtl::Reference< Entity > ent((*i)->findEntity(name));
192 if (ent.is()) {
193 return ent;
196 return rtl::Reference< Entity >();
199 rtl::Reference< MapCursor > Manager::createCursor(rtl::OUString const & name)
200 const
202 return new AggregatingCursor(providers_, name);
205 Manager::~Manager() throw () {}
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */