Keyple Service C++ Library - 3.4.1
Component of the Keyple C++ middleware
AbstractPluginAdapter.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional *
5 * information regarding copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the *
8 * terms of the Eclipse Public License 2.0 which is available at *
9 * http://www.eclipse.org/legal/epl-2.0 *
10 * *
11 * SPDX-License-Identifier: EPL-2.0 *
12 ******************************************************************************/
13
14#include "keyple/core/service/AbstractPluginAdapter.hpp"
15
16#include <map>
17#include <memory>
18#include <string>
19#include <utility>
20#include <vector>
21
22#include "keyple/core/service/AbstractReaderAdapter.hpp"
23#include "keyple/core/service/LocalConfigurableReaderAdapter.hpp"
24#include "keyple/core/service/ObservableLocalConfigurableReaderAdapter.hpp"
25#include "keyple/core/util/cpp/StringUtils.hpp"
26#include "keyple/core/util/cpp/exception/Exception.hpp"
27#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
28#include "keyple/core/util/cpp/exception/IllegalStateException.hpp"
29
30namespace keyple {
31namespace core {
32namespace service {
33
34using keyple::core::util::cpp::StringUtils;
35using keyple::core::util::cpp::exception::Exception;
36using keyple::core::util::cpp::exception::IllegalArgumentException;
37using keyple::core::util::cpp::exception::IllegalStateException;
38
39AbstractPluginAdapter::AbstractPluginAdapter(
40 const std::string& pluginName,
41 std::shared_ptr<KeyplePluginExtension> pluginExtension)
42: mPluginName(pluginName)
43, mPluginExtension(pluginExtension)
44, mIsRegistered(false)
45{
46}
47
48std::shared_ptr<LocalReaderAdapter>
49AbstractPluginAdapter::buildLocalReaderAdapter(
50 std::shared_ptr<ReaderSpi> readerSpi)
51{
52 std::shared_ptr<LocalReaderAdapter> adapter = nullptr;
53
54 const auto& observable
55 = std::dynamic_pointer_cast<ObservableReaderSpi>(readerSpi);
56 const auto& configurable
57 = std::dynamic_pointer_cast<ConfigurableReaderSpi>(readerSpi);
58
59 if (observable) {
60 if (configurable) {
61 adapter
62 = std::make_shared<ObservableLocalConfigurableReaderAdapter>(
63 configurable, getName());
64 } else {
65 adapter = std::make_shared<ObservableLocalReaderAdapter>(
66 observable, getName());
67 }
68 } else if (configurable) {
69 adapter = std::make_shared<LocalConfigurableReaderAdapter>(
70 configurable, getName());
71 } else {
72 adapter = std::make_shared<LocalReaderAdapter>(readerSpi, getName());
73 }
74
75 return adapter;
76}
77
78void
79AbstractPluginAdapter::checkStatus() const
80{
81 if (!mIsRegistered) {
82 throw IllegalStateException(
83 "Plugin '" + mPluginName + "' is not or no longer registered");
84 }
85}
86
87void
88AbstractPluginAdapter::doRegister()
89{
90 mIsRegistered = true;
91}
92
93void
94AbstractPluginAdapter::doUnregister()
95{
96 mIsRegistered = false;
97
98 for (const auto& reader : mReaders) {
99 try {
100 std::dynamic_pointer_cast<AbstractReaderAdapter>(reader.second)
101 ->doUnregister();
102 } catch (const Exception& e) {
103 mLogger->warn(
104 "[plugin=%] Failed to unregister reader [reader=%, reason=%]\n",
105 mPluginName,
106 reader.second->getName(),
107 e.getMessage());
108 }
109 }
110
111 mReaders.clear();
112 mIsRegistered = false;
113}
114
115const std::string&
116AbstractPluginAdapter::getName() const
117{
118 return mPluginName;
119}
120
121std::shared_ptr<KeyplePluginExtension>
122AbstractPluginAdapter::getExtension(
123 const std::type_info& pluginExtensionClass) const
124{
125 (void)pluginExtensionClass;
126
127 checkStatus();
128
129 return mPluginExtension;
130}
131
132std::shared_ptr<KeypleReaderExtension>
133AbstractPluginAdapter::getReaderExtension(
134 const std::type_info& readerExtensionClass,
135 const std::string& readerName) const
136{
137 checkStatus();
138
139 const auto reader = std::dynamic_pointer_cast<AbstractReaderAdapter>(
140 getReader(readerName));
141 if (reader == nullptr) {
142 throw IllegalArgumentException(
143 "Reader '" + readerName + "' is not found");
144 }
145
146 return reader->getExtension(readerExtensionClass);
147}
148
149std::map<const std::string, std::shared_ptr<CardReader>>&
150AbstractPluginAdapter::getReadersMap()
151{
152 return mReaders;
153}
154
155const std::vector<std::string>
156AbstractPluginAdapter::getReaderNames() const
157{
158 checkStatus();
159
160 std::vector<std::string> readerNames;
161 for (const auto& pair : mReaders) {
162 readerNames.push_back(pair.first);
163 }
164
165 return readerNames;
166}
167
168const std::vector<std::shared_ptr<CardReader>>
169AbstractPluginAdapter::getReaders() const
170{
171 checkStatus();
172
173 std::vector<std::shared_ptr<CardReader>> readers;
174 for (const auto& pair : mReaders) {
175 readers.push_back(pair.second);
176 }
177
178 return readers;
179}
180
181std::shared_ptr<CardReader>
182AbstractPluginAdapter::getReader(const std::string& name) const
183{
184 checkStatus();
185
186 if (mReaders.find(name) != mReaders.end()) {
187 return mReaders.at(name);
188 }
189
190 return nullptr;
191}
192
193std::shared_ptr<CardReader>
194AbstractPluginAdapter::findReader(const std::string& readerNameRegex) const
195{
196 for (const auto& reader : mReaders) {
197 try {
198 if (StringUtils::matches(
199 reader.second->getName(), readerNameRegex)) {
200 return reader.second;
201 }
202
203 } catch (const std::regex_error& e) {
204 throw IllegalArgumentException(
205 "Parameter 'readerNameRegex' has an invalid regex syntax:"
206 + readerNameRegex + ": " + e.what());
207 }
208 }
209
210 return nullptr;
211}
212
213} /* namespace service */
214} /* namespace core */
215} /* namespace keyple */