0030773: Application Framework - To allow to inherit existing attributes to reuse...
[occt.git] / src / BinMDF / BinMDF_ADriverTable.cxx
1 // Created on: 2002-10-29
2 // Created by: Michael SAZONOV
3 // Copyright (c) 2002-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 <BinMDF_ADriver.hxx>
18 #include <BinMDF_ADriverTable.hxx>
19 #include <BinMDF_DataMapIteratorOfTypeADriverMap.hxx>
20 #include <BinMDF_DerivedDriver.hxx>
21 #include <BinMDF_StringIdMap.hxx>
22 #include <Standard_NoSuchObject.hxx>
23 #include <Standard_Type.hxx>
24 #include <TCollection_HAsciiString.hxx>
25 #include <TDF_DerivedAttribute.hxx>
26
27 IMPLEMENT_STANDARD_RTTIEXT(BinMDF_ADriverTable,Standard_Transient)
28
29 //=======================================================================
30 //function : BinMDF_ADriverTable
31 //purpose  : Constructor
32 //=======================================================================
33 BinMDF_ADriverTable::BinMDF_ADriverTable ()
34 {
35 }
36
37 //=======================================================================
38 //function : AddDriver
39 //purpose  : Adds a translation driver <theDriver>.
40 //=======================================================================
41
42 void BinMDF_ADriverTable::AddDriver
43                 (const Handle(BinMDF_ADriver)& theDriver)
44 {
45   const Handle(Standard_Type)& aType = theDriver->SourceType();
46   myMap.Bind (aType, theDriver);
47 }
48
49 //=======================================================================
50 //function : AddDerivedDriver
51 //purpose  :
52 //=======================================================================
53 void BinMDF_ADriverTable::AddDerivedDriver (const Handle(TDF_Attribute)& theInstance)
54 {
55   const Handle(Standard_Type)& anInstanceType = theInstance->DynamicType();
56   if (!myMap.IsBound (anInstanceType)) // no direct driver, use a derived one
57   {
58     for (Handle(Standard_Type) aType = anInstanceType->Parent(); !aType.IsNull(); aType = aType->Parent())
59     {
60       if (myMap.IsBound (aType))
61       {
62         Handle(BinMDF_DerivedDriver) aDriver = new BinMDF_DerivedDriver (theInstance, myMap (aType));
63         myMap.Bind (anInstanceType, aDriver);
64         return;
65       }
66     }
67   }
68 }
69
70 //=======================================================================
71 //function : AddDerivedDriver
72 //purpose  :
73 //=======================================================================
74 const Handle(Standard_Type)& BinMDF_ADriverTable::AddDerivedDriver (Standard_CString theDerivedType)
75 {
76   if (Handle(TDF_Attribute) anInstance = TDF_DerivedAttribute::Attribute (theDerivedType))
77   {
78     AddDerivedDriver (anInstance);
79     return anInstance->DynamicType();
80   }
81   static const Handle(Standard_Type) aNullType;
82   return aNullType;
83 }
84
85 //=======================================================================
86 //function : AssignIds
87 //purpose  : Assigns the IDs to the drivers of the given Types.
88 //           It uses indices in the map as IDs.
89 //           Useful in storage procedure.
90 //=======================================================================
91
92 void BinMDF_ADriverTable::AssignIds
93                 (const TColStd_IndexedMapOfTransient& theTypes)
94 {
95   myMapId.Clear();
96   Standard_Integer i;
97   for (i=1; i <= theTypes.Extent(); i++) {
98     Handle(Standard_Type) aType (Handle(Standard_Type)::DownCast (theTypes(i)));
99     if (myMap.IsBound (aType)) {
100       myMapId.Bind (aType, i);
101     }
102     else {
103       throw Standard_NoSuchObject((TCollection_AsciiString("BinMDF_ADriverTable::AssignIds : ") +
104           "the type " + aType->Name() + " has not been registered").ToCString());
105     }
106   }
107 }
108
109 //=======================================================================
110 //function : AssignIds
111 //purpose  : Assigns the IDs to the drivers of the given Type Names;
112 //           It uses indices in the sequence as IDs.
113 //           Useful in retrieval procedure.
114 //=======================================================================
115
116 void BinMDF_ADriverTable::AssignIds
117                 (const TColStd_SequenceOfAsciiString& theTypeNames)
118 {
119   myMapId.Clear();
120   // first prepare the data map (TypeName => TypeID) for input types
121   BinMDF_StringIdMap aStringIdMap;
122   Standard_Integer i;
123   for (i=1; i <= theTypeNames.Length(); i++) {
124     const TCollection_AsciiString& aTypeName = theTypeNames(i);
125     aStringIdMap.Bind (aTypeName, i);
126   }
127   // and now associate the names with the registered types
128   BinMDF_DataMapIteratorOfTypeADriverMap it (myMap);
129   for (; it.More(); it.Next()) {
130     const Handle(Standard_Type)& aType = it.Key();
131     const Handle(BinMDF_ADriver)& aDriver = it.Value();
132     const TCollection_AsciiString& aTypeName = aDriver->TypeName();
133     if (aStringIdMap.IsBound(aTypeName)) {
134       i = aStringIdMap(aTypeName);
135       myMapId.Bind (aType, i);
136     }
137   }
138
139   // try to add derived drivers for attributes not found in myMap
140   for (BinMDF_StringIdMap::Iterator aStrId (aStringIdMap); aStrId.More(); aStrId.Next())
141   {
142     if (!myMapId.IsBound2 (aStrId.Value()))
143     {
144       if (Handle(Standard_Type) anAdded = AddDerivedDriver (aStrId.Key().ToCString()))
145       {
146         myMapId.Bind (anAdded, aStrId.Value());
147       }
148     }
149   }
150 }