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