Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Commit c440591

Browse files
committed
logical: implement technical space properties transform
1 parent 50cb362 commit c440591

2 files changed

Lines changed: 194 additions & 1 deletion

File tree

projects/dogen.logical/include/dogen.logical/types/transforms/technical_space_properties_transform.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,52 @@
2525
#pragma once
2626
#endif
2727

28+
#include <list>
29+
#include <boost/optional/optional.hpp>
30+
#include "dogen.identification/types/entities/logical_name_tree.hpp"
2831
#include "dogen.logical/types/entities/model.hpp"
2932
#include "dogen.logical/types/transforms/context.hpp"
33+
#include "dogen.logical/types/entities/element.hpp"
34+
#include "dogen.logical/types/entities/attribute.hpp"
35+
#include "dogen.logical/types/features/technical_space_properties.hpp"
36+
#include "dogen.logical/types/entities/structural/technical_space_properties.hpp"
3037

3138
namespace dogen::logical::transforms {
3239

3340
/**
3441
* @brief Reads technical space specific properties.
3542
*/
3643
class technical_space_properties_transform final {
44+
private:
45+
static boost::optional<entities::structural::technical_space_properties>
46+
obtain_properties(
47+
const features::technical_space_properties::feature_group& fg,
48+
entities::element& e);
49+
50+
static std::unordered_map<identification::entities::logical_id,
51+
entities::structural::technical_space_properties>
52+
obtain_properties(const variability::entities::feature_model& fm,
53+
entities::model& m);
54+
55+
private:
56+
static void
57+
walk_name_tree(const identification::entities::logical_name_tree& nt,
58+
const bool is_top_level, const std::unordered_map<
59+
identification::entities::logical_id,
60+
entities::structural::technical_space_properties>& src_tsps,
61+
entities::structural::technical_space_properties& dest_tsp);
62+
63+
static entities::structural::technical_space_properties
64+
compute_properties(
65+
const std::unordered_map<identification::entities::logical_id,
66+
entities::structural::technical_space_properties>& src_tsps,
67+
const std::list<logical::entities::attribute>& attrs);
68+
69+
static void populate_properties(
70+
const std::unordered_map<identification::entities::logical_id,
71+
entities::structural::technical_space_properties>& src_tsps,
72+
entities::model& m);
73+
3774
public:
3875
static void apply(const context& ctx, entities::model& m);
3976
};

projects/dogen.logical/src/types/transforms/technical_space_properties_transform.cpp

Lines changed: 157 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@
2020
*/
2121
#include <boost/throw_exception.hpp>
2222
#include "dogen.utility/types/log/logger.hpp"
23+
#include "dogen.utility/types/io/unordered_map_io.hpp"
2324
#include "dogen.tracing/types/scoped_tracer.hpp"
2425
#include "dogen.variability/types/helpers/configuration_selector.hpp"
26+
#include "dogen.identification/io/entities/logical_id_io.hpp"
2527
#include "dogen.logical/io/entities/model_io.hpp"
28+
#include "dogen.logical/types/entities/structural/object.hpp"
29+
#include "dogen.logical/types/entities/structural/primitive.hpp"
30+
#include "dogen.logical/io/entities/structural/technical_space_properties_io.hpp"
2631
#include "dogen.logical/types/entities/structural/technical_space_properties.hpp"
27-
#include "dogen.logical/types/features/technical_space_properties.hpp"
32+
#include "dogen.logical/types/transforms/transformation_error.hpp"
33+
#include "dogen.logical/types/entities/elements_traversal.hpp"
2834
#include "dogen.logical/types/transforms/technical_space_properties_transform.hpp"
2935

3036
namespace {
@@ -41,11 +47,161 @@ const std::string duplicate_id("Duplicate ID: ");
4147

4248
namespace dogen::logical::transforms {
4349

50+
boost::optional<entities::structural::technical_space_properties>
51+
technical_space_properties_transform::obtain_properties(
52+
const features::technical_space_properties::feature_group& fg,
53+
entities::element& e) {
54+
55+
const auto id(e.name().id());
56+
BOOST_LOG_SEV(lg, debug) << "Procesing element: " << id;
57+
58+
/*
59+
* If we do not have any configuration related to streaming
60+
* operations, there is nothing to do.
61+
*/
62+
const auto& cfg(*e.configuration());
63+
const variability::helpers::configuration_selector s(cfg);
64+
if (!s.has_configuration_point(fg.requires_manual_default_constructor) &&
65+
!s.has_configuration_point(fg.requires_manual_move_constructor) &&
66+
!s.has_configuration_point(fg.requires_stream_manipulators)) {
67+
BOOST_LOG_SEV(lg, debug) << "No properties found.";
68+
return boost::optional<
69+
entities::structural::technical_space_properties>();
70+
}
71+
72+
/*
73+
* Create the properties and slot them into the results container.
74+
*/
75+
entities::structural::technical_space_properties r;
76+
const auto scfg(features::technical_space_properties::
77+
make_static_configuration(fg, cfg));
78+
r.requires_manual_default_constructor(
79+
scfg.requires_manual_default_constructor);
80+
r.requires_manual_move_constructor(
81+
scfg.requires_manual_move_constructor);
82+
r.requires_stream_manipulators(scfg.requires_stream_manipulators);
83+
84+
return r;
85+
}
86+
87+
std::unordered_map<identification::entities::logical_id,
88+
entities::structural::technical_space_properties>
89+
technical_space_properties_transform::obtain_properties(
90+
const variability::entities::feature_model& fm,
91+
entities::model& m) {
92+
93+
const auto fg(features::technical_space_properties::make_feature_group(fm));
94+
std::unordered_map<identification::entities::logical_id,
95+
entities::structural::technical_space_properties> r;
96+
97+
entities::elements_traversal(m,
98+
[&](entities::element& e) {
99+
const auto o(obtain_properties(fg, e));
100+
if (!o)
101+
return;
102+
103+
const auto id(e.name().id());
104+
const auto pair(std::make_pair(id, *o));
105+
const auto inserted(r.insert(pair).second);
106+
if (!inserted) {
107+
BOOST_LOG_SEV(lg, error) << duplicate_id << id;
108+
BOOST_THROW_EXCEPTION(
109+
transformation_error(duplicate_id + id.value()));
110+
}
111+
});
112+
BOOST_LOG_SEV(lg, debug) << "Streaming properties: " << r;
113+
return r;
114+
}
115+
116+
void technical_space_properties_transform::
117+
walk_name_tree(const identification::entities::logical_name_tree& nt,
118+
const bool is_top_level, const std::unordered_map<
119+
identification::entities::logical_id,
120+
entities::structural::technical_space_properties>& src_tsps,
121+
entities::structural::technical_space_properties& dest_tsp) {
122+
123+
for (const auto& c : nt.children())
124+
walk_name_tree(c, false/*is_top_level*/, src_tsps, dest_tsp);
125+
126+
if (is_top_level && nt.is_current_simple_type())
127+
dest_tsp.requires_manual_default_constructor(true);
128+
129+
const auto i(src_tsps.find(nt.current().id()));
130+
if (i == src_tsps.end())
131+
return;
132+
133+
const auto src_tsp(i->second);
134+
if (src_tsp.requires_stream_manipulators())
135+
dest_tsp.requires_stream_manipulators(true);
136+
137+
if (!is_top_level)
138+
return;
139+
140+
if (src_tsp.requires_manual_default_constructor())
141+
dest_tsp.requires_manual_default_constructor(true);
142+
143+
if (src_tsp.requires_manual_move_constructor())
144+
dest_tsp.requires_manual_move_constructor(true);
145+
}
146+
147+
entities::structural::technical_space_properties
148+
technical_space_properties_transform::compute_properties(
149+
const std::unordered_map<identification::entities::logical_id,
150+
entities::structural::technical_space_properties>& src_tsps,
151+
const std::list<logical::entities::attribute>& attrs) {
152+
153+
entities::structural::technical_space_properties r;
154+
for (const auto& attr : attrs) {
155+
const auto& nt(attr.parsed_type());
156+
walk_name_tree(nt, true/*is_top_level*/, src_tsps, r);
157+
}
158+
return r;
159+
}
160+
161+
void technical_space_properties_transform::populate_properties(
162+
const std::unordered_map<identification::entities::logical_id,
163+
entities::structural::technical_space_properties>& src_tsps,
164+
entities::model& m) {
165+
166+
using identification::entities::model_type;
167+
auto& se(m.structural_elements());
168+
for (auto& pair : se.objects()) {
169+
/*
170+
* We only need to generate the properties for elements of the
171+
* target model.
172+
*/
173+
auto& e(*pair.second);
174+
if (e.provenance().model_type() != model_type::target)
175+
continue;
176+
177+
const auto& attrs(e.local_attributes());
178+
e.technical_space_properties(compute_properties(src_tsps, attrs));
179+
}
180+
181+
for (auto& pair : se.primitives()) {
182+
/*
183+
* We only need to generate the properties for elements of the
184+
* target model.
185+
*/
186+
auto& p(*pair.second);
187+
if (p.provenance().model_type() != model_type::target)
188+
continue;
189+
190+
using logical::entities::attribute;
191+
const std::list<attribute> attrs{ p.value_attribute() };
192+
p.technical_space_properties(compute_properties(src_tsps, attrs));
193+
}
194+
}
195+
44196
void technical_space_properties_transform::
45197
apply(const context &ctx, entities::model &m) {
46198
tracing::scoped_transform_tracer stp(lg, "technical space properties",
47199
transform_id, m.name().qualified().dot(), *ctx.tracer(), m);
48200

201+
const auto& fm(*ctx.feature_model());
202+
const auto src_tsps(obtain_properties(fm, m));
203+
populate_properties(src_tsps, m);
204+
49205
stp.end_transform(m);
50206
}
51207

0 commit comments

Comments
 (0)