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