PropertyMgr.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD& STL
5 // ============================================================================
6 #include <iostream>
7 #include <sstream>
8 #include <string>
9 #include <functional>
10 #include <stdexcept>
11 #include <algorithm>
12 // ============================================================================
13 // GaudiKernel
14 // ============================================================================
15 #include "GaudiKernel/PropertyMgr.h"
16 #include "GaudiKernel/INamedInterface.h"
17 #include "GaudiKernel/GaudiException.h"
18 #include "GaudiKernel/Bootstrap.h"
19 #include "GaudiKernel/ISvcLocator.h"
20 #include "GaudiKernel/IMessageSvc.h"
21 // ============================================================================
22 namespace
23 {
24  // ==========================================================================
26  struct Nocase : public std::binary_function<std::string,std::string,bool>
27  {
28  inline bool operator() ( const std::string& v1 ,
29  const std::string& v2 ) const
30  {
31  std::string::const_iterator i1 = v1.begin() ;
32  std::string::const_iterator i2 = v2.begin() ;
33  for ( ; v1.end() != i1 && v2.end() != i2 ; ++i1 , ++i2 )
34  { if ( toupper(*i1) != toupper(*i2) ) { return false ; } }
35  return v1.size() == v2.size() ;
36  }
37  };
38  // ==========================================================================
40  struct PropByName : public std::unary_function<const Property*,bool>
41  {
42  PropByName ( const std::string& name ) : m_name ( name ) {} ;
43  inline bool operator() ( const Property* p ) const
44  { return ( 0 == p ) ? false : m_cmp ( p->name() , m_name ) ; }
45  private:
46  std::string m_name ;
47  Nocase m_cmp ;
48  } ;
49  // ==========================================================================
50 }
51 // ====================================================================
52 // constructor from the interface
53 // ====================================================================
55  : m_properties ()
56  , m_remoteProperties ()
57  , m_todelete ()
58  , m_pOuter ( iface )
59 {
60  addRef(); // initial reference count set to 1
61 }
62 // ====================================================================
63 // copy constructor
64 // ====================================================================
66  : IInterface(right),
67  IProperty(right),
69  base_class(right)
70  , m_properties ( right.m_properties )
71  , m_remoteProperties ( right.m_remoteProperties )
72  , m_todelete ( right.m_todelete )
73  , m_pOuter ( right.m_pOuter )
74 {
75  addRef(); // initial reference count set to 1
76  std::transform
77  ( m_todelete.begin() , m_todelete.end () ,
78  m_todelete.begin() , std::mem_fun(&Property::clone));
79 }
80 // ====================================================================
81 // destructor
82 // ====================================================================
84 {
86  for ( Properties::iterator ip = m_todelete.begin() ;
87  m_todelete.end() != ip ; ++ip ) { delete *ip ; }
88 }
89 // ====================================================================
90 // assignment operator
91 // ====================================================================
93 {
94  if ( &right == this ) { return *this ; }
95  //
96  for ( Properties::iterator ip = m_todelete.begin() ;
97  m_todelete.end() != ip ; ++ip ) { delete *ip ; }
98  //
99  m_properties = right.m_properties ;
101  m_todelete = right.m_todelete ;
102  m_pOuter = right.m_pOuter ;
103  //
104  std::transform
105  ( m_todelete.begin() , m_todelete.end () ,
106  m_todelete.begin() , std::mem_fun(&Property::clone));
107  //
108  return *this ;
109 }
110 // ====================================================================
111 // Declare a remote property
112 // ====================================================================
114 ( const std::string& name ,
115  IProperty* rsvc ,
116  const std::string& rname )
117 {
118  if ( 0 == rsvc ) { return 0 ; }
119  const std::string& nam = rname.empty() ? name : rname ;
120  Property* p = property ( nam , rsvc->getProperties() ) ;
121  m_remoteProperties.push_back ( RemProperty ( name , std::make_pair ( rsvc , nam ) ) ) ;
122  return p ;
123 }
124 // ====================================================================
125 // get the property by name form the proposed list
126 // ====================================================================
128 ( const std::string& name ,
129  const std::vector<Property*>& props ) const
130 {
131  Properties::const_iterator it =
132  std::find_if ( props.begin() , props.end() , PropByName( name ) ) ;
133  if ( props.end() != it ) { return *it ; } // RETURN
134  return 0 ; // RETURN
135 }
136 // ====================================================================
137 // retrieve the property by name
138 // ====================================================================
140 ( const std::string& name ) const
141 {
142  // local property ?
143  Property* lp = property ( name , m_properties ) ;
144  if ( 0 != lp ) { return lp ; } // RETURN
145  // look for remote property
146  Nocase cmp ;
147  for ( RemoteProperties::const_iterator it = m_remoteProperties.begin() ;
148  m_remoteProperties.end() != it ; ++it )
149  {
150  if ( !cmp(it->first,name) ) { continue ; } // CONTINUE
151  const IProperty* p = it->second.first ;
152  if ( 0 == p ) { continue ; } // CONITNUE
153  return property ( it->second.second , p->getProperties() ) ; // RETURN
154  }
155  return 0 ; // RETURN
156 }
157 // ====================================================================
158 /* set a property from another property
159  * Implementation of IProperty::setProperty
160  */
161 // =====================================================================
163 {
164  Property* pp = property( p.name() ) ;
165  if ( 0 == pp ) { return StatusCode::FAILURE ; } // RETURN
166  //
167  try
168  { if ( !pp->assign(p) ) { return StatusCode::FAILURE ; } } // RETURN
169  catch(...) { return StatusCode::FAILURE ; } // RETURN
170  //
171  return StatusCode::SUCCESS; // Property value set
172 }
173 // ====================================================================
174 /* set a property from the stream
175  * Implementation of IProperty::setProperty
176  */
177 // =====================================================================
179 PropertyMgr::setProperty( const std::string& i )
180 {
181  std::string name ;
182  std::string value ;
183  StatusCode sc = Gaudi::Parsers::parse( name , value , i ) ;
184  if ( sc.isFailure() ) { return sc ; }
185  return setProperty ( name , value ) ;
186 }
187 // =====================================================================
188 /* set a property from the string
189  * Implementation of IProperty::setProperty
190  */
191 // =====================================================================
193 PropertyMgr::setProperty( const std::string& n, const std::string& v )
194 {
195  Property* p = property( n ) ;
196  if ( 0 == p ) { return StatusCode::FAILURE ; } // RETURN
197  bool result = p->fromString( v ) != 0 ;
198  return result ? StatusCode::SUCCESS : StatusCode::FAILURE ;
199 }
200 // =====================================================================
201 /* Retrieve the value of a property
202  * Implementation of IProperty::getProperty
203  */
204 // =====================================================================
206 {
207  try
208  {
209  const Property* pp = property( p->name() ) ;
210  if ( 0 == pp ) { return StatusCode::FAILURE ; } // RETURN
211  if ( !pp->load( *p ) ) { return StatusCode::FAILURE ; } // RETURN
212  }
213  catch ( ... ) { return StatusCode::FAILURE; } // RETURN
214  return StatusCode::SUCCESS ; // RETURN
215 }
216 // =====================================================================
217 /* Get the property by name
218  * Implementation of IProperty::getProperty
219  */
220 // =====================================================================
221 const Property& PropertyMgr::getProperty( const std::string& name) const
222 {
223  const Property* p = property( name ) ;
224  if ( 0 != p ) { return *p ; } // RETURN
225  //
226  throw std::out_of_range( "Property "+name+" not found." ); // Not found
227 }
228 // =====================================================================
229 /* Get the property by name
230  * Implementation of IProperty::getProperty
231  */
232 // =====================================================================
234 ( const std::string& n ,
235  std::string& v ) const
236 {
237  // get the property
238  const Property* p = property( n ) ;
239  if ( 0 == p ) { return StatusCode::FAILURE ; }
240  // convert the value into the string
241  v = p->toString() ;
242  //
243  return StatusCode::SUCCESS ;
244 }
245 // =====================================================================
246 // Implementation of IProperty::getProperties
247 // =====================================================================
248 const std::vector<Property*>&
250 // =====================================================================
251 // Implementation of IInterface::queryInterface
252 // =====================================================================
254  // try local interfaces
255  StatusCode sc= base_class::queryInterface(iid, pinterface);
256  if (sc.isSuccess()) return sc;
257  // fall back on the owner
258  return (0 != m_pOuter)? m_pOuter->queryInterface(iid, pinterface)
259  : sc; // FAILURE
260 }
261 // =====================================================================
262 // Implementation of IProperty::hasProperty
263 // =====================================================================
264 bool PropertyMgr::hasProperty(const std::string& name) const {
265  return any_of(begin(m_properties), end(m_properties),
266  [&name](Property* prop) {
267  return Nocase()(prop->name(), name);
268  });
269 }
270 void PropertyMgr::assertUniqueName(const std::string& name) const {
271  if (UNLIKELY(hasProperty(name))) {
272  // TODO: queryInterface should be const
273  // Note: using SmartIF causes a segfault in genconf (wrong ref. count)
274  INamedInterface* owner = nullptr;
275  std::string ownerName{"PropertyMgr"};
276  if (m_pOuter &&
277  const_cast<IInterface*>(m_pOuter)->queryInterface(INamedInterface::interfaceID(), (void**)&owner).isSuccess()) {
278  ownerName = owner->name();
279  }
280  auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>("MessageSvc");
281  MsgStream log(msgSvc, ownerName);
282  log << MSG::WARNING
283  << "duplicated property name '" << name
284  << "', see https://its.cern.ch/jira/browse/GAUDI-1023"<< endmsg;
285  }
286 }
287 // =====================================================================
288 // The END
289 // =====================================================================
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode setProperty(const Property &p)
set the property form another property
virtual bool assign(const Property &source)=0
import the property value form the source
virtual const std::vector< Property * > & getProperties() const =0
Get list of properties.
virtual std::string toString() const =0
value -> string
const std::string & name() const
property name
Definition: Property.h:47
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
Properties m_todelete
Properties to be deleted.
Definition: PropertyMgr.h:170
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
virtual bool load(Property &dest) const =0
export the property value to the destination
return false
Definition: Bootstrap.cpp:338
Property manager helper class.
Definition: PropertyMgr.h:34
bool hasProperty(const std::string &name) const
Return true if we have a property with the given name.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:85
IInterface * m_pOuter
Interface hub reference (ApplicationMgr)
Definition: PropertyMgr.h:174
PropertyMgr(IInterface *iface=0)
constructor from the interface
Definition: PropertyMgr.cpp:54
StatusCode queryInterface(const InterfaceID &iid, void **pinterface)
Set the void** to the pointer to the requested interface of the instance.
virtual const std::string & name() const =0
Retrieve the name of the instance.
Gaudi::InterfaceId< IInterface, 0, 0 > iid
Interface ID.
Definition: IInterface.h:164
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:82
Base class used to implement the interfaces.
Definition: implements.h:133
Interface ID class.
Definition: IInterface.h:55
Properties m_properties
Collection of all declared properties.
Definition: PropertyMgr.h:166
GAUDI_API ISvcLocator * svcLocator()
RemoteProperties m_remoteProperties
Collection of all declared remote properties.
Definition: PropertyMgr.h:168
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
Definition of the basic interface.
Definition: IInterface.h:160
virtual ~PropertyMgr()
virtual destructor
Definition: PropertyMgr.cpp:83
std::pair< std::string, std::pair< IProperty *, std::string > > RemProperty
Definition: PropertyMgr.h:160
The IMessage is the interface implemented by the message service.
Definition: IMessageSvc.h:57
PropertyMgr & operator=(const PropertyMgr &)
Definition: PropertyMgr.cpp:92
StatusCode getProperty(Property *p) const
get the property
tuple end
Definition: IOTest.py:101
const std::vector< Property * > & getProperties() const
get all properties
IInterface compliant class extending IInterface with the name() method.
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:43
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
Property * declareRemoteProperty(const std::string &name, IProperty *rsvc, const std::string &rname="")
Declare a remote property.
#define UNLIKELY(x)
Definition: Kernel.h:127
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:22
list i
Definition: ana.py:128
virtual Property * clone() const =0
clone: "virtual constructor"
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:171
void assertUniqueName(const std::string &name) const
Throw an exception if the name is already present in the list of properties (see GAUDI-1023).
void toupper(std::string &s)
Property * property(const std::string &name) const
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
virtual StatusCode fromString(const std::string &value)=0
string -> value