FOSSredder 0.5.0
Loading...
Searching...
No Matches
WorkspaceQueryService.cpp
Go to the documentation of this file.
1
5
6#include "core/pch.h"
7
9
13
14#include <algorithm>
15
16namespace {
17
18constexpr auto kContractBaseName = "Contract";
19
20std::string normalizedText(const std::string& value) {
22}
23
24std::vector<std::string> normalizedSorted(std::vector<std::string> values) {
25 std::vector<std::string> out;
26 out.reserve(values.size());
27 for (const auto& value : values) {
28 const auto normalized = core::domain::policies::alias::trimCopy(value);
29 if (!normalized.empty()) {
30 out.push_back(normalized);
31 }
32 }
33 std::sort(out.begin(), out.end());
34 return out;
35}
36
37bool sameStringSet(const std::vector<std::string>& lhs,
38 const std::vector<std::string>& rhs) {
39 return normalizedSorted(lhs) == normalizedSorted(rhs);
40}
41
42std::vector<std::string> normalizedValues(const std::vector<std::string>& values) {
43 std::vector<std::string> out;
44 out.reserve(values.size());
45 for (const auto& value : values) {
46 const auto normalized = core::domain::policies::alias::trimCopy(value);
47 if (!normalized.empty()) {
48 out.push_back(normalized);
49 }
50 }
51 return out;
52}
53
54bool containsValue(const std::vector<std::string>& values,
55 const std::string& value) {
56 const auto target = core::domain::policies::alias::trimCopy(value);
57 if (target.empty()) {
58 return false;
59 }
60 const auto normalized = normalizedValues(values);
61 return std::find(normalized.begin(), normalized.end(), target) != normalized.end();
62}
63
64bool containsAllValues(const std::vector<std::string>& values,
65 const std::vector<std::string>& required) {
66 const auto normalizedRequired = normalizedValues(required);
67 return std::all_of(normalizedRequired.begin(), normalizedRequired.end(),
68 [&](const std::string& value) {
69 return containsValue(values, value);
70 });
71}
72
73int trailingContractIndex(const std::string& value) {
74 const auto trimmed = core::domain::policies::alias::trimCopy(value);
75 const std::string prefix = std::string(kContractBaseName) + " ";
76 if (trimmed.size() <= prefix.size() ||
77 normalizedText(trimmed.substr(0, prefix.size())) != normalizedText(prefix)) {
78 return -1;
79 }
80 try {
81 std::size_t consumed = 0;
82 const int index = std::stoi(trimmed.substr(prefix.size()), &consumed);
83 return consumed == trimmed.size() - prefix.size() ? index : -1;
84 } catch (...) {
85 return -1;
86 }
87}
88
90 const std::string& id,
91 const std::string& name) {
93 out.id = id;
94 out.name = name;
95 return out;
96}
97
98const core::domain::Contract* findContractById(
100 const std::string& id) {
101 const auto target = core::domain::policies::alias::trimCopy(id);
102 if (target.empty()) {
103 return nullptr;
104 }
105 for (const auto& contract : state.catalog.contracts()) {
106 if (contract && contract->id() == target) {
107 return contract.get();
108 }
109 }
110 return nullptr;
111}
112
113} // namespace
114
115namespace core::application {
116
118 : session_(&session) {
119}
120
122
124
125const core::application::workspace::WorkspaceSessionState& WorkspaceQueryService::stateRef() const noexcept {
126 return session_->state();
127}
128
130 return projector_.project(stateRef(), currentPath());
131}
132
133const std::string& WorkspaceQueryService::currentPath() const noexcept {
134 return session_->currentPath();
135}
136
137std::optional<core::ports::workspace::StatementDraftSnapshot> WorkspaceQueryService::statementDraftSnapshot(const std::string& draftId) const {
138 return projector_.projectStatementDraft(stateRef(), draftId);
139}
140
142 const auto target = normalizedText(name);
143 if (target.empty()) {
144 return {};
145 }
146 for (const auto& actor : stateRef().catalog.actors()) {
147 if (actor && normalizedText(actor->name()) == target) {
148 return identity(actor->id(), actor->name());
149 }
150 }
151 return {};
152}
153
155 const auto target = normalizedText(name);
156 if (target.empty()) {
157 return {};
158 }
159 for (const auto& property : stateRef().catalog.properties()) {
160 if (property && normalizedText(property->name()) == target) {
161 return identity(property->id(), property->name());
162 }
163 }
164 return {};
165}
166
168 const std::string& name,
169 const std::string& type,
170 const std::vector<std::string>& actorIds,
171 const std::vector<std::string>& propertyIds) const {
172 const auto normalizedName = normalizedText(name);
173 const auto normalizedType = normalizedText(type);
174 if (normalizedName.empty() || normalizedType.empty()) {
175 return {};
176 }
177 for (const auto& contract : stateRef().catalog.contracts()) {
178 if (!contract ||
179 normalizedText(contract->name()) != normalizedName ||
180 normalizedText(contract->type()) != normalizedType ||
181 !sameStringSet(contract->actorIds(), actorIds) ||
182 !sameStringSet(contract->propertyIds(), propertyIds)) {
183 continue;
184 }
185
186 auto out = identity(contract->id(), contract->name());
187 out.type = contract->type();
188 out.allocatableMode = contract->allocatableMode();
189 out.actorIds = normalizedSorted(contract->actorIds());
190 out.propertyIds = normalizedSorted(contract->propertyIds());
191 return out;
192 }
193 return {};
194}
195
200
201 if (change.contractChanged) {
203 if (const auto* contract = findContractById(stateRef(), out.contractId)) {
204 const auto actorIds = normalizedValues(contract->actorIds());
205 out.actorId = actorIds.empty() ? std::string{} : actorIds.front();
206 out.propertyIds = normalizedValues(contract->propertyIds());
207 } else {
208 out.actorId.clear();
209 out.propertyIds.clear();
210 }
211 }
212
213 if (change.actorChanged) {
215 const auto* contract = findContractById(stateRef(), out.contractId);
216 if (contract && !out.actorId.empty() &&
217 !containsValue(contract->actorIds(), out.actorId)) {
218 out.contractId.clear();
219 }
220 }
221
222 if (change.propertiesChanged) {
223 out.propertyIds = normalizedValues(change.propertyIds);
224 const auto* contract = findContractById(stateRef(), out.contractId);
225 if (contract && !containsAllValues(contract->propertyIds(), out.propertyIds)) {
226 out.contractId.clear();
227 }
228 }
229
230 return out;
231}
232
234 int maxIndex = 0;
235 for (const auto& contract : stateRef().catalog.contracts()) {
236 if (!contract) {
237 continue;
238 }
239 maxIndex = std::max(maxIndex, trailingContractIndex(contract->name()));
240 }
241 return std::string(kContractBaseName) + " " + std::to_string(maxIndex + 1);
242}
243
244} // namespace core::application
Shared alias normalization and ranking helpers for core entities.
Domain model for contracts.
Reads workspace snapshots and draft projections from the application layer.
Declares the mutable workspace session that ties in-memory state to storage.
core::ports::workspace::WorkspaceSnapshot workspaceSnapshot() const
Projects full workspace snapshot for port consumers.
std::optional< core::ports::workspace::StatementDraftSnapshot > statementDraftSnapshot(const std::string &draftId={}) const
Projects one statement draft snapshot.
core::ports::workspace::WorkspaceIdentitySnapshot contractIdentityBySignature(const std::string &name, const std::string &type, const std::vector< std::string > &actorIds, const std::vector< std::string > &propertyIds) const
Finds a contract identity by normalized signature.
core::ports::workspace::TransactionCatalogSelection transactionCatalogSelection(const core::ports::workspace::TransactionCatalogSelectionChange &change) const
Applies catalog consistency rules to a transaction form selection.
WorkspaceQueryService(WorkspaceSession &session)
Creates the query service for one workspace session.
core::ports::workspace::WorkspaceIdentitySnapshot actorIdentityByName(const std::string &name) const
Finds an actor identity by normalized name.
std::string nextContractName() const
Returns the next generated contract name.
core::ports::workspace::WorkspaceIdentitySnapshot propertyIdentityByName(const std::string &name) const
Finds a property identity by normalized name.
const std::string & currentPath() const noexcept
Returns current workspace file path.
Maintains the editable app state for one workspace and persists it through IStorageManager.
const core::application::workspace::WorkspaceSessionState & state() const noexcept
const ContractList & contracts() const noexcept
Returns all contracts in the catalog.
Collects common core includes and aliases for precompiled-header builds.
std::string canonicalAliasValue(std::string value)
Canonicalizes an alias string for comparison.
std::string trimCopy(std::string value)
Trims leading and trailing whitespace from text.
QString normalizedText(const QString &value)
Normalizes text for case-insensitive UI comparisons.
core::domain::catalog::WorkspaceCatalog catalog
Catalog selection change request for transaction forms.
bool propertiesChanged
True when propertyIds contains user-selected properties.
bool contractChanged
True when contractId contains a user-selected contract.
std::string actorId
New actor id when actorChanged is true.
TransactionCatalogSelection current
Current transaction catalog selection.
std::string contractId
New contract id when contractChanged is true.
bool actorChanged
True when actorId contains a user-selected actor.
std::vector< std::string > propertyIds
New property ids when propertiesChanged is true.
Transaction catalog ids selected by a UI form or workspace query.
std::vector< std::string > propertyIds
Selected property ids.