BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
jsonitemcontainerconverter.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/model/mvvm/serialization/jsonitemcontainerconverter.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include "mvvm/model/sessionitem.h"
19 #include "mvvm/model/tagrow.h"
24 #include <QJsonArray>
25 #include <QJsonObject>
26 
27 using namespace ModelView;
28 
30  std::unique_ptr<JsonTagInfoConverterInterface> m_taginfo_converter;
32 
34  : m_converter_callbacks(std::move(callbacks))
35  {
36  m_taginfo_converter = std::make_unique<JsonTagInfoConverter>();
37  }
38 
39  QJsonObject create_json(const SessionItem& item)
40  {
42  : QJsonObject();
43  }
44 
45  std::unique_ptr<SessionItem> create_item(const QJsonObject& json)
46  {
48  : std::unique_ptr<SessionItem>();
49  }
50 
51  void update_item(const QJsonObject& json, SessionItem* item)
52  {
55  }
56 
57  //! Update container from json content. Number of existing container items should match size
58  //! of json array.
59  void update_items(const QJsonObject& json, SessionItemContainer& container)
60  {
61  auto array = json[JsonItemFormatAssistant::itemsKey].toArray();
62  if (array.size() != container.itemCount())
63  throw std::runtime_error("Error in JsonItemContainerConverter: size is different");
64  int index{0};
65  for (const auto obj : array)
66  update_item(obj.toObject(), container.itemAt(index++));
67  }
68 
69  void create_items(const QJsonObject& json, SessionItemContainer& container)
70  {
71  for (const auto obj : json[JsonItemFormatAssistant::itemsKey].toArray()) {
72  if (auto item = create_item(obj.toObject()); item)
73  container.insertItem(item.release(), container.itemCount());
74  }
75  }
76 
77  //! Populates container with content reconstructed from JSON object. Container must be empty.
78 
79  void populate_container(const QJsonObject& json, SessionItemContainer& container)
80  {
81  if (!container.empty())
82  throw std::runtime_error(
83  "Error in JsonItemContainerConverter: container is not empty.");
84 
85  create_items(json, container);
86  }
87 
88  //! Update container with content reconstructed from JSON object.
89  //! It is assumed, that container has some items already created.
90 
91  void update_container(const QJsonObject& json, SessionItemContainer& container)
92  {
93  TagInfo tagInfo =
94  m_taginfo_converter->from_json(json[JsonItemFormatAssistant::tagInfoKey].toObject());
95 
96  if (Compatibility::IsCompatibleSinglePropertyTag(container, tagInfo))
97  update_items(json, container);
98 
99  else if (Compatibility::IsCompatibleGroupTag(container, tagInfo))
100  update_items(json, container);
101 
102  else if (Compatibility::IsCompatibleUniversalTag(container, tagInfo))
103  create_items(json, container);
104 
105  else
106  throw std::runtime_error("Error in JsonItemContainerConverter: can't convert json");
107  }
108 };
109 
111  : p_impl(std::make_unique<JsonItemContainerConverterImpl>(std::move(callbacks)))
112 {
113 }
114 
116 
118 {
119  QJsonObject result;
121  p_impl->m_taginfo_converter->to_json(container.tagInfo());
122 
123  QJsonArray itemArray;
124  for (auto item : container)
125  itemArray.append(p_impl->create_json(*item));
126  result[JsonItemFormatAssistant::itemsKey] = itemArray;
127 
128  return result;
129 }
130 
131 //! Reconstructs SessionItemContainer from the content of JSON object. Can work in two modes:
132 //! + If SessionItemContainer is empty, the content will be reconstructed from JSON
133 //! + If SessionItemContainer contains some items already, they will be populated from JSON.
134 //! Second mode is used when loading project from disk to allow back compatibility.
135 
136 void JsonItemContainerConverter::from_json(const QJsonObject& json, SessionItemContainer& container)
137 {
138  static JsonItemFormatAssistant assistant;
139 
140  if (!assistant.isSessionItemContainer(json))
141  throw std::runtime_error("Error in JsonItemContainerConverter: given JSON can't represent "
142  "SessionItemContainer.");
143 
144  TagInfo tagInfo = p_impl->m_taginfo_converter->from_json(
145  json[JsonItemFormatAssistant::tagInfoKey].toObject());
146 
147  if (tagInfo.name() != container.tagInfo().name())
148  throw std::runtime_error("Error in JsonItemContainerConverter: attempt to update "
149  "container from JSON representing another container.");
150 
151  if (container.empty())
152  p_impl->populate_container(json, container);
153  else
154  p_impl->update_container(json, container);
155 }
void from_json(const QJsonObject &json, SessionItemContainer &container)
Reconstructs SessionItemContainer from the content of JSON object.
std::unique_ptr< JsonItemContainerConverterImpl > p_impl
QJsonObject to_json(const SessionItemContainer &container)
JsonItemContainerConverter(ConverterCallbacks callbacks)
Utility class to determine, whether given JSON object can represent various parts of SessionModel.
bool isSessionItemContainer(const QJsonObject &json) const
Returns true if given json object represents SessionItemContainer.
Holds collection of SessionItem objects related to the same tag.
bool insertItem(SessionItem *item, int index)
Inserts item in a vector of children at given index, returns true in the case of success.
int itemCount() const
Returns number of items in given tag.
SessionItem * itemAt(int index) const
Returns item at given index. Returns nullptr if index is invalid.
The main object representing an editable/displayable/serializable entity.
Definition: sessionitem.h:38
Holds info about single tag for SessionItem.
Definition: taginfo.h:28
std::string name() const
Definition: taginfo.cpp:45
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
MVVM_MODEL_EXPORT bool IsCompatibleSinglePropertyTag(const SessionItemContainer &container, const TagInfo &taginfo)
Returns true if given TagInfo is a single property tag which is compatible with given container.
MVVM_MODEL_EXPORT bool IsCompatibleUniversalTag(const SessionItemContainer &container, const TagInfo &taginfo)
Returns true if given TagInfo is compatible with given container.
MVVM_MODEL_EXPORT bool IsCompatibleGroupTag(const SessionItemContainer &container, const TagInfo &taginfo)
Returns true if given TagInfo is a tag from GroupItem which is compatible with given container.
materialitems.h Collection of materials to populate MaterialModel.
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
void update_items(const QJsonObject &json, SessionItemContainer &container)
Update container from json content.
void populate_container(const QJsonObject &json, SessionItemContainer &container)
Populates container with content reconstructed from JSON object. Container must be empty.
void create_items(const QJsonObject &json, SessionItemContainer &container)
std::unique_ptr< SessionItem > create_item(const QJsonObject &json)
void update_container(const QJsonObject &json, SessionItemContainer &container)
Update container with content reconstructed from JSON object.
Provides necessary callbacks to convert SessionItem to JSON and back.
update_item_t m_update_item
creates new SessionItem from JSON object
create_item_t m_create_item
creates JSON object from session item
Defines class CLASS?