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