Line data Source code
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 :
10 : #include "sal/config.h"
11 :
12 : #include <set>
13 : #include <vector>
14 :
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"
21 :
22 : namespace unoidl {
23 :
24 : namespace {
25 :
26 : class AggregatingCursor: public MapCursor {
27 : public:
28 487 : AggregatingCursor(
29 : std::vector< rtl::Reference< MapCursor > > const & cursors):
30 487 : cursors_(cursors), iterator_(cursors_.begin())
31 487 : {}
32 :
33 : private:
34 974 : virtual ~AggregatingCursor() throw () {}
35 :
36 : virtual rtl::Reference< Entity > getNext(rtl::OUString * name);
37 :
38 : std::vector< rtl::Reference< MapCursor > > cursors_;
39 : std::vector< rtl::Reference< MapCursor > >::iterator iterator_;
40 : std::set< rtl::OUString > seenMembers;
41 : };
42 :
43 18174 : rtl::Reference< Entity > AggregatingCursor::getNext(rtl::OUString * name) {
44 : for (;;) {
45 18174 : if (iterator_ == cursors_.end()) {
46 17436 : return rtl::Reference< Entity >();
47 : }
48 17687 : rtl::OUString n;
49 18912 : rtl::Reference< Entity > ent((*iterator_)->getNext(&n));
50 17687 : if (ent.is()) {
51 17110 : if (seenMembers.insert(n).second) {
52 16462 : if (name != 0) {
53 16462 : *name = n;
54 : }
55 16462 : return ent;
56 : }
57 : } else {
58 577 : ++iterator_;
59 : }
60 1225 : }
61 : }
62 :
63 : }
64 :
65 0 : NoSuchFileException::~NoSuchFileException() throw () {}
66 :
67 8 : FileFormatException::~FileFormatException() throw () {}
68 :
69 557775 : Entity::~Entity() throw () {}
70 :
71 1263 : MapCursor::~MapCursor() throw () {}
72 :
73 2425 : ModuleEntity::~ModuleEntity() throw () {}
74 :
75 555350 : PublishableEntity::~PublishableEntity() throw () {}
76 :
77 27118 : EnumTypeEntity::~EnumTypeEntity() throw () {}
78 :
79 88182 : PlainStructTypeEntity::~PlainStructTypeEntity() throw () {}
80 :
81 2270 : PolymorphicStructTypeTemplateEntity::~PolymorphicStructTypeTemplateEntity()
82 1135 : throw ()
83 2270 : {}
84 :
85 114580 : ExceptionTypeEntity::~ExceptionTypeEntity() throw () {}
86 :
87 812706 : InterfaceTypeEntity::~InterfaceTypeEntity() throw () {}
88 :
89 6072 : TypedefEntity::~TypedefEntity() throw () {}
90 :
91 26712 : ConstantGroupEntity::~ConstantGroupEntity() throw () {}
92 :
93 10134 : SingleInterfaceBasedServiceEntity::~SingleInterfaceBasedServiceEntity() throw ()
94 10134 : {}
95 :
96 21028 : AccumulationBasedServiceEntity::~AccumulationBasedServiceEntity() throw () {}
97 :
98 1890 : InterfaceBasedSingletonEntity::~InterfaceBasedSingletonEntity() throw () {}
99 :
100 8 : ServiceBasedSingletonEntity::~ServiceBasedSingletonEntity() throw () {}
101 :
102 307 : Provider::~Provider() throw () {}
103 :
104 695 : rtl::Reference< Provider > loadProvider(
105 : rtl::Reference< Manager > const & manager, OUString const & uri)
106 : {
107 : try {
108 695 : return new UnoidlProvider(uri);
109 8 : } catch (FileFormatException & e) {
110 : SAL_INFO(
111 : "unoidl",
112 : "FileFormatException \"" << e.getDetail() << "\", retrying <" << uri
113 : << "> as legacy format");
114 8 : return new LegacyProvider(manager, uri);
115 : }
116 : }
117 :
118 687 : void Manager::addProvider(rtl::Reference< Provider > const & provider) {
119 : assert(provider.is());
120 687 : osl::MutexGuard g(mutex_);
121 687 : providers_.push_back(provider);
122 687 : }
123 :
124 517351 : rtl::Reference< Entity > Manager::findEntity(rtl::OUString const & name) const {
125 : //TODO: caching? (here or in cppuhelper::TypeManager?)
126 517351 : osl::MutexGuard g(mutex_);
127 2464670 : for (std::vector< rtl::Reference< Provider > >::const_iterator i(
128 517351 : providers_.begin());
129 1988014 : i != providers_.end(); ++i)
130 : {
131 993853 : rtl::Reference< Entity > ent((*i)->findEntity(name));
132 993853 : if (ent.is()) {
133 517197 : return ent;
134 : }
135 476656 : }
136 154 : return rtl::Reference< Entity >();
137 : }
138 :
139 487 : rtl::Reference< MapCursor > Manager::createCursor(rtl::OUString const & name)
140 : const
141 : {
142 487 : std::vector< rtl::Reference< MapCursor > > curs;
143 4887 : for (std::vector< rtl::Reference< Provider > >::const_iterator i(
144 487 : providers_.begin());
145 3258 : i != providers_.end(); ++i)
146 : {
147 1142 : if (name.isEmpty()) {
148 28 : curs.push_back((*i)->createRootCursor());
149 : } else {
150 1114 : rtl::Reference< Entity > ent((*i)->findEntity(name));
151 1114 : if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
152 : curs.push_back(
153 549 : static_cast< ModuleEntity * >(ent.get())->createCursor());
154 1114 : }
155 : }
156 : }
157 487 : return curs.empty()
158 487 : ? rtl::Reference< MapCursor >() : new AggregatingCursor(curs);
159 : }
160 :
161 242 : Manager::~Manager() throw () {}
162 :
163 : }
164 :
165 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|