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