0024023: Revamp the OCCT Handle -- ambiguity
[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
16#include <XmlMDF.ixx>
17#include <XmlMDF_ADriver.hxx>
18#include <XmlMDF_TagSourceDriver.hxx>
19#include <XmlMDF_ReferenceDriver.hxx>
20#include <XmlMDF_DataMapIteratorOfTypeADriverMap.hxx>
21
22#include <XmlObjMgt_Persistent.hxx>
23#include <XmlObjMgt_DOMString.hxx>
24#include <XmlObjMgt_Document.hxx>
25
26#include <TDF_TagSource.hxx>
27#include <TDF_Label.hxx>
28#include <TDF_Tool.hxx>
29#include <TDF_AttributeIterator.hxx>
30#include <TDF_ChildIterator.hxx>
31#include <TColStd_MapOfTransient.hxx>
32#include <Storage_Schema.hxx>
ec357c5c 33#include <TDF_Attribute.hxx>
7fd59977 34
35IMPLEMENT_DOMSTRING (TagString, "tag")
36IMPLEMENT_DOMSTRING (LabelString, "label")
37#define DATATYPE_MIGRATION
38//#define DATATYPE_MIGRATION_DEB
39//=======================================================================
40//function : UnsuppTypesMap
41//purpose :
42//=======================================================================
43
44static TColStd_MapOfTransient& UnsuppTypesMap ()
45{
46 static TColStd_MapOfTransient anUnsuppTypes;
47 return anUnsuppTypes;
48}
49
50//=======================================================================
51//function : FromTo
52//purpose : Paste transient data into DOM_Element
53//=======================================================================
54void XmlMDF::FromTo (const Handle(TDF_Data)& theData,
55 XmlObjMgt_Element& theElement,
56 XmlObjMgt_SRelocationTable& theRelocTable,
57 const Handle(XmlMDF_ADriverTable)& theDrivers)
58{
59 UnsuppTypesMap().Clear();
60// Standard_Integer count =
61 WriteSubTree(theData->Root(), theElement, theRelocTable, theDrivers);
62 UnsuppTypesMap().Clear();
63}
64
65//=======================================================================
66//function : WriteSubTree
67//purpose :
68//=======================================================================
69Standard_Integer XmlMDF::WriteSubTree
70 (const TDF_Label& theLabel,
71 XmlObjMgt_Element& theElement,
72 XmlObjMgt_SRelocationTable& theRelocTable,
73 const Handle(XmlMDF_ADriverTable)& theDrivers)
74{
75 XmlObjMgt_Document aDoc = theElement.getOwnerDocument();
76
77 // create element "label"
78 XmlObjMgt_Element aLabElem = aDoc.createElement (::LabelString());
79
80 // Extraction of the driver subset.
81 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
82
83 // write attributes
84 Standard_Integer count = 0;
85 TDF_AttributeIterator itr1 (theLabel);
86 for ( ; itr1.More(); itr1.Next())
87 {
88 const Handle(TDF_Attribute)& tAtt = itr1.Value();
89 const Handle(Standard_Type)& aType = tAtt->DynamicType();
90 if (aDriverMap.IsBound (aType))
91 {
92 const Handle(XmlMDF_ADriver)& aDriver = aDriverMap.Find (aType);
93 count++;
94
95 // Add source to relocation table
96 Standard_Integer anId = theRelocTable.Add (tAtt);
97
98 // Create DOM data item
99 XmlObjMgt_Persistent pAtt;
100 pAtt.CreateElement (aLabElem, aDriver->TypeName().ToCString(), anId);
101
102 // Paste
103 aDriver -> Paste (tAtt, pAtt, theRelocTable);
104 }
0797d9d3 105#ifdef OCCT_DEBUG
7fd59977 106 else if (!UnsuppTypesMap().Contains (aType))
107 {
108 cout << "attribute driver for type "<< aType -> Name()<< " not found"<< endl;
109 UnsuppTypesMap().Add (aType);
110 }
111#endif
112 }
113
114 // write sub-labels
115 TDF_ChildIterator itr2 (theLabel);
116 for ( ; itr2.More(); itr2.Next())
117 {
118 const TDF_Label& aChildLab = itr2.Value();
119 count += WriteSubTree(aChildLab, aLabElem, theRelocTable, theDrivers);
120 }
121
122 if (count > 0)
123 {
124 theElement.appendChild(aLabElem);
125
126 // set attribute "tag"
127 aLabElem.setAttribute (::TagString(), theLabel.Tag());
128 }
129
130 return count;
131}
132
133//=======================================================================
134//function : FromTo
135//purpose : Paste data from DOM_Element into transient document
136//=======================================================================
137Standard_Boolean XmlMDF::FromTo (const XmlObjMgt_Element& theElement,
138 Handle(TDF_Data)& theData,
139 XmlObjMgt_RRelocationTable& theRelocTable,
140 const Handle(XmlMDF_ADriverTable)& theDrivers)
141{
142 TDF_Label aRootLab = theData->Root();
143 XmlMDF_MapOfDriver aDriverMap;
144 CreateDrvMap (theDrivers, aDriverMap);
145
146 Standard_Integer count = 0;
147
148 LDOM_Node theNode = theElement.getFirstChild();
149 XmlObjMgt_Element anElem = (const XmlObjMgt_Element&)theNode;
150 while ( !anElem.isNull() )
151 {
152 if ( anElem.getNodeName().equals (::LabelString()) )
153 {
154 Standard_Integer subcount =
155 ReadSubTree(anElem, aRootLab, theRelocTable, aDriverMap);
156 // check for error
157 if (subcount < 0)
158 return Standard_False;
159 count += subcount;
160 }
161 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
162 LDOM_Node theNode1 = anElem.getNextSibling();
163 anElem = (const XmlObjMgt_Element &) theNode1;
164 }
165
166 return Standard_True;
167}
168
169//=======================================================================
170//function : ReadSubTree
171//purpose :
172//=======================================================================
173Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement,
174 const TDF_Label& theLabel,
175 XmlObjMgt_RRelocationTable& theRelocTable,
176 const XmlMDF_MapOfDriver& theDriverMap)
177{
178 // Extraction of the driver subset.
179 Standard_Integer count = 0;
180
181 //XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theElement.getFirstChild();
182 LDOM_Node theNode = theElement.getFirstChild();
183 XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theNode;
184 while ( !anElem.isNull() )
185 {
186 if ( anElem.getNodeType() == LDOM_Node::ELEMENT_NODE )
187 {
188 if ( anElem.getNodeName().equals (::LabelString()) )
189 {
190 // read tag
191 Standard_Integer tag;
192 XmlObjMgt_DOMString aTag (anElem.getAttribute(::TagString()));
193 if ( !aTag.GetInteger (tag) ) {
194 TCollection_ExtendedString anErrorMessage =
195 TCollection_ExtendedString ("Wrong Tag value for OCAF Label: ")
196 + aTag;
197 theDriverMap.Find("TDF_TagSource") -> WriteMessage (anErrorMessage);
198 return -1;
199 }
200 // create label
201 TDF_Label aLab = theLabel.FindChild(tag, Standard_True);
202
203 // read sub-tree
204 Standard_Integer subcount =
205 ReadSubTree(anElem, aLab, theRelocTable, theDriverMap);
206 // check for error
207 if (subcount == -1)
208 return -1;
209 count += subcount;
210 }
211 else
212 {
213 // read attribute
214 XmlObjMgt_DOMString aName = anElem.getNodeName();
215
216#ifdef DATATYPE_MIGRATION
217 TCollection_AsciiString newName;
218 if(Storage_Schema::CheckTypeMigration(aName, newName)) {
0797d9d3 219#ifdef OCCT_DEBUG
7fd59977 220 cout << "CheckTypeMigration:OldType = " <<aName.GetString() << " Len = "<<strlen(aName.GetString())<<endl;
221 cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl;
222#endif
223 aName = newName.ToCString();
224 }
225#endif
226
227 if (theDriverMap.IsBound (aName))
228 {
229 count++;
230 const Handle(XmlMDF_ADriver)& driver = theDriverMap.Find(aName);
231 XmlObjMgt_Persistent pAtt (anElem);
232 Standard_Integer anID = pAtt.Id ();
233 if (anID <= 0) { // check for ID validity
234 TCollection_ExtendedString anErrorMessage =
235 TCollection_ExtendedString("Wrong ID of OCAF attribute with type ")
236 + aName;
237 driver -> WriteMessage (anErrorMessage);
238 return -1;
239 }
240 Handle(TDF_Attribute) tAtt;
241 Standard_Boolean isBound = theRelocTable.IsBound(anID);
242 if (isBound)
243 tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID));
244 else
245 tAtt = driver -> NewEmpty();
246 if (tAtt->Label().IsNull())
247 theLabel.AddAttribute (tAtt);
248 else
249 driver->WriteMessage
250 (TCollection_ExtendedString("XmlDriver warning: ") +
251 "attempt to attach attribute " +
252 aName + " to a second label");
253
254 if (! driver -> Paste (pAtt, tAtt, theRelocTable))
255 {
256 // error converting persistent to transient
257 driver->WriteMessage
258 (TCollection_ExtendedString("XmlDriver warning: ") +
259 "failure reading attribute " + aName);
260 }
261 else if (isBound == Standard_False)
262 theRelocTable.Bind (anID, tAtt);
263 }
0797d9d3 264#ifdef OCCT_DEBUG
7fd59977 265 else
266 {
267 const TCollection_AsciiString anAsciiName = aName;
268 cerr << "XmlDriver warning: "
269 << "label contains object of unknown type "<< anAsciiName<< endl;
270 }
271#endif
272 }
273 }
274 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
275 LDOM_Node theNode1 = anElem.getNextSibling();
276 anElem = (const XmlObjMgt_Element &) theNode1;
277 }
278
279 // AfterRetrieval
280 if (count > 0)
281 {
282 }
283
284 return count;
285}
286
287//=======================================================================
288//function : AddDrivers
289//purpose :
290//=======================================================================
291void XmlMDF::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
292 const Handle(CDM_MessageDriver)& aMessageDriver)
293{
294 aDriverTable->AddDriver (new XmlMDF_TagSourceDriver(aMessageDriver));
295 aDriverTable->AddDriver (new XmlMDF_ReferenceDriver(aMessageDriver));
296}
297
298//=======================================================================
299//function : CreateDrvMap
300//purpose :
301//=======================================================================
302
303void XmlMDF::CreateDrvMap (const Handle(XmlMDF_ADriverTable)& theDrivers,
304 XmlMDF_MapOfDriver& theAsciiDriverMap)
305{
306 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
307 XmlMDF_DataMapIteratorOfTypeADriverMap anIter (aDriverMap);
308 while (anIter.More()) {
309 const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
310 const TCollection_AsciiString aTypeName = aDriver -> TypeName();
311 if (theAsciiDriverMap.IsBound (aTypeName) == Standard_False)
312 theAsciiDriverMap.Bind (aTypeName, aDriver);
313 else
314 aDriver -> WriteMessage
315 (TCollection_ExtendedString ("Warning: skipped driver name: \"")
316 + aTypeName + '\"');
317 anIter.Next();
318 }
319}