1 //                                               -*- C++ -*-
2 /**
3  *  @brief Class PersistentObjectFactory reloads a PersistentObject from a storage manager
4  *
5  *  Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca
6  *
7  *  This library is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU Lesser General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License
18  *  along with this library.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 #ifndef OPENTURNS_PERSISTENTOBJECTFACTORY_HXX
22 #define OPENTURNS_PERSISTENTOBJECTFACTORY_HXX
23 
24 #include "openturns/PersistentObject.hxx"
25 #include "openturns/StorageManager.hxx"
26 #include "openturns/Exception.hxx"
27 #include "openturns/Catalog.hxx"
28 
29 BEGIN_NAMESPACE_OPENTURNS
30 
31 
32 
33 /**
34  * @class PersistentObjectFactory
35  *
36  * @brief Reloads a PersistentObject from a storage manager
37  * @see PersistentObject
38  * @see StorageManager
39  */
40 
41 class OT_API PersistentObjectFactory
42 {
43 public:
44 
45 
46   /** @copydoc PersistentObject::clone() const */
47   virtual PersistentObjectFactory * clone() const = 0;
48 
49   /** Destructor */
~PersistentObjectFactory()50   virtual ~PersistentObjectFactory() {};
51 
52   /** Method build() creates a new PersistentObject from the storage manager
53    * @param mgr The storage manager that points to the object to be reloaded
54    * @return A pointer to a newly allocated object
55    * @internal
56    */
57   virtual PersistentObject * build(StorageManager & mgr) const = 0;
58 
59   /** Method assign() fills a PersistentObject with another one (must have same type)
60    *
61    * This method performs an assignment between the two objects after having casted them to the same type
62    * @param po The persistent object to be refilled (may be empty, ie default constructed)
63    * @param other The persistent object of the same type as \em po that should be copied to \em po
64    * @internal
65    */
66   virtual void assign(PersistentObject & po, const PersistentObject & other) const = 0;
67 
68   /** This method register the factory into the Catalog
69    * @see Catalog
70    * @internal
71    */
registerMe(const String & className) const72   void registerMe(const String & className) const
73   {
74     Catalog::Add(className, this);
75   }
76 
77   /** Accessor to PersistentObject's shadowed id */
setShadowedId(PersistentObject & obj,Id id) const78   void setShadowedId(PersistentObject & obj, Id id) const
79   {
80     obj.setShadowedId(id);
81   }
82 
getShadowedId(PersistentObject & obj) const83   Id getShadowedId(PersistentObject & obj) const
84   {
85     return obj.getShadowedId();
86   }
87 
88 protected:
89 
90 private:
91 
92 }; /* class PersistentObjectFactory */
93 
94 
95 /**
96  * @class Factory
97  * @brief Ease the creation of factories for any PersistentObject based class
98  * @tparam PERSISTENT The class which the %Factory is bounded to
99  */
100 template <class PERSISTENT>
101 class Factory
102   : PersistentObjectFactory
103 {
104 public:
105   /** Constructor
106    *
107    * @internal See the CLASSNAME_INIT macro.
108    */
Factory()109   Factory()
110   {
111     registerMe(PERSISTENT::GetClassName());
112   }
113 
114   /** Virtual constructor */
clone() const115   virtual Factory * clone() const
116   {
117     return new Factory(*this);
118   }
119 
120   /** Method build() creates a new PersistentObject from the storage manager */
build(StorageManager & mgr) const121   virtual PersistentObject * build(StorageManager & mgr) const
122   {
123     Advocate adv ( mgr.readObject() );
124 
125     PERSISTENT * p_rebuildObject = new PERSISTENT();
126     assert(p_rebuildObject && "PersistentObject not allocated");
127     //try {
128 
129     p_rebuildObject->load(adv);
130 
131     //} catch (Exception & ex) {
132     // Nothing to do
133     // The rebuild object remains the default one
134     //}
135     return p_rebuildObject;
136   }
137 
138   /** Method assign() fills a PersistentObject with another one (must have same type) */
assign(PersistentObject & po,const PersistentObject & other) const139   virtual void assign(PersistentObject & po, const PersistentObject & other) const
140   {
141     PERSISTENT & ref_po          = static_cast<PERSISTENT &>(po);
142     const PERSISTENT & ref_other = static_cast<const PERSISTENT &>(other);
143     ref_po = ref_other;
144   }
145 
146 }; /* end class Factory */
147 
148 
149 END_NAMESPACE_OPENTURNS
150 
151 #endif /* OPENTURNS_PERSISTENTOBJECTFACTORY_HXX */
152