0027970: Improvement of standard attributes usability - containers.
[occt.git] / src / XmlMDataStd / XmlMDataStd_ReferenceArrayDriver.cxx
1 // Created on: 2007-05-29
2 // Created by: Vlad Romashko
3 // Copyright (c) 2007-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 <LDOM_MemManager.hxx>
19 #include <Standard_Type.hxx>
20 #include <TDataStd_ReferenceArray.hxx>
21 #include <TDF_Attribute.hxx>
22 #include <TDF_Label.hxx>
23 #include <TDF_Tool.hxx>
24 #include <XmlMDataStd_ReferenceArrayDriver.hxx>
25 #include <XmlObjMgt.hxx>
26 #include <XmlObjMgt_Document.hxx>
27 #include <XmlObjMgt_Persistent.hxx>
28
29 IMPLEMENT_STANDARD_RTTIEXT(XmlMDataStd_ReferenceArrayDriver,XmlMDF_ADriver)
30 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
31 IMPLEMENT_DOMSTRING (LastIndexString,  "last")
32 IMPLEMENT_DOMSTRING (ExtString,        "string")
33 IMPLEMENT_DOMSTRING (AttributeIDString, "refarrattguid")
34 //=======================================================================
35 //function : XmlMDataStd_ReferenceArrayDriver
36 //purpose  : Constructor
37 //=======================================================================
38 XmlMDataStd_ReferenceArrayDriver::XmlMDataStd_ReferenceArrayDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
39      : XmlMDF_ADriver (theMsgDriver, NULL)
40 {
41
42 }
43
44 //=======================================================================
45 //function : NewEmpty
46 //purpose  : 
47 //=======================================================================
48 Handle(TDF_Attribute) XmlMDataStd_ReferenceArrayDriver::NewEmpty() const
49 {
50   return new TDataStd_ReferenceArray();
51 }
52
53 //=======================================================================
54 //function : Paste
55 //purpose  : persistent -> transient (retrieve)
56 //=======================================================================
57 Standard_Boolean XmlMDataStd_ReferenceArrayDriver::Paste(const XmlObjMgt_Persistent&  theSource,
58                                                          const Handle(TDF_Attribute)& theTarget,
59                                                          XmlObjMgt_RRelocationTable&  ) const
60 {
61   Standard_Integer aFirstInd, aLastInd;
62   const XmlObjMgt_Element& anElement = theSource;
63
64   // Read the FirstIndex; if the attribute is absent initialize to 1
65   XmlObjMgt_DOMString aFirstIndex= anElement.getAttribute(::FirstIndexString());
66   if (aFirstIndex == NULL)
67     aFirstInd = 1;
68   else if (!aFirstIndex.GetInteger(aFirstInd)) 
69   {
70     TCollection_ExtendedString aMessageString =
71       TCollection_ExtendedString("Cannot retrieve the first index"
72                                  " for ReferenceArray attribute as \"")
73         + aFirstIndex + "\"";
74     WriteMessage (aMessageString);
75     return Standard_False;
76   }
77
78   // Read the LastIndex; the attribute should present
79   if (!anElement.getAttribute(::LastIndexString()).GetInteger(aLastInd)) 
80   {
81     TCollection_ExtendedString aMessageString =
82       TCollection_ExtendedString("Cannot retrieve the last index"
83                                  " for ReferenceArray attribute as \"")
84         + aFirstIndex + "\"";
85     WriteMessage (aMessageString);
86     return Standard_False;
87   }
88
89   Handle(TDataStd_ReferenceArray) aReferenceArray = Handle(TDataStd_ReferenceArray)::DownCast(theTarget);
90   aReferenceArray->Init(aFirstInd, aLastInd);
91   
92   if (!anElement.hasChildNodes())
93   {
94     TCollection_ExtendedString aMessageString = 
95       TCollection_ExtendedString("Cannot retrieve a Array of reference");
96     WriteMessage (aMessageString);
97     return Standard_False;
98   }
99
100   LDOM_Node aCurNode = anElement.getFirstChild();
101   LDOM_Element* aCurElement = (LDOM_Element*)&aCurNode;
102   XmlObjMgt_DOMString aValueStr;
103   Standard_Integer i = aFirstInd;
104   while (*aCurElement != anElement.getLastChild())
105   {
106     aValueStr = XmlObjMgt::GetStringValue( *aCurElement );
107     if (aValueStr == NULL)
108     {
109       WriteMessage ("Cannot retrieve reference string from element");
110       return Standard_False;
111     }
112     TCollection_AsciiString anEntry;
113     if (XmlObjMgt::GetTagEntryString (aValueStr, anEntry) == Standard_False)
114     {
115       TCollection_ExtendedString aMessage =
116         TCollection_ExtendedString ("Cannot retrieve reference from \"")
117         + aValueStr + '\"';
118       WriteMessage (aMessage);
119       return Standard_False;
120     }
121     // Find label by entry
122     TDF_Label tLab; // Null label.
123     if (anEntry.Length() > 0)
124     {
125       TDF_Tool::Label(aReferenceArray->Label().Data(), anEntry, tLab, Standard_True);
126     }
127     aReferenceArray->SetValue(i++, tLab);
128     aCurNode = aCurElement->getNextSibling();
129     aCurElement = (LDOM_Element*)&aCurNode;
130   }
131
132   // Last reference
133   aValueStr = XmlObjMgt::GetStringValue( *aCurElement );
134   if (aValueStr == NULL)
135   {
136     WriteMessage ("Cannot retrieve reference string from element");
137     return Standard_False;
138   }
139   TCollection_AsciiString anEntry;
140   if (XmlObjMgt::GetTagEntryString (aValueStr, anEntry) == Standard_False)
141   {
142     TCollection_ExtendedString aMessage =
143       TCollection_ExtendedString ("Cannot retrieve reference from \"")
144       + aValueStr + '\"';
145     WriteMessage (aMessage);
146     return Standard_False;
147   }
148   // Find label by entry
149   TDF_Label tLab; // Null label.
150   if (anEntry.Length() > 0)
151   {
152     TDF_Tool::Label(aReferenceArray->Label().Data(), anEntry, tLab, Standard_True);
153   }
154   aReferenceArray->SetValue(i, tLab);
155
156   // attribute id
157   Standard_GUID aGUID;
158   XmlObjMgt_DOMString aGUIDStr = anElement.getAttribute(::AttributeIDString());
159   if (aGUIDStr.Type() == XmlObjMgt_DOMString::LDOM_NULL)
160     aGUID = TDataStd_ReferenceArray::GetID(); //default case
161   else
162     aGUID = Standard_GUID(Standard_CString(aGUIDStr.GetString())); // user defined case
163
164   aReferenceArray->SetID(aGUID);
165
166   return Standard_True;
167 }
168
169 //=======================================================================
170 //function : Paste
171 //purpose  : transient -> persistent (store)
172 //=======================================================================
173 void XmlMDataStd_ReferenceArrayDriver::Paste(const Handle(TDF_Attribute)& theSource,
174                                              XmlObjMgt_Persistent&        theTarget,
175                                              XmlObjMgt_SRelocationTable&  ) const
176 {
177   Handle(TDataStd_ReferenceArray) aReferenceArray = Handle(TDataStd_ReferenceArray)::DownCast(theSource);
178   TDF_Label L = aReferenceArray->Label();
179   if (L.IsNull())
180   {
181     WriteMessage ("Label of a ReferenceArray is Null.");
182     return;
183   }
184
185   Standard_Integer aL = aReferenceArray->Lower();
186   Standard_Integer anU = aReferenceArray->Upper();
187   XmlObjMgt_Element& anElement = theTarget;
188   anElement.setAttribute(::FirstIndexString(), aL);
189   anElement.setAttribute(::LastIndexString(), anU);
190   
191   XmlObjMgt_Document aDoc (anElement.getOwnerDocument());
192   
193   for (Standard_Integer i = aL; i <= anU; i++)
194   {
195     if (L.IsDescendant(aReferenceArray->Value(i).Root()))
196     {
197       // Internal reference
198       TCollection_AsciiString anEntry;
199       TDF_Tool::Entry(aReferenceArray->Value(i), anEntry);
200
201       XmlObjMgt_DOMString aDOMString;
202       XmlObjMgt::SetTagEntryString (aDOMString, anEntry);
203       XmlObjMgt_Element aCurTarget = aDoc.createElement( ::ExtString() );
204       XmlObjMgt::SetStringValue (aCurTarget, aDOMString, Standard_True);
205       anElement.appendChild( aCurTarget );
206     }
207   }
208   if(aReferenceArray->ID() != TDataStd_ReferenceArray::GetID()) {
209     //convert GUID
210     Standard_Character aGuidStr [Standard_GUID_SIZE_ALLOC];
211     Standard_PCharacter pGuidStr = aGuidStr;
212     aReferenceArray->ID().ToCString (pGuidStr);
213     theTarget.Element().setAttribute (::AttributeIDString(), aGuidStr);
214   }
215 }