LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
DocumentElements.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
2//
3// SPDX-License-Identifier: MIT
4
5/************************************************************************
6 * @file DocumentElements.cpp
7 * @author Besancon Romaric
8 * @date Wed Oct 29 13:31:44 2003
9 * @author Gael de Chalendar
10 * @date Wed Apr 08 2015
11 ***********************************************************************/
12
13#include "DocumentElements.h"
14
16#include <fstream>
17#include <string>
18#include <deque>
19#include <algorithm>
20#include <boost/lexical_cast.hpp>
21
22#include <QtCore/QTextStream>
23
25#include "contentDocument.h"
26
27using namespace std;
28using namespace Lima;
29using namespace Lima::Common;
30using namespace Lima::Common::Misc;
31 // to handle dates (parsing)
32
33namespace Lima {
34namespace DocumentsReader {
35
36
38 const QString& elementName, unsigned int firstBytePos )
39: m_elementName(elementName), m_offset(firstBytePos)
40{
41 // transmit offset to the part.
42 addPart(QString(), m_offset);
43}
44
46 for( deque<ContentElementPart*>::iterator cIt = begin() ; cIt != end() ; cIt++ ) {
47 delete *cIt;
48 }
49}
50
52 return m_offset;
53}
54
55void AbstractStructuredDocumentElement::setOffset( unsigned long int offset)
56{
57 m_offset = offset;
58}
59
60
62 const unsigned int offset )
63{
64#ifdef DEBUG_LP
66 LDEBUG << "AbstractStructuredDocumentElement::addPart:" << text.left(50) << "(...)" << offset;
67#endif
68 push_back(new ContentElementPart(text,offset));
69}
70
72{
73#ifdef DEBUG_LP
75 LDEBUG << "AbstractStructuredDocumentElement::addToCurrentOffset:" << value.left(50) << "(...)";
76#endif
77 if( isDiscarding() )
78 {
79 addSpaces(value.length());
80 }
81 else
82 {
83// m_offset += value.size();
84 back()->addText(value);
85 }
86#ifdef DEBUG_LP
87 LDEBUG << "AbstractStructuredDocumentElement::addToCurrentOffset end offset = " << m_offset;
88 LDEBUG << "AbstractStructuredDocumentElement::addToCurrentOffset "<<this<<" text:" << back()->getText();
89#endif
90}
91
93#ifdef DEBUG_LP
95 LDEBUG << "AbstractStructuredDocumentElement::addSpaces(" << nbSpaces << ")";
96#endif
97 back()->addText(QString(nbSpaces, ' ') );
98#ifdef DEBUG_LP
99 LDEBUG << "AbstractStructuredDocumentElement::addSpaces text:" << back()->getText();
100#endif
101}
102
103//***********************************************************************
104// output
105//***********************************************************************
106
107std::ostream& operator << (std::ostream& out, const PropagatedProperties& properties)
108{
109 properties.print(out);
110 return out;
111}
112
113QTextStream& operator << (QTextStream& out, const PropagatedProperties& properties)
114{
115 properties.print(out);
116 return out;
117}
118
119QDebug& operator << (QDebug& out, const PropagatedProperties& properties)
120{
121 properties.print(out);
122 return out;
123}
124
125
126void PropagatedProperties::print(std::ostream& out) const
127{
128 for(auto iter=begin(); iter!=end(); iter++) {
129 out << iter->first.getId() << "," << storageTypeTag[iter->first.getStorageType()].toStdString()
130 << "," << cardinalityTypeTag[iter->first.getValueCardinality()].toStdString() << ": ";
131 for(auto str : iter->second) {
132 out << str << ", ";
133 }
134 out << endl;
135 }
136 return;
137}
138void PropagatedProperties::print(QTextStream& out) const
139{
140 for(auto iter=begin(); iter!=end(); iter++) {
141 out << QString::fromStdString(iter->first.getId()) << "," << storageTypeTag[iter->first.getStorageType()]
142 << "," << cardinalityTypeTag[iter->first.getValueCardinality()] << ": ";
143 for(auto str : iter->second) {
144 out << QString::fromStdString(str) << ", ";
145 }
146 out << "\n";
147 }
148 return;
149}
150void PropagatedProperties::print(QDebug& out) const
151{
152 for(auto iter=begin(); iter!=end(); iter++) {
153 out << QString::fromStdString(iter->first.getId()) << "," << storageTypeTag[iter->first.getStorageType()]
154 << "," << cardinalityTypeTag[iter->first.getValueCardinality()] << ": ";
155 for(auto str : iter->second) {
156 out << QString::fromStdString(str) << ", ";
157 }
158 out << "\n";
159 }
160 return;
161}
162//***********************************************************************
163
164
165DiscardableDocumentElement::DiscardableDocumentElement( const QString& elementName, unsigned int firstBytePos )
166 : AbstractStructuredDocumentElement(elementName, firstBytePos)
167{
168#ifdef DEBUG_LP
169 DRLOGINIT;
170 LDEBUG << "DiscardableDocumentElement::DiscardableDocumentElement(" << elementName << ")";
171#endif
172}
173
175 const QString& elementName,
176 unsigned int firstBytePos,
177 const PropagatedProperties& toBePropagated )
178 : AbstractStructuredDocumentElementWithProperties(elementName, firstBytePos, toBePropagated)
179{
180#ifdef DEBUG_LP
181 DRLOGINIT;
182 LDEBUG << "PresentationDocumentElement::PresentationDocumentElement(" << elementName << ")";
183#endif
184 m_toBePropagated = toBePropagated;
185}
186
188 const QString& elementName,
189 unsigned int firstBytePos,
190 const DocumentPropertyType& propType,
191 const PropagatedProperties& toBePropagated )
192 : AbstractStructuredDocumentElementWithProperties(elementName, firstBytePos, toBePropagated)
193{
194#ifdef DEBUG_LP
195 DRLOGINIT;
196 LDEBUG << "IgnoredDocumentElement::IgnoredDocumentElement(" << elementName << ")";
197#endif
198 m_propType = propType;
199}
200
202 const QString& elementName,
203 unsigned int firstBytePos,
204 const DocumentPropertyType& propType )
205 : AbstractStructuredDocumentElement(elementName, firstBytePos) {
206 m_propType = propType;
207}
208
209// Call when some character content is added
211 if( hasPropType() )
212 m_propertyValue.append(value);
213}
214
216 const QString& elementName,
217 unsigned int firstBytePos,
218 const PropagatedProperties& toBePropagated ) :
219 AbstractStructuredDocumentElement(elementName, firstBytePos), m_toBePropagated(toBePropagated)
220{
221}
222
226
228 const QString& elementName,
229 unsigned int firstBytePos,
230 const PropagatedProperties& toBePropagated ) :
231 AbstractStructuredDocumentElementWithProperties(elementName, firstBytePos, toBePropagated)
232{
233#ifdef DEBUG_LP
234 DRLOGINIT;
235 LDEBUG << "HierarchyDocumentElement::HierarchyDocumentElement(" << elementName << ")";
236#endif
237 setPropagatedValue(toBePropagated);
238}
239
241 const QString& elementName, unsigned int firstBytePos,
242 const DocumentPropertyType& propType,
243 const PropagatedProperties& toBePropagated )
244 : AbstractStructuredDocumentElementWithProperties(elementName, firstBytePos, toBePropagated)
245{
246 m_propType = propType;
247#ifdef DEBUG_LP
248 DRLOGINIT;
249 LDEBUG << "IndexingDocumentElement::IndexingDocumentElement(" << elementName << ")";
250#endif
251 setPropagatedValue(toBePropagated);
252}
253
256
257// // Call when some character content is added
258// void IndexingDocumentElement::addToCurrentOffset(const Lima::LimaString& value) {
259// if( hasPropType() )
260// m_propertyValue.append(value);
261// AbstractStructuredDocumentElement::addToCurrentOffset(value);
262// }
263
264// TODO: transfert this code in parent class ?
266 const PropagatedProperties& toBePropagated )
267{
268#ifdef DEBUG_LP
269 DRLOGINIT;
270 LDEBUG << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue" << getElementName() << this << "," << toBePropagated.size() << "properties";
271#endif
272
273 if(toBePropagated.size()) {
274#ifdef DEBUG_LP
275 LDEBUG << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue properties:" << toBePropagated;
276#endif
277 }
278
279 for(auto it = toBePropagated.begin() ; it != toBePropagated.end() ; it++ )
280 {
281 const DocumentPropertyType& property = (*it).first;
282 std::vector<std::string> v_data = (*it).second;
283 if (v_data.empty())
284 {
285#ifdef DEBUG_LP
286 LDEBUG << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue do not try to propagate empty value for" << property.getId();
287#endif
288 continue;
289 }
290 if(property.getValueCardinality() != CARDINALITY_MULTIPLE) {
291#ifdef DEBUG_LP
292 LDEBUG << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue add propagated value for later use, for" << property.getId() << v_data;
293#endif
294 m_toBePropagated.insert(std::make_pair(property,v_data));
295 }
296 else {
297#ifdef DEBUG_LP
298 LDEBUG << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue append propagated value for later use, for" << property.getId() << v_data;
299#endif
300 for(std::string data : v_data) {
301 auto ite_Beg = m_toBePropagated[property].begin(),
302 ite_End = m_toBePropagated[property].end();
303 if(std::find(ite_Beg,ite_End,data) == ite_End) {
304 m_toBePropagated[property].push_back(data);
305 }
306 }
307 }
308
309#ifdef DEBUG_LP
310 LTRACE << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue propagating" << property.getId() << v_data;
311#endif
312 for(std::string data : v_data) {
313 if (data.empty())
314 {
315#ifdef DEBUG_LP
316 LDEBUG << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue do not try to propagate empty value for" << property.getId();
317#endif
318 continue;
319 }
320#ifdef DEBUG_LP
321 LTRACE << "AbstractStructuredDocumentElementWithProperties::setPropagatedValue propagating" << property.getId() << data;
322#endif
323 switch (property.getStorageType()) {
324
325 case STORAGE_DATE: {
326 QDate dateValue;
327 QDate dateIgnore;
328 ContentStructuredDocument::parseDate(data,dateValue,dateIgnore);
329 GenericDocumentProperties::setDateValue(property.getId(), dateValue);
330 }
331 break;
333 if( property.getValueCardinality() == CARDINALITY_MULTIPLE)
334 GenericDocumentProperties::addStringValue(property.getId(), data);
335 else
336 GenericDocumentProperties::setStringValue(property.getId(), data);
337 break;
338 case STORAGE_INTEGER:
339 default:
340 GenericDocumentProperties::setIntValue(property.getId(), atoi(data.c_str()));
341 break;
342 }
343 }
344 }
345}
346
348 const DocumentPropertyType& propType, const string& value )
349{
350#ifdef DEBUG_LP
351 DRLOGINIT;
352 LDEBUG << "AbstractStructuredDocumentElementWithProperties::addProperty" << getElementName() << propType.getId() << value;
353#endif
354 // insert property if it's not present
355 if (m_toBePropagated.find(propType) == m_toBePropagated.end())
356 {
357 auto result = m_toBePropagated.insert(std::make_pair(propType, std::vector<std::string>(1,value) ));
358 if (!result.second)
359 {
360 DRLOGINIT;
361 LERROR << "AbstractStructuredDocumentElementWithProperties::addProperty FAILED to add" << getElementName() << propType.getId() << value;
362 }
363 }
364 else
365 {
366 // replace property value or append if cardinality is multi-valued
367 if (propType.getValueCardinality() == CARDINALITY_MULTIPLE) {
368#ifdef DEBUG_LP
369 LDEBUG << "AbstractStructuredDocumentElementWithProperties::addProperty append" << getElementName() << propType.getId() << "value" << m_toBePropagated[propType] << "with" << value;
370#endif
371 m_toBePropagated[propType].push_back( value );
372 }
373 else {
374#ifdef DEBUG_LP
375 LDEBUG << "AbstractStructuredDocumentElementWithProperties::addProperty set" << getElementName() << propType.getId() << "value" << m_toBePropagated[propType] << "by" << value;
376#endif
377 m_toBePropagated[propType] = std::vector<std::string>(1, value);
378 }
379 }
380}
381
387
388} // namespace DocumentsReader
389}
390
#define LTRACE
Definition LimaCommon.h:156
#define LDEBUG
Definition LimaCommon.h:157
#define LERROR
Definition LimaCommon.h:161
#define DRLOGINIT
void setStringValue(const std::string &propName, const std::string &val)
void addStringValue(const std::string &propName, const std::string &str)
void setDateValue(const std::string &propName, const QDate &val)
void setIntValue(const std::string &propName, const uint64_t &val)
void addProperty(const DocumentPropertyType &propType, const std::string &value)
AbstractStructuredDocumentElementWithProperties(const QString &elementName, unsigned int firstBytePos, const PropagatedProperties &toBePropagated)
void setPropagatedValue(const PropagatedProperties &toBePropagated)
void addPart(const Lima::LimaString &text, const unsigned int offset)
unsigned long int m_offset
current position during parsing
AbstractStructuredDocumentElement(const QString &elementName, unsigned int firstBytePos)
virtual void addToCurrentOffset(const Lima::LimaString &value)
Partie de texte (contenu dans un element) partageant le meme offset caractere.
static void parseDate(const std::string &dateStr, QDate &dateBegin, QDate &dateEnd)
DiscardableDocumentElement(const QString &elementName, unsigned int firstBytePos)
void addToCurrentOffset(const Lima::LimaString &value) override
DocumentPropertyElement(const QString &elementName, unsigned int firstBytePos, const DocumentPropertyType &propType)
const CardinalityType & getValueCardinality() const
HierarchyDocumentElement(const QString &elementName, unsigned int firstBytePos, const PropagatedProperties &toBePropagated)
IgnoredDocumentElement(const QString &elementName, unsigned int firstBytePos, const DocumentPropertyType &propType, const PropagatedProperties &toBePropagated)
IndexingDocumentElement(const QString &elementName, unsigned int firstBytePos, const DocumentPropertyType &propType, const PropagatedProperties &toBePropagated)
PresentationDocumentElement(const QString &elementName, unsigned int firstBytePos, const PropagatedProperties &toBePropagated)
virtual void print(std::ostream &) const
const std::string & getId() const
get the object id
std::ostream & operator<<(std::ostream &out, const PropagatedProperties &properties)
static const QString cardinalityTypeTag[MAX_STORAGE_TYPE]
static const QString storageTypeTag[MAX_STORAGE_TYPE]
NAUTITIA.
QString LimaString
Definition LimaString.h:33
STL namespace.