bump product version to 6.4.0.3
[LibreOffice.git] / unoidl / source / unoidl.cxx
blobcabf575efd3d213d470b6799be9474605a7f19ef
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>
11 #include <sal/log.hxx>
13 #include <set>
14 #include <vector>
16 #include <osl/file.h>
17 #include <osl/file.hxx>
18 #include <osl/mutex.hxx>
19 #include <rtl/ref.hxx>
20 #include <rtl/ustring.hxx>
21 #include <unoidl/unoidl.hxx>
23 #include "legacyprovider.hxx"
24 #include "sourcefileprovider.hxx"
25 #include "sourcetreeprovider.hxx"
26 #include "unoidlprovider.hxx"
28 namespace unoidl {
30 namespace {
32 class AggregatingModule: public ModuleEntity {
33 public:
34 AggregatingModule(
35 std::vector< rtl::Reference< Provider > > const & providers,
36 OUString const & name):
37 providers_(providers), name_(name)
40 private:
41 virtual ~AggregatingModule() throw () override {}
43 virtual std::vector< OUString > getMemberNames() const override;
45 virtual rtl::Reference< MapCursor > createCursor() const override;
47 std::vector< rtl::Reference< Provider > > providers_;
48 OUString const name_;
51 std::vector< OUString > AggregatingModule::getMemberNames() const {
52 std::set< OUString > names;
53 for (auto & i: providers_) {
54 rtl::Reference< Entity > ent(i->findEntity(name_));
55 if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
56 std::vector< OUString > ns(
57 static_cast< ModuleEntity * >(ent.get())->getMemberNames());
58 names.insert(ns.begin(), ns.end());
61 return std::vector< OUString >(names.begin(), names.end());
64 class AggregatingCursor: public MapCursor {
65 public:
66 AggregatingCursor(
67 std::vector< rtl::Reference< Provider > > const & providers,
68 OUString const & name):
69 providers_(providers), name_(name), iterator_(providers_.begin())
70 { findCursor(); }
72 private:
73 virtual ~AggregatingCursor() throw () override {}
75 virtual rtl::Reference< Entity > getNext(OUString * name) override;
77 void findCursor();
79 std::vector< rtl::Reference< Provider > > providers_;
80 OUString const name_;
81 std::vector< rtl::Reference< Provider > >::iterator iterator_;
82 rtl::Reference< MapCursor > cursor_;
83 std::set< OUString > seen_;
86 rtl::Reference< Entity > AggregatingCursor::getNext(OUString * name) {
87 while (cursor_.is()) {
88 OUString n;
89 rtl::Reference< Entity > ent(cursor_->getNext(&n));
90 if (ent.is()) {
91 if (seen_.insert(n).second) {
92 if (name != nullptr) {
93 *name = n;
95 return ent->getSort() == Entity::SORT_MODULE
96 ? new AggregatingModule(
97 providers_, (name_.isEmpty() ? name_ : name_ + ".") + n)
98 : ent;
100 } else {
101 cursor_.clear();
102 findCursor();
105 return rtl::Reference< Entity >();
108 void AggregatingCursor::findCursor() {
109 for (; !cursor_.is() && iterator_ != providers_.end(); ++iterator_) {
110 if (name_.isEmpty()) {
111 cursor_ = (*iterator_)->createRootCursor();
112 } else {
113 rtl::Reference< Entity > ent((*iterator_)->findEntity(name_));
114 if (ent.is() && ent->getSort() == Entity::SORT_MODULE) {
115 cursor_ = static_cast< ModuleEntity * >(ent.get())->
116 createCursor();
122 rtl::Reference< MapCursor > AggregatingModule::createCursor() const {
123 return new AggregatingCursor(providers_, name_);
128 NoSuchFileException::~NoSuchFileException() throw () {}
130 FileFormatException::~FileFormatException() throw () {}
132 Entity::~Entity() throw () {}
134 MapCursor::~MapCursor() throw () {}
136 ModuleEntity::~ModuleEntity() throw () {}
138 PublishableEntity::~PublishableEntity() throw () {}
140 EnumTypeEntity::~EnumTypeEntity() throw () {}
142 PlainStructTypeEntity::~PlainStructTypeEntity() throw () {}
144 PolymorphicStructTypeTemplateEntity::~PolymorphicStructTypeTemplateEntity()
145 throw ()
148 ExceptionTypeEntity::~ExceptionTypeEntity() throw () {}
150 InterfaceTypeEntity::~InterfaceTypeEntity() throw () {}
152 TypedefEntity::~TypedefEntity() throw () {}
154 ConstantGroupEntity::~ConstantGroupEntity() throw () {}
156 SingleInterfaceBasedServiceEntity::~SingleInterfaceBasedServiceEntity() throw ()
159 AccumulationBasedServiceEntity::~AccumulationBasedServiceEntity() throw () {}
161 InterfaceBasedSingletonEntity::~InterfaceBasedSingletonEntity() throw () {}
163 ServiceBasedSingletonEntity::~ServiceBasedSingletonEntity() throw () {}
165 Provider::~Provider() throw () {}
167 rtl::Reference< Provider > Manager::addProvider(OUString const & uri) {
168 rtl::Reference< Provider > p(loadProvider(uri));
169 assert(p.is());
171 osl::MutexGuard g(mutex_);
172 providers_.push_back(p);
174 return p;
177 rtl::Reference< Entity > Manager::findEntity(OUString const & name) const {
178 //TODO: caching? (here or in cppuhelper::TypeManager?)
179 osl::MutexGuard g(mutex_);
180 for (auto & i: providers_) {
181 rtl::Reference< Entity > ent(i->findEntity(name));
182 if (ent.is()) {
183 return ent;
186 return rtl::Reference< Entity >();
189 rtl::Reference< MapCursor > Manager::createCursor(OUString const & name)
190 const
192 return new AggregatingCursor(providers_, name);
195 Manager::~Manager() throw () {}
197 rtl::Reference< Provider > Manager::loadProvider(OUString const & uri) {
198 osl::DirectoryItem item;
199 if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None) {
200 osl::FileStatus status(osl_FileStatus_Mask_Type);
201 if (item.getFileStatus(status) == osl::FileBase::E_None
202 && status.getFileType() == osl::FileStatus::Directory)
204 return new detail::SourceTreeProvider(*this, uri);
207 if (uri.endsWith(".idl")) {
208 return new detail::SourceFileProvider(this, uri);
210 try {
211 return new detail::UnoidlProvider(uri);
212 } catch (FileFormatException & e) {
213 SAL_INFO(
214 "unoidl",
215 "FileFormatException \"" << e.getDetail() << "\", retrying <" << uri
216 << "> as legacy format");
217 return new detail::LegacyProvider(*this, uri);
223 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */