ACF $AcfVersion:0$
TXmlFileSerializerComp.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QObject>
7#include <QtCore/QDir>
8
9// ACF includes
11#include <istd/CSystem.h>
14
15
16namespace ifile
17{
18
19
25template <class ReadArchive, class WriteArchive>
27{
28public:
30
31 I_BEGIN_COMPONENT(TXmlFileSerializerComp);
32 I_ASSIGN(m_autoCreateDirectoryAttrPtr, "AutoCreatePath", "Create directory/file path automatically if not exists", true, false);
33 I_ASSIGN(m_serializeAcfHeaderAttrPtr, "SerializeAcfHeader", "Enable or disable serializing of standard ACF header with version information", true, true);
34 I_ASSIGN(m_rootTagAttrPtr, "RootTag", "XML tag used as document root", true, "Acf");
35 I_END_COMPONENT;
36
37 // reimplemented (ifile::IFilePersistence)
40 const QString& filePath = QString(),
41 ibase::IProgressManager* progressManagerPtr = nullptr) const override;
43 const istd::IChangeable& data,
44 const QString& filePath = QString(),
45 ibase::IProgressManager* progressManagerPtr = nullptr) const override;
46
47protected:
48 class ReadArchiveEx: public ReadArchive
49 {
50 public:
51 typedef ReadArchive BaseClass;
52
53 ReadArchiveEx(const QString& filePath,
54 bool serializeHeader,
55 const iser::CArchiveTag& rootTag,
56 const TXmlFileSerializerComp* loggerPtr)
57 : ReadArchive(filePath, serializeHeader, rootTag),
58 m_loggerPtr(loggerPtr)
59 {
60 }
61
62 protected:
63 // reimplemented (istd::ILogger)
64 virtual bool IsLogConsumed(
66 const int* flagsPtr = nullptr) const override
67 {
69
70 return (m_loggerPtr != nullptr) && m_loggerPtr->IsLogConsumed(&slaveCategory, flagsPtr);
71 }
72
73 virtual bool SendLogMessage(
75 int id,
76 const QString& message,
77 const QString& messageSource,
78 int flags = 0) const override
79 {
80 if (m_loggerPtr != nullptr){
81 QString correctedMessage = message;
82 QString correctedMessageSource = messageSource;
83
84 BaseClass::DecorateMessage(category, id, flags, correctedMessage, correctedMessageSource);
85
86 return m_loggerPtr->SendLogMessage(istd::IInformationProvider::IC_INFO, id, correctedMessage, correctedMessageSource, flags);
87 }
88
89 return false;
90 }
91
92 private:
93 const TXmlFileSerializerComp* m_loggerPtr;
94 };
95
96 class WriteArchiveEx: public WriteArchive
97 {
98 public:
99 typedef WriteArchive BaseClass;
100
102 const QString& filePath,
103 const iser::IVersionInfo* infoPtr,
104 bool serializeHeader,
105 const iser::CArchiveTag& rootTag,
106 const TXmlFileSerializerComp* loggerPtr)
107 :WriteArchive(filePath, infoPtr, serializeHeader, rootTag),
108 m_loggerPtr(loggerPtr)
109 {
110 }
111
112 protected:
113 // reimplemented (istd::ILogger)
114 virtual bool IsLogConsumed(
116 const int* flagsPtr = nullptr) const override
117 {
119
120 return (m_loggerPtr != nullptr) && m_loggerPtr->IsLogConsumed(&slaveCategory, flagsPtr);
121 }
122
123 virtual bool SendLogMessage(
125 int id,
126 const QString& message,
127 const QString& messageSource,
128 int flags = 0) const override
129 {
130 if (m_loggerPtr != nullptr){
131 QString correctedMessage = message;
132 QString correctedMessageSource = messageSource;
133
134 BaseClass::DecorateMessage(category, id, flags, correctedMessage, correctedMessageSource);
135
136 return m_loggerPtr->SendLogMessage(category, id, correctedMessage, correctedMessageSource, flags);
137 }
138
139 return false;
140 }
141
142 private:
143 const TXmlFileSerializerComp* m_loggerPtr;
144 };
145
149 virtual void OnReadError(const ReadArchive& archive, const istd::IChangeable& data, const QString& filePath) const;
150
151protected:
152 I_ATTR(bool, m_autoCreateDirectoryAttrPtr);
153 I_ATTR(bool, m_serializeAcfHeaderAttrPtr);
154 I_ATTR(QByteArray, m_rootTagAttrPtr);
155};
156
157
158// public methods
159
160// reimplemented (ifile::IFilePersistence)
161
162template <class ReadArchive, class WriteArchive>
164 istd::IChangeable& data,
165 const QString& filePath,
166 ibase::IProgressManager* /*progressManagerPtr*/) const
167{
168 if (IsOperationSupported(&data, &filePath, QF_LOAD | QF_FILE, *m_beQuiteOnLoadAttrPtr)){
169 iser::CArchiveTag rootTag(*m_rootTagAttrPtr, "Root of document", iser::CArchiveTag::TT_GROUP);
170
171 ReadArchiveEx archive(filePath, *m_serializeAcfHeaderAttrPtr, rootTag, this);
172
173 Q_ASSERT(!archive.IsStoring());
174
178 iser::ISerializable* serializablePtr = dynamic_cast<iser::ISerializable*>(&data);
179 if (serializablePtr == nullptr){
180 serializablePtr = CompCastPtr<iser::ISerializable>(&data);
181 }
182
183 Q_ASSERT(serializablePtr != nullptr);
184
185 if (serializablePtr->Serialize(archive)){
186 return OS_OK;
187 }
188 else{
189 OnReadError(archive, data, filePath);
190 }
191 }
192
193 return OS_FAILED;
194}
195
196
197template <class ReadArchive, class WriteArchive>
199 const istd::IChangeable& data,
200 const QString& filePath,
201 ibase::IProgressManager* /*progressManagerPtr*/) const
202{
203 if (*m_autoCreateDirectoryAttrPtr){
204 QFileInfo fileInfo(filePath);
205
206 if (!istd::CSystem::EnsurePathExists(fileInfo.dir().absolutePath())){
207 SendErrorMessage(MI_FILE_NOT_EXIST, QObject::tr("Cannot create path to file"));
208 }
209 }
210
211 if (IsOperationSupported(&data, &filePath, QF_SAVE | QF_FILE, false)){
212 iser::CArchiveTag rootTag(*m_rootTagAttrPtr, "Root of document", iser::CArchiveTag::TT_GROUP);
213
214 WriteArchiveEx archive(filePath, GetVersionInfo(), *m_serializeAcfHeaderAttrPtr, rootTag, this);
215 Q_ASSERT(archive.IsStoring());
216
220 const iser::ISerializable* serializablePtr = dynamic_cast<const iser::ISerializable*>(&data);
221 if(serializablePtr == nullptr){
222 serializablePtr = CompCastPtr<iser::ISerializable>(&data);
223 }
224 Q_ASSERT(serializablePtr != nullptr);
225
226 if (!CheckMinimalVersion(*serializablePtr, archive.GetVersionInfo())){
227 SendWarningMessage(MI_UNSUPPORTED_VERSION, QObject::tr("Archive version is not supported, possible lost of data"));
228 }
229
230 if ((const_cast<iser::ISerializable*>(serializablePtr))->Serialize(archive)){
231 return OS_OK;
232 }
233 else{
234 SendInfoMessage(MI_CANNOT_SAVE, QObject::tr("Cannot serialize object to file: '%1'").arg(filePath));
235 }
236 }
237
238 return OS_FAILED;
239}
240
241
242// protected methods
243
244template <class ReadArchive, class WriteArchive>
246 const ReadArchive& /*archive*/,
247 const istd::IChangeable& /*data*/,
248 const QString& filePath) const
249{
250 SendWarningMessage(MI_CANNOT_LOAD, QString(QObject::tr("Cannot load object from file ")) + filePath);
251}
252
253
254} // namespace ifile
255
256
Consume information about progress of some process.
Base implementation of file serializer.
OperationState
Result of operation.
virtual bool IsLogConsumed(const istd::IInformationProvider::InformationCategory *, const int *flagsPtr=nullptr) const override
ReadArchiveEx(const QString &filePath, bool serializeHeader, const iser::CArchiveTag &rootTag, const TXmlFileSerializerComp *loggerPtr)
virtual bool SendLogMessage(istd::IInformationProvider::InformationCategory category, int id, const QString &message, const QString &messageSource, int flags=0) const override
WriteArchiveEx(const QString &filePath, const iser::IVersionInfo *infoPtr, bool serializeHeader, const iser::CArchiveTag &rootTag, const TXmlFileSerializerComp *loggerPtr)
virtual bool SendLogMessage(istd::IInformationProvider::InformationCategory category, int id, const QString &message, const QString &messageSource, int flags=0) const override
virtual bool IsLogConsumed(const istd::IInformationProvider::InformationCategory *, const int *flagsPtr=nullptr) const override
Template implementation of file serializer using loading and storing archive implementation.
virtual void OnReadError(const ReadArchive &archive, const istd::IChangeable &data, const QString &filePath) const
Called if read error is occurred.
virtual ifile::IFilePersistence::OperationState LoadFromFile(istd::IChangeable &data, const QString &filePath=QString(), ibase::IProgressManager *progressManagerPtr=nullptr) const override
This function loads data data from file filePath.
virtual ifile::IFilePersistence::OperationState SaveToFile(const istd::IChangeable &data, const QString &filePath=QString(), ibase::IProgressManager *progressManagerPtr=nullptr) const override
This function saves data data to file filePath.
virtual bool SendLogMessage(istd::IInformationProvider::InformationCategory category, int id, const QString &message, const QString &messageSource, int flags=0) const override
Send any message to log.
virtual void DecorateMessage(istd::IInformationProvider::InformationCategory category, int id, int flags, QString &message, QString &messageSource) const override
Decorate message parts before outputting.
virtual bool IsLogConsumed(const istd::IInformationProvider::InformationCategory *categoryPtr=NULL, const int *flagsPtr=NULL) const override
Check if any log message is consumed.
Process tag used to group data in archive stream.
Definition CArchiveTag.h:22
@ TT_GROUP
Normal tag used for grouping of tags or processed elements.
Definition CArchiveTag.h:37
Common class for all classes which objects can be archived or restored from archive.
virtual bool Serialize(IArchive &archive)=0
Load or store state of this object as a archive stream.
Provides access to version information.
static bool EnsurePathExists(const QString &filePath)
Ensure that the given path exists.
Common interface for data model objects, which can be changed.
Definition IChangeable.h:28
InformationCategory
Category of information.
@ IC_INFO
Normal information level.
Contains interfaces and implementations of file system related components.