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