Keyple Plugin Stub C++ Library - 2.2.2
Component of the Keyple C++ middleware
StubPoolPluginAdapter.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * This program and the accompanying materials are made available under the *
5 * terms of the MIT License which is available at *
6 * https://opensource.org/licenses/MIT. *
7 * *
8 * SPDX-License-Identifier: MIT *
9 ******************************************************************************/
10
11#include "keyple/plugin/stub/StubPoolPluginAdapter.hpp"
12
13#include <algorithm>
14
15#include "keyple/core/plugin/PluginIOException.hpp"
16#include "keyple/core/util/KeypleAssert.hpp"
17#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp"
18
19namespace keyple {
20namespace plugin {
21namespace stub {
22
23using keyple::core::plugin::PluginIOException;
24using keyple::core::plugin::spi::PoolReaderSpi;
25using keyple::core::util::Assert;
26using keyple::core::util::cpp::exception::IllegalArgumentException;
27
28StubPoolPluginAdapter::StubPoolPluginAdapter(
29 const std::string& name,
30 const std::vector<std::shared_ptr<StubPoolReaderConfiguration>>&
31 readerConfigurations,
32 const int monitoringCycleDuration)
33{
34 /*
35 * C++: cannot directly use readerConfigurations to build
36 * mStubPluginAdapter, need to cast to a new sort of vector
37 */
38 std::vector<std::shared_ptr<StubReaderConfiguration>> configurations;
39 for (const auto& config : readerConfigurations) {
40 configurations.push_back(
41 std::dynamic_pointer_cast<StubReaderConfiguration>(config));
42 }
43
44 mStubPluginAdapter = std::make_shared<StubPluginAdapter>(
45 name, configurations, monitoringCycleDuration);
46
47 for (const auto& readerConfiguration : readerConfigurations) {
48 mReaderToGroup.insert(
49 {readerConfiguration->getName(),
50 readerConfiguration->getGroupReference()});
51 }
52}
53
54const std::string&
55StubPoolPluginAdapter::getName() const
56{
57 return mStubPluginAdapter->getName();
58}
59
60const std::vector<std::shared_ptr<ReaderSpi>>
61StubPoolPluginAdapter::searchAvailableReaders()
62{
63 return mStubPluginAdapter->searchAvailableReaders();
64}
65
66const std::vector<std::string>
67StubPoolPluginAdapter::getReaderGroupReferences() const
68{
69 std::vector<std::string> references;
70 for (const auto& ref : mReaderToGroup) {
71 references.push_back(ref.second);
72 }
73
74 return references;
75}
76
77std::shared_ptr<PoolReaderSpi>
78StubPoolPluginAdapter::allocateReader(const std::string& readerGroupReference)
79{
80 std::vector<std::string> candidateReadersName;
81
82 if (readerGroupReference == "") {
83 /* Every reader is candidate for allocation */
84 candidateReadersName = mStubPluginAdapter->searchAvailableReaderNames();
85 } else {
86 /* Only readers from the readerGroupReference are candidates for
87 * allocation */
88 candidateReadersName = listReadersByGroup(readerGroupReference);
89 }
90
91 /* Find the first non allocated reader among candidates */
92 for (const auto& readerName : candidateReadersName) {
93 /* Find if already existing */
94 const auto it = std::find(
95 mAllocatedReaders.begin(), mAllocatedReaders.end(), readerName);
96 if (it == mAllocatedReaders.end()) {
97 mAllocatedReaders.push_back(readerName);
98 return std::dynamic_pointer_cast<PoolReaderSpi>(
99 mStubPluginAdapter->searchReader(readerName));
100 }
101 }
102
103 throw PluginIOException(
104 "No reader is available for the given group reference:"
105 + readerGroupReference);
106}
107
108void
109StubPoolPluginAdapter::releaseReader(std::shared_ptr<ReaderSpi> readerSpi)
110{
111 Assert::getInstance().notNull(readerSpi, "reader SPI");
112
113 const auto stub = std::dynamic_pointer_cast<StubReader>(readerSpi);
114 if (!stub) {
115 throw IllegalArgumentException(
116 std::string("Cannot cast 'readerSpi' to StubReader. Actual type: ")
117 + typeid(readerSpi).name());
118 }
119
120 const auto it = std::find(
121 mAllocatedReaders.begin(),
122 mAllocatedReaders.end(),
123 readerSpi->getName());
124 mAllocatedReaders.erase(it);
125}
126
127void
128StubPoolPluginAdapter::onUnregister()
129{
130 /* NO-OP */
131}
132
133void
134StubPoolPluginAdapter::plugPoolReader(
135 const std::string& groupReference,
136 const std::string& readerName,
137 std::shared_ptr<StubSmartCard> card)
138{
139 /* Create new reader */
140 mStubPluginAdapter->plugReader(readerName, false, card);
141
142 /* Map reader to groupReference */
143 mReaderToGroup.insert({readerName, groupReference});
144}
145
146void
147StubPoolPluginAdapter::unplugPoolReaders(const std::string& groupReference)
148{
149 /* Find the reader in the readerPool */
150 const std::vector<std::string> readerNames
151 = listReadersByGroup(groupReference);
152 for (const auto& readerName : readerNames) {
153 unplugPoolReader(readerName);
154 }
155}
156
157void
158StubPoolPluginAdapter::unplugPoolReader(const std::string& readerName)
159{
160 /* Remove reader from pool */
161 mReaderToGroup.erase(mReaderToGroup.find(readerName));
162
163 /* Remove reader from allocate list */
164 const auto it = std::find(
165 mAllocatedReaders.begin(), mAllocatedReaders.end(), readerName);
166 if (it != mAllocatedReaders.end()) {
167 mAllocatedReaders.erase(it);
168 }
169
170 /* Remove reader from plugin */
171 mStubPluginAdapter->unplugReader(readerName);
172}
173
174int
175StubPoolPluginAdapter::getMonitoringCycleDuration() const
176{
177 return mStubPluginAdapter->getMonitoringCycleDuration();
178}
179
180const std::vector<std::string>
181StubPoolPluginAdapter::searchAvailableReaderNames()
182{
183 return mStubPluginAdapter->searchAvailableReaderNames();
184}
185
186std::shared_ptr<ReaderSpi>
187StubPoolPluginAdapter::searchReader(const std::string& readerName)
188{
189 return mStubPluginAdapter->searchReader(readerName);
190}
191
192const std::vector<std::string>
193StubPoolPluginAdapter::listReadersByGroup(const std::string& aGroupReference)
194{
195 std::vector<std::string> readers;
196
197 /* Find the reader in the readerPool */
198 for (const auto& entry : mReaderToGroup) {
199 const std::string readerName = entry.first;
200 const std::string groupReference = entry.second;
201 if (groupReference == aGroupReference) {
202 readers.push_back(readerName);
203 }
204 }
205
206 return readers;
207}
208
209} /* namespace stub */
210} /* namespace plugin */
211} /* namespace keyple */