0030169: Application Framework - Document format version management improvement
[occt.git] / src / XmlMNaming / XmlMNaming_NamingDriver.cxx
1 // Created on: 2001-08-31
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 <Message_Messenger.hxx>
18 #include <Standard_Type.hxx>
19 #include <TDF_Attribute.hxx>
20 #include <TDF_Tool.hxx>
21 #include <TNaming_Iterator.hxx>
22 #include <TNaming_ListIteratorOfListOfNamedShape.hxx>
23 #include <TNaming_Name.hxx>
24 #include <TNaming_NamedShape.hxx>
25 #include <TNaming_Naming.hxx>
26 #include <XmlMNaming_NamingDriver.hxx>
27 #include <XmlObjMgt.hxx>
28 #include <XmlObjMgt_Persistent.hxx>
29
30 IMPLEMENT_STANDARD_RTTIEXT(XmlMNaming_NamingDriver,XmlMDF_ADriver)
31
32 //=======================================================================
33 static TopAbs_ShapeEnum ShapeEnumFromString (const XmlObjMgt_DOMString&);
34 static TNaming_NameType NameTypeFromString (const XmlObjMgt_DOMString&);
35
36 static const XmlObjMgt_DOMString& ShapeEnumToString (const TopAbs_ShapeEnum);
37 static const XmlObjMgt_DOMString& NameTypeToString (const TNaming_NameType);
38
39 IMPLEMENT_DOMSTRING (IndexString,               "index")
40 IMPLEMENT_DOMSTRING (StopNamedShapeString,      "stopNS")
41 IMPLEMENT_DOMSTRING (TypeString,                "nametype")
42 IMPLEMENT_DOMSTRING (ShapeTypeString,           "shapetype")
43 IMPLEMENT_DOMSTRING (ArgumentsString,           "arguments")
44 IMPLEMENT_DOMSTRING (ContextLabelString,        "contextlabel")
45 IMPLEMENT_DOMSTRING (OrientString,              "orientation")
46
47 IMPLEMENT_DOMSTRING (NTUnknownString,           "unknown")
48 IMPLEMENT_DOMSTRING (NTIdentityString,          "identity")
49 IMPLEMENT_DOMSTRING (NTModifUntilString,        "modifuntil")
50 IMPLEMENT_DOMSTRING (NTGenerationString,        "generation")
51 IMPLEMENT_DOMSTRING (NTIntersectionString,      "intersection")
52 IMPLEMENT_DOMSTRING (NTUnionString,             "union")
53 IMPLEMENT_DOMSTRING (NTSubtractionString,       "subtraction")
54 IMPLEMENT_DOMSTRING (NTConstShapeString,        "constshape")
55 IMPLEMENT_DOMSTRING (NTFilterByNeighString,     "filterbyneigh")
56 IMPLEMENT_DOMSTRING (NTOrientationString,       "orientation")
57 IMPLEMENT_DOMSTRING (NTWireInString,            "wirein")
58 IMPLEMENT_DOMSTRING (NTShellInString,            "shellin")
59
60 IMPLEMENT_DOMSTRING (ShCompoundString,          "compound")
61 IMPLEMENT_DOMSTRING (ShCompsolidString,         "compsolid")
62 IMPLEMENT_DOMSTRING (ShSolidString,             "solid")
63 IMPLEMENT_DOMSTRING (ShShellString,             "shell")
64 IMPLEMENT_DOMSTRING (ShFaceString,              "face")
65 IMPLEMENT_DOMSTRING (ShWireString,              "wire")
66 IMPLEMENT_DOMSTRING (ShEdgeString,              "edge")
67 IMPLEMENT_DOMSTRING (ShVertexString,            "vertex")
68 IMPLEMENT_DOMSTRING (ShShapeString,             "shape")
69
70 //=======================================================================
71 //function : XmlMNaming_NamingDriver
72 //purpose  : Constructor
73 //=======================================================================
74 XmlMNaming_NamingDriver::XmlMNaming_NamingDriver
75                         (const Handle(Message_Messenger)& theMsgDriver)
76       : XmlMDF_ADriver (theMsgDriver, NULL)
77 {}
78
79 //=======================================================================
80 //function : NewEmpty
81 //purpose  : 
82 //=======================================================================
83 Handle(TDF_Attribute) XmlMNaming_NamingDriver::NewEmpty() const
84 {
85   return (new TNaming_Naming());
86 }
87
88 //=======================================================================
89 //function : Paste
90 //purpose  : persistent -> transient (retrieve)
91 //=======================================================================
92 Standard_Boolean XmlMNaming_NamingDriver::Paste
93                         (const XmlObjMgt_Persistent&  theSource,
94                          const Handle(TDF_Attribute)& theTarget,
95                          XmlObjMgt_RRelocationTable&  theRelocTable) const
96 {
97   const XmlObjMgt_Element& anElem = theSource;
98   Handle(TNaming_Naming) aNg = Handle(TNaming_Naming)::DownCast(theTarget);  
99
100   TNaming_Name& aNgName = aNg->ChangeName();
101
102   // type and shape type
103   aNgName.Type     (NameTypeFromString (anElem.getAttribute(::TypeString())));
104   aNgName.ShapeType(ShapeEnumFromString(anElem.getAttribute(::ShapeTypeString())));
105
106   Standard_Integer aNb;
107   Handle(TNaming_NamedShape) NS;
108   TCollection_ExtendedString aMsgString;
109
110   XmlObjMgt_DOMString aDOMStr = anElem.getAttribute(::ArgumentsString());
111   if (aDOMStr != NULL)
112   {
113     Standard_CString aGs = Standard_CString(aDOMStr.GetString());
114
115     // first argument
116     if (!XmlObjMgt::GetInteger(aGs, aNb))
117     {
118       aMsgString = TCollection_ExtendedString
119         ("XmlMNaming_NamingDriver: Cannot retrieve reference "
120          "on first Argument from \"") + aDOMStr + "\"";
121       myMessageDriver->Send (aMsgString, Message_Fail);
122       return Standard_False;
123     }
124     while (aNb > 0)
125     {
126       if (theRelocTable.IsBound(aNb))
127         NS = Handle(TNaming_NamedShape)::DownCast(theRelocTable.Find(aNb));
128       else
129       {
130         NS = new TNaming_NamedShape;
131         theRelocTable.Bind(aNb, NS);
132       }
133       aNgName.Append(NS);
134
135       // next argument
136       if (!XmlObjMgt::GetInteger(aGs, aNb)) aNb = 0;
137     }
138   }
139
140   // stop named shape
141   aDOMStr = anElem.getAttribute(::StopNamedShapeString());
142   if (aDOMStr != NULL)
143   {
144     if (!aDOMStr.GetInteger(aNb))
145     {
146       aMsgString = TCollection_ExtendedString
147         ("XmlMNaming_NamingDriver: Cannot retrieve reference "
148          "on StopNamedShape from \"") + aDOMStr + "\"";
149       myMessageDriver->Send (aMsgString, Message_Fail);
150       return Standard_False;
151     }
152     if (aNb > 0)
153     {
154       if (theRelocTable.IsBound(aNb))
155         NS = Handle(TNaming_NamedShape)::DownCast(theRelocTable.Find(aNb));
156       else
157       {
158         NS = new TNaming_NamedShape;
159         theRelocTable.Bind(aNb, NS);
160       }
161       aNgName.StopNamedShape(NS);  
162     }
163   }
164
165   // index
166   aDOMStr = anElem.getAttribute(::IndexString());
167   if (!aDOMStr.GetInteger(aNb))
168   {
169     aMsgString = TCollection_ExtendedString
170       ("XmlMNaming_NamingDriver: Cannot retrieve "
171        "integer value of Index from \"") + aDOMStr + "\"";
172     myMessageDriver->Send (aMsgString, Message_Fail);
173     return Standard_False;
174   }
175   aNgName.Index(aNb);
176 //
177   if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 3) {
178     XmlObjMgt_DOMString aDomEntry = anElem.getAttribute(::ContextLabelString());
179     if (aDomEntry != NULL)
180     {   
181       TCollection_AsciiString anEntry;
182       if (XmlObjMgt::GetTagEntryString (aDomEntry, anEntry) == Standard_False)
183       {
184         TCollection_ExtendedString aMessage =
185           TCollection_ExtendedString ("Cannot retrieve Entry from \"")
186           + aDomEntry + '\"';
187         myMessageDriver->Send (aMessage, Message_Fail);
188         return Standard_False;
189       }
190
191       // find label by entry
192       TDF_Label tLab; // Null label.
193       if (anEntry.Length() > 0) {
194         TDF_Tool::Label(aNg->Label().Data(), anEntry, tLab, Standard_True);
195         aNgName.ContextLabel(tLab);
196 #ifdef OCCT_DEBUG
197         cout << "Retrieving Context Label = " << anEntry.ToCString() <<endl;
198 #endif
199       }
200     }
201 #ifdef OCCT_DEBUG
202     else
203       cout << "Retrieving Context Label is NULL" <<endl;
204 #endif
205
206     if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 4 && 
207       theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < 7) {
208           // Orientation processing - converting from old format
209           Handle(TNaming_NamedShape) aNS;
210           if (aNg->Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
211             //const TDF_Label& aLab = aNS->Label();
212             TNaming_Iterator itL (aNS);
213             for (; itL.More(); itL.Next()) {
214               const TopoDS_Shape& S = itL.NewShape();
215               if (S.IsNull()) continue;
216               if(aNS->Evolution() == TNaming_SELECTED) {
217                 if (itL.More() && itL.NewShape().ShapeType() != TopAbs_VERTEX &&
218                     !itL.OldShape().IsNull() && itL.OldShape().ShapeType() == TopAbs_VERTEX ) {//OR-N
219                   TopAbs_Orientation OrientationToApply = itL.OldShape().Orientation();
220                   aNgName.Orientation(OrientationToApply);
221                 }
222               }
223             }
224           }         
225         }
226     if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 6) {
227        aDOMStr = anElem.getAttribute(::OrientString());
228        if (!aDOMStr.GetInteger(aNb))
229        {
230          aMsgString = TCollection_ExtendedString
231            ("XmlMNaming_NamingDriver: Cannot retrieve "
232             "integer value of orientation from \"") + aDOMStr + "\"";
233          myMessageDriver->Send (aMsgString, Message_Fail);
234          return Standard_False;
235        }
236        aNgName.Orientation((TopAbs_Orientation)aNb);
237     }
238     // or. end
239   }
240 #ifdef OCCT_DEBUG
241   else 
242     cout << "Current Document Format Version = "  << theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() <<endl;
243 #endif
244   return Standard_True;
245 }
246
247 //=======================================================================
248 //function : Paste
249 //purpose  : transient -> persistent (store)
250 //=======================================================================
251 void XmlMNaming_NamingDriver::Paste
252                         (const Handle(TDF_Attribute)& theSource,
253                          XmlObjMgt_Persistent&        theTarget,
254                          XmlObjMgt_SRelocationTable&  theRelocTable) const
255 {
256   Handle(TNaming_Naming) aNg = Handle(TNaming_Naming)::DownCast(theSource);
257   XmlObjMgt_Element& anElem = theTarget;
258   const TNaming_Name& aNgName = aNg->GetName();
259
260   // type and shape type
261   anElem.setAttribute(::TypeString(), NameTypeToString(aNgName.Type()));
262   anElem.setAttribute(::ShapeTypeString(), ShapeEnumToString(aNgName.ShapeType()));
263   
264   Standard_Integer aNb;
265
266   // arguments
267   Standard_Integer NbArgs = aNgName.Arguments().Extent();
268   if (NbArgs > 0)
269   {
270     TCollection_AsciiString anArgsStr;
271     for (TNaming_ListIteratorOfListOfNamedShape it (aNgName.Arguments()); it.More(); it.Next())
272     {
273       Handle(TNaming_NamedShape) anArg = it.Value();
274       aNb = 0;
275       if (!anArg.IsNull())
276       {
277         aNb = theRelocTable.FindIndex(anArg);
278         if (aNb == 0)
279         {
280           aNb = theRelocTable.Add(anArg);
281         }
282         anArgsStr += TCollection_AsciiString(aNb) + " ";
283       }
284       else anArgsStr += "0 ";
285     }
286     anElem.setAttribute(::ArgumentsString(), anArgsStr.ToCString());
287   }
288
289   // stop named shape
290   Handle(TNaming_NamedShape) aSNS = aNgName.StopNamedShape();
291   if (!aSNS.IsNull())
292   {
293     aNb = theRelocTable.FindIndex(aSNS);
294     if (aNb == 0)
295     {
296       aNb = theRelocTable.Add(aSNS);
297     }
298     anElem.setAttribute(::StopNamedShapeString(), aNb);
299   }
300
301   // index
302   anElem.setAttribute(::IndexString(), aNgName.Index());
303
304   // context label
305   TCollection_AsciiString anEntry;
306   if(!aNgName.ContextLabel().IsNull())
307     TDF_Tool::Entry(aNgName.ContextLabel(), anEntry);  
308   XmlObjMgt_DOMString aDOMString;
309   XmlObjMgt::SetTagEntryString (aDOMString, anEntry);
310   anElem.setAttribute(::ContextLabelString(), aDOMString);
311 #ifdef OCCT_DEBUG
312   cout << "XmlMNaming_NamingDriver::Store: ContextLabel Entry = " << anEntry << endl;
313   if (aDOMString != NULL)
314   {
315     Standard_CString aStr = Standard_CString(aDOMString.GetString());
316     cout << "XmlMNaming_NamingDriver::Store: ContextLabel DOMString = " << aStr << endl;
317   } else
318     cout << "XmlMNaming_NamingDriver::Store: aDOMString is NULL" <<endl;
319 #endif
320
321   // orientation
322   anElem.setAttribute(::OrientString(), (Standard_Integer)aNgName.Orientation());
323
324 }
325
326 //=======================================================================
327 //function : ShapeEnumToString
328 //purpose  : 
329 //=======================================================================
330 static const XmlObjMgt_DOMString& ShapeEnumToString (const TopAbs_ShapeEnum theE)
331 {
332   switch (theE)
333   {
334   case TopAbs_COMPOUND  : return ::ShCompoundString();
335   case TopAbs_COMPSOLID : return ::ShCompsolidString();
336   case TopAbs_SOLID     : return ::ShSolidString();
337   case TopAbs_SHELL     : return ::ShShellString();
338   case TopAbs_FACE      : return ::ShFaceString();
339   case TopAbs_WIRE      : return ::ShWireString();
340   case TopAbs_EDGE      : return ::ShEdgeString();
341   case TopAbs_VERTEX    : return ::ShVertexString();
342   case TopAbs_SHAPE     : return ::ShShapeString();  
343   }
344   static XmlObjMgt_DOMString aNullString;
345   return aNullString; // To avoid compilation error message.
346 }
347
348 //=======================================================================
349 //function : NameTypeToString
350 //purpose  : 
351 //=======================================================================
352 static const XmlObjMgt_DOMString& NameTypeToString (const TNaming_NameType theE) 
353 {
354   switch (theE)
355   { 
356   case TNaming_UNKNOWN             : return ::NTUnknownString();  
357   case TNaming_IDENTITY            : return ::NTIdentityString();
358   case TNaming_MODIFUNTIL          : return ::NTModifUntilString();
359   case TNaming_GENERATION          : return ::NTGenerationString();
360   case TNaming_INTERSECTION        : return ::NTIntersectionString();
361   case TNaming_UNION               : return ::NTUnionString();
362   case TNaming_SUBSTRACTION        : return ::NTSubtractionString();
363   case TNaming_CONSTSHAPE          : return ::NTConstShapeString();
364   case TNaming_FILTERBYNEIGHBOURGS : return ::NTFilterByNeighString();
365   case TNaming_ORIENTATION         : return ::NTOrientationString();
366   case TNaming_WIREIN              : return ::NTWireInString();
367   case TNaming_SHELLIN             : return ::NTShellInString();
368   default:
369     throw Standard_DomainError("TNaming_NameType; enum term unknown ");
370   }
371 }
372
373 //=======================================================================
374 //function : ShapeEnumFromString
375 //purpose  : 
376 //=======================================================================
377 static TopAbs_ShapeEnum ShapeEnumFromString (const XmlObjMgt_DOMString& theString)
378 {
379   TopAbs_ShapeEnum aResult = TopAbs_SHAPE;
380   if (!theString.equals (::ShShapeString()))
381   {
382     if (theString.equals (::ShCompoundString()))
383       aResult = TopAbs_COMPOUND;
384     else if (theString.equals (::ShCompsolidString()))
385       aResult = TopAbs_COMPSOLID;
386     else if (theString.equals (::ShSolidString()))
387       aResult = TopAbs_SOLID;
388     else if (theString.equals (::ShShellString()))
389       aResult = TopAbs_SHELL;
390     else if (theString.equals (::ShFaceString()))
391       aResult = TopAbs_FACE;
392     else if (theString.equals (::ShWireString()))
393       aResult = TopAbs_WIRE;
394     else if (theString.equals (::ShEdgeString()))
395       aResult = TopAbs_EDGE;
396     else if (theString.equals (::ShVertexString()))
397       aResult = TopAbs_VERTEX;
398     else
399       throw Standard_DomainError("TopAbs_ShapeEnum; string value without enum term equivalence");
400   }
401   return aResult;
402 }
403
404 //=======================================================================
405 //function : NameTypeFromString
406 //purpose  : 
407 //=======================================================================
408 static TNaming_NameType NameTypeFromString (const XmlObjMgt_DOMString& theString) 
409 {
410   TNaming_NameType aResult = TNaming_UNKNOWN;
411   if (!theString.equals (::NTUnknownString()))
412   {
413     if (theString.equals (::NTIdentityString()))
414       aResult = TNaming_IDENTITY;
415     else if (theString.equals (::NTModifUntilString()))
416       aResult = TNaming_MODIFUNTIL;
417     else if (theString.equals (::NTGenerationString()))
418       aResult = TNaming_GENERATION;
419     else if (theString.equals (::NTIntersectionString()))
420       aResult = TNaming_INTERSECTION;
421     else if (theString.equals (::NTUnionString()))
422       aResult = TNaming_UNION;
423     else if (theString.equals (::NTSubtractionString()))
424       aResult = TNaming_SUBSTRACTION;
425     else if (theString.equals (::NTConstShapeString()))
426       aResult = TNaming_CONSTSHAPE;
427     else if (theString.equals (::NTFilterByNeighString()))
428       aResult = TNaming_FILTERBYNEIGHBOURGS;
429     else if (theString.equals (::NTOrientationString()))
430       aResult = TNaming_ORIENTATION;
431     else if (theString.equals (::NTWireInString()))
432       aResult = TNaming_WIREIN;
433     else if (theString.equals (::NTShellInString()))
434       aResult = TNaming_SHELLIN;
435     else
436       throw Standard_DomainError("TNaming_NameType; string value without enum term equivalence");
437   }
438   return aResult;
439 }