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