0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / XmlMDF / XmlMDF.cxx
CommitLineData
b311480e 1// Created on: 2001-07-09
2// Created by: Julia DOROVSKIKH
3// Copyright (c) 2001-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21#include <XmlMDF.ixx>
22#include <XmlMDF_ADriver.hxx>
23#include <XmlMDF_TagSourceDriver.hxx>
24#include <XmlMDF_ReferenceDriver.hxx>
25#include <XmlMDF_DataMapIteratorOfTypeADriverMap.hxx>
26
27#include <XmlObjMgt_Persistent.hxx>
28#include <XmlObjMgt_DOMString.hxx>
29#include <XmlObjMgt_Document.hxx>
30
31#include <TDF_TagSource.hxx>
32#include <TDF_Label.hxx>
33#include <TDF_Tool.hxx>
34#include <TDF_AttributeIterator.hxx>
35#include <TDF_ChildIterator.hxx>
36#include <TColStd_MapOfTransient.hxx>
37#include <Storage_Schema.hxx>
38
39IMPLEMENT_DOMSTRING (TagString, "tag")
40IMPLEMENT_DOMSTRING (LabelString, "label")
41#define DATATYPE_MIGRATION
42//#define DATATYPE_MIGRATION_DEB
43//=======================================================================
44//function : UnsuppTypesMap
45//purpose :
46//=======================================================================
47
48static TColStd_MapOfTransient& UnsuppTypesMap ()
49{
50 static TColStd_MapOfTransient anUnsuppTypes;
51 return anUnsuppTypes;
52}
53
54//=======================================================================
55//function : FromTo
56//purpose : Paste transient data into DOM_Element
57//=======================================================================
58void XmlMDF::FromTo (const Handle(TDF_Data)& theData,
59 XmlObjMgt_Element& theElement,
60 XmlObjMgt_SRelocationTable& theRelocTable,
61 const Handle(XmlMDF_ADriverTable)& theDrivers)
62{
63 UnsuppTypesMap().Clear();
64// Standard_Integer count =
65 WriteSubTree(theData->Root(), theElement, theRelocTable, theDrivers);
66 UnsuppTypesMap().Clear();
67}
68
69//=======================================================================
70//function : WriteSubTree
71//purpose :
72//=======================================================================
73Standard_Integer XmlMDF::WriteSubTree
74 (const TDF_Label& theLabel,
75 XmlObjMgt_Element& theElement,
76 XmlObjMgt_SRelocationTable& theRelocTable,
77 const Handle(XmlMDF_ADriverTable)& theDrivers)
78{
79 XmlObjMgt_Document aDoc = theElement.getOwnerDocument();
80
81 // create element "label"
82 XmlObjMgt_Element aLabElem = aDoc.createElement (::LabelString());
83
84 // Extraction of the driver subset.
85 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
86
87 // write attributes
88 Standard_Integer count = 0;
89 TDF_AttributeIterator itr1 (theLabel);
90 for ( ; itr1.More(); itr1.Next())
91 {
92 const Handle(TDF_Attribute)& tAtt = itr1.Value();
93 const Handle(Standard_Type)& aType = tAtt->DynamicType();
94 if (aDriverMap.IsBound (aType))
95 {
96 const Handle(XmlMDF_ADriver)& aDriver = aDriverMap.Find (aType);
97 count++;
98
99 // Add source to relocation table
100 Standard_Integer anId = theRelocTable.Add (tAtt);
101
102 // Create DOM data item
103 XmlObjMgt_Persistent pAtt;
104 pAtt.CreateElement (aLabElem, aDriver->TypeName().ToCString(), anId);
105
106 // Paste
107 aDriver -> Paste (tAtt, pAtt, theRelocTable);
108 }
109#ifdef DEB
110 else if (!UnsuppTypesMap().Contains (aType))
111 {
112 cout << "attribute driver for type "<< aType -> Name()<< " not found"<< endl;
113 UnsuppTypesMap().Add (aType);
114 }
115#endif
116 }
117
118 // write sub-labels
119 TDF_ChildIterator itr2 (theLabel);
120 for ( ; itr2.More(); itr2.Next())
121 {
122 const TDF_Label& aChildLab = itr2.Value();
123 count += WriteSubTree(aChildLab, aLabElem, theRelocTable, theDrivers);
124 }
125
126 if (count > 0)
127 {
128 theElement.appendChild(aLabElem);
129
130 // set attribute "tag"
131 aLabElem.setAttribute (::TagString(), theLabel.Tag());
132 }
133
134 return count;
135}
136
137//=======================================================================
138//function : FromTo
139//purpose : Paste data from DOM_Element into transient document
140//=======================================================================
141Standard_Boolean XmlMDF::FromTo (const XmlObjMgt_Element& theElement,
142 Handle(TDF_Data)& theData,
143 XmlObjMgt_RRelocationTable& theRelocTable,
144 const Handle(XmlMDF_ADriverTable)& theDrivers)
145{
146 TDF_Label aRootLab = theData->Root();
147 XmlMDF_MapOfDriver aDriverMap;
148 CreateDrvMap (theDrivers, aDriverMap);
149
150 Standard_Integer count = 0;
151
152 LDOM_Node theNode = theElement.getFirstChild();
153 XmlObjMgt_Element anElem = (const XmlObjMgt_Element&)theNode;
154 while ( !anElem.isNull() )
155 {
156 if ( anElem.getNodeName().equals (::LabelString()) )
157 {
158 Standard_Integer subcount =
159 ReadSubTree(anElem, aRootLab, theRelocTable, aDriverMap);
160 // check for error
161 if (subcount < 0)
162 return Standard_False;
163 count += subcount;
164 }
165 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
166 LDOM_Node theNode1 = anElem.getNextSibling();
167 anElem = (const XmlObjMgt_Element &) theNode1;
168 }
169
170 return Standard_True;
171}
172
173//=======================================================================
174//function : ReadSubTree
175//purpose :
176//=======================================================================
177Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement,
178 const TDF_Label& theLabel,
179 XmlObjMgt_RRelocationTable& theRelocTable,
180 const XmlMDF_MapOfDriver& theDriverMap)
181{
182 // Extraction of the driver subset.
183 Standard_Integer count = 0;
184
185 //XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theElement.getFirstChild();
186 LDOM_Node theNode = theElement.getFirstChild();
187 XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theNode;
188 while ( !anElem.isNull() )
189 {
190 if ( anElem.getNodeType() == LDOM_Node::ELEMENT_NODE )
191 {
192 if ( anElem.getNodeName().equals (::LabelString()) )
193 {
194 // read tag
195 Standard_Integer tag;
196 XmlObjMgt_DOMString aTag (anElem.getAttribute(::TagString()));
197 if ( !aTag.GetInteger (tag) ) {
198 TCollection_ExtendedString anErrorMessage =
199 TCollection_ExtendedString ("Wrong Tag value for OCAF Label: ")
200 + aTag;
201 theDriverMap.Find("TDF_TagSource") -> WriteMessage (anErrorMessage);
202 return -1;
203 }
204 // create label
205 TDF_Label aLab = theLabel.FindChild(tag, Standard_True);
206
207 // read sub-tree
208 Standard_Integer subcount =
209 ReadSubTree(anElem, aLab, theRelocTable, theDriverMap);
210 // check for error
211 if (subcount == -1)
212 return -1;
213 count += subcount;
214 }
215 else
216 {
217 // read attribute
218 XmlObjMgt_DOMString aName = anElem.getNodeName();
219
220#ifdef DATATYPE_MIGRATION
221 TCollection_AsciiString newName;
222 if(Storage_Schema::CheckTypeMigration(aName, newName)) {
223#ifdef DATATYPE_MIGRATION_DEB
224 cout << "CheckTypeMigration:OldType = " <<aName.GetString() << " Len = "<<strlen(aName.GetString())<<endl;
225 cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl;
226#endif
227 aName = newName.ToCString();
228 }
229#endif
230
231 if (theDriverMap.IsBound (aName))
232 {
233 count++;
234 const Handle(XmlMDF_ADriver)& driver = theDriverMap.Find(aName);
235 XmlObjMgt_Persistent pAtt (anElem);
236 Standard_Integer anID = pAtt.Id ();
237 if (anID <= 0) { // check for ID validity
238 TCollection_ExtendedString anErrorMessage =
239 TCollection_ExtendedString("Wrong ID of OCAF attribute with type ")
240 + aName;
241 driver -> WriteMessage (anErrorMessage);
242 return -1;
243 }
244 Handle(TDF_Attribute) tAtt;
245 Standard_Boolean isBound = theRelocTable.IsBound(anID);
246 if (isBound)
247 tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID));
248 else
249 tAtt = driver -> NewEmpty();
250 if (tAtt->Label().IsNull())
251 theLabel.AddAttribute (tAtt);
252 else
253 driver->WriteMessage
254 (TCollection_ExtendedString("XmlDriver warning: ") +
255 "attempt to attach attribute " +
256 aName + " to a second label");
257
258 if (! driver -> Paste (pAtt, tAtt, theRelocTable))
259 {
260 // error converting persistent to transient
261 driver->WriteMessage
262 (TCollection_ExtendedString("XmlDriver warning: ") +
263 "failure reading attribute " + aName);
264 }
265 else if (isBound == Standard_False)
266 theRelocTable.Bind (anID, tAtt);
267 }
268#ifdef DEB
269 else
270 {
271 const TCollection_AsciiString anAsciiName = aName;
272 cerr << "XmlDriver warning: "
273 << "label contains object of unknown type "<< anAsciiName<< endl;
274 }
275#endif
276 }
277 }
278 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
279 LDOM_Node theNode1 = anElem.getNextSibling();
280 anElem = (const XmlObjMgt_Element &) theNode1;
281 }
282
283 // AfterRetrieval
284 if (count > 0)
285 {
286 }
287
288 return count;
289}
290
291//=======================================================================
292//function : AddDrivers
293//purpose :
294//=======================================================================
295void XmlMDF::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
296 const Handle(CDM_MessageDriver)& aMessageDriver)
297{
298 aDriverTable->AddDriver (new XmlMDF_TagSourceDriver(aMessageDriver));
299 aDriverTable->AddDriver (new XmlMDF_ReferenceDriver(aMessageDriver));
300}
301
302//=======================================================================
303//function : CreateDrvMap
304//purpose :
305//=======================================================================
306
307void XmlMDF::CreateDrvMap (const Handle(XmlMDF_ADriverTable)& theDrivers,
308 XmlMDF_MapOfDriver& theAsciiDriverMap)
309{
310 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
311 XmlMDF_DataMapIteratorOfTypeADriverMap anIter (aDriverMap);
312 while (anIter.More()) {
313 const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
314 const TCollection_AsciiString aTypeName = aDriver -> TypeName();
315 if (theAsciiDriverMap.IsBound (aTypeName) == Standard_False)
316 theAsciiDriverMap.Bind (aTypeName, aDriver);
317 else
318 aDriver -> WriteMessage
319 (TCollection_ExtendedString ("Warning: skipped driver name: \"")
320 + aTypeName + '\"');
321 anIter.Next();
322 }
323}