0030286: Cover polygonal HLR algorithm by regression tests
[occt.git] / src / XmlMDF / XmlMDF.cxx
CommitLineData
b311480e 1// Created on: 2001-07-09
2// Created by: Julia DOROVSKIKH
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
83ae3591 17#include <Message_Messenger.hxx>
7fd59977 18#include <Storage_Schema.hxx>
42cf5bc1 19#include <TColStd_MapOfTransient.hxx>
ec357c5c 20#include <TDF_Attribute.hxx>
42cf5bc1 21#include <TDF_AttributeIterator.hxx>
22#include <TDF_ChildIterator.hxx>
23#include <TDF_Data.hxx>
24#include <TDF_Label.hxx>
25#include <TDF_TagSource.hxx>
26#include <TDF_Tool.hxx>
27#include <XmlMDF.hxx>
28#include <XmlMDF_ADriver.hxx>
29#include <XmlMDF_ADriverTable.hxx>
30#include <XmlMDF_DataMapIteratorOfTypeADriverMap.hxx>
31#include <XmlMDF_ReferenceDriver.hxx>
32#include <XmlMDF_TagSourceDriver.hxx>
33#include <XmlObjMgt_Document.hxx>
34#include <XmlObjMgt_DOMString.hxx>
35#include <XmlObjMgt_Persistent.hxx>
c2f5b821 36#include <XmlLDrivers.hxx>
030ba648 37#include <TDocStd_Owner.hxx>
38#include <TDocStd_Document.hxx>
60fddce4 39#include <Standard_GUID.hxx>
7fd59977 40
41IMPLEMENT_DOMSTRING (TagString, "tag")
42IMPLEMENT_DOMSTRING (LabelString, "label")
43#define DATATYPE_MIGRATION
44//#define DATATYPE_MIGRATION_DEB
45//=======================================================================
46//function : UnsuppTypesMap
47//purpose :
48//=======================================================================
49
50static TColStd_MapOfTransient& UnsuppTypesMap ()
51{
52 static TColStd_MapOfTransient anUnsuppTypes;
53 return anUnsuppTypes;
54}
55
56//=======================================================================
57//function : FromTo
58//purpose : Paste transient data into DOM_Element
59//=======================================================================
60void XmlMDF::FromTo (const Handle(TDF_Data)& theData,
61 XmlObjMgt_Element& theElement,
62 XmlObjMgt_SRelocationTable& theRelocTable,
63 const Handle(XmlMDF_ADriverTable)& theDrivers)
64{
65 UnsuppTypesMap().Clear();
66// Standard_Integer count =
67 WriteSubTree(theData->Root(), theElement, theRelocTable, theDrivers);
68 UnsuppTypesMap().Clear();
69}
70
71//=======================================================================
72//function : WriteSubTree
73//purpose :
74//=======================================================================
75Standard_Integer XmlMDF::WriteSubTree
76 (const TDF_Label& theLabel,
77 XmlObjMgt_Element& theElement,
78 XmlObjMgt_SRelocationTable& theRelocTable,
79 const Handle(XmlMDF_ADriverTable)& theDrivers)
80{
81 XmlObjMgt_Document aDoc = theElement.getOwnerDocument();
82
83 // create element "label"
84 XmlObjMgt_Element aLabElem = aDoc.createElement (::LabelString());
85
86 // Extraction of the driver subset.
87 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
88
89 // write attributes
90 Standard_Integer count = 0;
91 TDF_AttributeIterator itr1 (theLabel);
92 for ( ; itr1.More(); itr1.Next())
93 {
94 const Handle(TDF_Attribute)& tAtt = itr1.Value();
95 const Handle(Standard_Type)& aType = tAtt->DynamicType();
96 if (aDriverMap.IsBound (aType))
97 {
98 const Handle(XmlMDF_ADriver)& aDriver = aDriverMap.Find (aType);
99 count++;
100
101 // Add source to relocation table
102 Standard_Integer anId = theRelocTable.Add (tAtt);
103
104 // Create DOM data item
105 XmlObjMgt_Persistent pAtt;
c2f5b821 106 // In the document version 8 the attribute TPrsStd_AISPresentation
107 // was replaced by TDataXtd_Presentation. Therefore, for old versions
108 // we write old name of the attribute (TPrsStd_AISPresentation).
109 Standard_CString typeName = aDriver->TypeName().ToCString();
110 if (XmlLDrivers::StorageVersion() < 8 &&
111 strcmp(typeName, "TDataXtd_Presentation") == 0)
112 {
113 typeName = "TPrsStd_AISPresentation";
114 }
115 pAtt.CreateElement (aLabElem, typeName, anId);
7fd59977 116
117 // Paste
118 aDriver -> Paste (tAtt, pAtt, theRelocTable);
119 }
0797d9d3 120#ifdef OCCT_DEBUG
7fd59977 121 else if (!UnsuppTypesMap().Contains (aType))
122 {
123 cout << "attribute driver for type "<< aType -> Name()<< " not found"<< endl;
124 UnsuppTypesMap().Add (aType);
125 }
126#endif
127 }
128
129 // write sub-labels
130 TDF_ChildIterator itr2 (theLabel);
131 for ( ; itr2.More(); itr2.Next())
132 {
133 const TDF_Label& aChildLab = itr2.Value();
134 count += WriteSubTree(aChildLab, aLabElem, theRelocTable, theDrivers);
135 }
136
030ba648 137 if (count > 0 || TDocStd_Owner::GetDocument(theLabel.Data())->EmptyLabelsSavingMode())
7fd59977 138 {
139 theElement.appendChild(aLabElem);
140
141 // set attribute "tag"
142 aLabElem.setAttribute (::TagString(), theLabel.Tag());
143 }
144
145 return count;
146}
147
148//=======================================================================
149//function : FromTo
150//purpose : Paste data from DOM_Element into transient document
151//=======================================================================
152Standard_Boolean XmlMDF::FromTo (const XmlObjMgt_Element& theElement,
153 Handle(TDF_Data)& theData,
154 XmlObjMgt_RRelocationTable& theRelocTable,
155 const Handle(XmlMDF_ADriverTable)& theDrivers)
156{
157 TDF_Label aRootLab = theData->Root();
158 XmlMDF_MapOfDriver aDriverMap;
159 CreateDrvMap (theDrivers, aDriverMap);
160
161 Standard_Integer count = 0;
162
163 LDOM_Node theNode = theElement.getFirstChild();
164 XmlObjMgt_Element anElem = (const XmlObjMgt_Element&)theNode;
165 while ( !anElem.isNull() )
166 {
167 if ( anElem.getNodeName().equals (::LabelString()) )
168 {
169 Standard_Integer subcount =
170 ReadSubTree(anElem, aRootLab, theRelocTable, aDriverMap);
171 // check for error
172 if (subcount < 0)
173 return Standard_False;
174 count += subcount;
175 }
176 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
177 LDOM_Node theNode1 = anElem.getNextSibling();
178 anElem = (const XmlObjMgt_Element &) theNode1;
179 }
180
181 return Standard_True;
182}
183
184//=======================================================================
185//function : ReadSubTree
186//purpose :
187//=======================================================================
188Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement,
189 const TDF_Label& theLabel,
190 XmlObjMgt_RRelocationTable& theRelocTable,
191 const XmlMDF_MapOfDriver& theDriverMap)
192{
193 // Extraction of the driver subset.
194 Standard_Integer count = 0;
195
196 //XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theElement.getFirstChild();
197 LDOM_Node theNode = theElement.getFirstChild();
198 XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theNode;
199 while ( !anElem.isNull() )
200 {
201 if ( anElem.getNodeType() == LDOM_Node::ELEMENT_NODE )
202 {
203 if ( anElem.getNodeName().equals (::LabelString()) )
204 {
205 // read tag
206 Standard_Integer tag;
207 XmlObjMgt_DOMString aTag (anElem.getAttribute(::TagString()));
208 if ( !aTag.GetInteger (tag) ) {
209 TCollection_ExtendedString anErrorMessage =
210 TCollection_ExtendedString ("Wrong Tag value for OCAF Label: ")
211 + aTag;
83ae3591 212 theDriverMap.Find("TDF_TagSource") -> myMessageDriver->Send (anErrorMessage, Message_Fail);
7fd59977 213 return -1;
214 }
215 // create label
216 TDF_Label aLab = theLabel.FindChild(tag, Standard_True);
217
218 // read sub-tree
219 Standard_Integer subcount =
220 ReadSubTree(anElem, aLab, theRelocTable, theDriverMap);
221 // check for error
222 if (subcount == -1)
223 return -1;
224 count += subcount;
225 }
226 else
227 {
228 // read attribute
229 XmlObjMgt_DOMString aName = anElem.getNodeName();
230
231#ifdef DATATYPE_MIGRATION
232 TCollection_AsciiString newName;
233 if(Storage_Schema::CheckTypeMigration(aName, newName)) {
0797d9d3 234#ifdef OCCT_DEBUG
7fd59977 235 cout << "CheckTypeMigration:OldType = " <<aName.GetString() << " Len = "<<strlen(aName.GetString())<<endl;
236 cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl;
237#endif
238 aName = newName.ToCString();
239 }
240#endif
241
242 if (theDriverMap.IsBound (aName))
243 {
244 count++;
245 const Handle(XmlMDF_ADriver)& driver = theDriverMap.Find(aName);
246 XmlObjMgt_Persistent pAtt (anElem);
247 Standard_Integer anID = pAtt.Id ();
248 if (anID <= 0) { // check for ID validity
249 TCollection_ExtendedString anErrorMessage =
250 TCollection_ExtendedString("Wrong ID of OCAF attribute with type ")
251 + aName;
83ae3591 252 driver -> myMessageDriver->Send (anErrorMessage, Message_Fail);
7fd59977 253 return -1;
254 }
255 Handle(TDF_Attribute) tAtt;
256 Standard_Boolean isBound = theRelocTable.IsBound(anID);
257 if (isBound)
258 tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID));
259 else
260 tAtt = driver -> NewEmpty();
60fddce4 261
262 if (tAtt->Label().IsNull())
263 {
264 try
265 {
266 theLabel.AddAttribute (tAtt);
267 }
268 catch (const Standard_DomainError&)
269 {
270 // For attributes that can have arbitrary GUID (e.g. TDataStd_Integer), exception
271 // will be raised in valid case if attribute of that type with default GUID is already
272 // present on the same label; the reason is that actual GUID will be read later.
273 // To avoid this, set invalid (null) GUID to the newly added attribute (see #29669)
274 static const Standard_GUID fbidGuid;
275 tAtt->SetID (fbidGuid);
276 theLabel.AddAttribute (tAtt);
277 }
278 }
7fd59977 279 else
83ae3591 280 driver->myMessageDriver->Send
7fd59977 281 (TCollection_ExtendedString("XmlDriver warning: ") +
282 "attempt to attach attribute " +
83ae3591 283 aName + " to a second label", Message_Warning);
7fd59977 284
285 if (! driver -> Paste (pAtt, tAtt, theRelocTable))
286 {
287 // error converting persistent to transient
83ae3591 288 driver->myMessageDriver->Send
7fd59977 289 (TCollection_ExtendedString("XmlDriver warning: ") +
83ae3591 290 "failure reading attribute " + aName, Message_Warning);
7fd59977 291 }
292 else if (isBound == Standard_False)
293 theRelocTable.Bind (anID, tAtt);
294 }
0797d9d3 295#ifdef OCCT_DEBUG
7fd59977 296 else
297 {
298 const TCollection_AsciiString anAsciiName = aName;
299 cerr << "XmlDriver warning: "
300 << "label contains object of unknown type "<< anAsciiName<< endl;
301 }
302#endif
303 }
304 }
305 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
306 LDOM_Node theNode1 = anElem.getNextSibling();
307 anElem = (const XmlObjMgt_Element &) theNode1;
308 }
309
310 // AfterRetrieval
311 if (count > 0)
312 {
313 }
314
315 return count;
316}
317
318//=======================================================================
319//function : AddDrivers
320//purpose :
321//=======================================================================
322void XmlMDF::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
83ae3591 323 const Handle(Message_Messenger)& aMessageDriver)
7fd59977 324{
325 aDriverTable->AddDriver (new XmlMDF_TagSourceDriver(aMessageDriver));
326 aDriverTable->AddDriver (new XmlMDF_ReferenceDriver(aMessageDriver));
327}
328
329//=======================================================================
330//function : CreateDrvMap
331//purpose :
332//=======================================================================
333
334void XmlMDF::CreateDrvMap (const Handle(XmlMDF_ADriverTable)& theDrivers,
335 XmlMDF_MapOfDriver& theAsciiDriverMap)
336{
337 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
338 XmlMDF_DataMapIteratorOfTypeADriverMap anIter (aDriverMap);
339 while (anIter.More()) {
340 const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
341 const TCollection_AsciiString aTypeName = aDriver -> TypeName();
342 if (theAsciiDriverMap.IsBound (aTypeName) == Standard_False)
343 theAsciiDriverMap.Bind (aTypeName, aDriver);
344 else
83ae3591 345 aDriver -> myMessageDriver->Send
7fd59977 346 (TCollection_ExtendedString ("Warning: skipped driver name: \"")
83ae3591 347 + aTypeName + '\"', Message_Warning);
7fd59977 348 anIter.Next();
349 }
350}