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