0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / XmlMDF / XmlMDF.cxx
1 // Created on: 2001-07-09
2 // Created by: Julia DOROVSKIKH
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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     }
104 #ifdef XMLMDF_DEB
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         }
263 #ifdef XMLMDATASTD_DEB
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 }