All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  constexpr struct NoCaseCmp_t
27  {
28  inline bool operator() ( const std::string& v1 ,
29  const std::string& v2 ) const
30  {
31  return v1.size() == v2.size() &&
32  std::equal(std::begin(v1),std::end(v1),std::begin(v2),
33  [](char c1, char c2) {
34  return toupper(c1) == toupper(c2);
35  } );
36  }
37  } noCaseCmp {} ;
38  // ==========================================================================
40  struct PropByName
41  {
42  std::string m_name ;
43 
44  inline bool operator() ( const Property* p ) const
45  { return p && noCaseCmp( p->name() , m_name ) ; }
46  } ;
47  // ==========================================================================
48 }
49 // ====================================================================
50 // constructor from the interface
51 // ====================================================================
53  : m_pOuter ( iface )
54 {
55  addRef(); // initial reference count set to 1
56 }
57 // ====================================================================
58 // Declare a remote property
59 // ====================================================================
61 ( const std::string& name ,
62  IProperty* rsvc ,
63  const std::string& rname )
64 {
65  if ( !rsvc ) { return nullptr ; }
66  const std::string& nam = rname.empty() ? name : rname ;
67  Property* p = property ( nam , rsvc->getProperties() ) ;
68  m_remoteProperties.emplace_back ( name , std::make_pair( rsvc , nam ) ) ;
69  return p ;
70 }
71 // ====================================================================
72 // get the property by name form the proposed list
73 // ====================================================================
75 ( const std::string& name ,
76  const std::vector<Property*>& props ) const
77 {
78  auto it = std::find_if( props.begin(), props.end(), PropByName{ name } ) ;
79  return ( it != props.end() ) ? *it : nullptr; // RETURN
80 }
81 // ====================================================================
82 // retrieve the property by name
83 // ====================================================================
85 ( const std::string& name ) const
86 {
87  // local property ?
88  Property* lp = property ( name , m_properties ) ;
89  if ( lp ) { return lp ; } // RETURN
90  // look for remote property
91  for ( const auto& it : m_remoteProperties )
92  {
93  if ( !noCaseCmp(it.first,name) ) { continue ; } // CONTINUE
94  const IProperty* p = it.second.first ;
95  if ( !p ) { continue ; } // CONTINUE
96  return property ( it.second.second , p->getProperties() ) ; // RETURN
97  }
98  return nullptr ; // RETURN
99 }
100 // ====================================================================
101 /* set a property from another property
102  * Implementation of IProperty::setProperty
103  */
104 // =====================================================================
106 {
107  Property* pp = property( p.name() ) ;
108  try
109  { if ( pp && pp->assign(p) ) { return StatusCode::SUCCESS ; } } // RETURN
110  catch(...) { }
111  //
112  return StatusCode::FAILURE;
113 }
114 // ====================================================================
115 /* set a property from the stream
116  * Implementation of IProperty::setProperty
117  */
118 // =====================================================================
120 PropertyMgr::setProperty( const std::string& i )
121 {
122  std::string name ;
123  std::string value ;
124  StatusCode sc = Gaudi::Parsers::parse( name , value , i ) ;
125  if ( sc.isFailure() ) { return sc ; }
126  return setProperty ( name , value ) ;
127 }
128 // =====================================================================
129 /* set a property from the string
130  * Implementation of IProperty::setProperty
131  */
132 // =====================================================================
134 PropertyMgr::setProperty( const std::string& n, const std::string& v )
135 {
136  Property* p = property( n ) ;
137  return ( p && p->fromString(v) ) ? StatusCode::SUCCESS : StatusCode::FAILURE ;
138 }
139 // =====================================================================
140 /* Retrieve the value of a property
141  * Implementation of IProperty::getProperty
142  */
143 // =====================================================================
145 {
146  try
147  {
148  const Property* pp = property( p->name() ) ;
149  if ( pp && pp->load(*p) ) return StatusCode::SUCCESS; // RETURN
150  }
151  catch ( ... ) { }
152  return StatusCode::FAILURE ; // RETURN
153 }
154 // =====================================================================
155 /* Get the property by name
156  * Implementation of IProperty::getProperty
157  */
158 // =====================================================================
159 const Property& PropertyMgr::getProperty( const std::string& name) const
160 {
161  const Property* p = property( name ) ;
162  if ( !p ) throw std::out_of_range( "Property "+name+" not found." ); // Not found
163  return *p ; // RETURN
164 }
165 // =====================================================================
166 /* Get the property by name
167  * Implementation of IProperty::getProperty
168  */
169 // =====================================================================
171 ( const std::string& n ,
172  std::string& v ) const
173 {
174  // get the property
175  const Property* p = property( n ) ;
176  if ( !p ) { return StatusCode::FAILURE ; }
177  // convert the value into the string
178  v = p->toString() ;
179  //
180  return StatusCode::SUCCESS ;
181 }
182 // =====================================================================
183 // Implementation of IProperty::getProperties
184 // =====================================================================
185 const std::vector<Property*>&
187 // =====================================================================
188 // Implementation of IInterface::queryInterface
189 // =====================================================================
190 StatusCode PropertyMgr::queryInterface(const InterfaceID& iid, void** pinterface) {
191  // try local interfaces
192  StatusCode sc= base_class::queryInterface(iid, pinterface);
193  if (sc.isSuccess()) return sc;
194  // fall back on the owner
195  return m_pOuter ? m_pOuter->queryInterface(iid, pinterface)
196  : sc; // FAILURE
197 }
198 // =====================================================================
199 // Implementation of IProperty::hasProperty
200 // =====================================================================
201 bool PropertyMgr::hasProperty(const std::string& name) const {
202  return any_of(begin(m_properties), end(m_properties),
203  [&name](const Property* prop) {
204  return noCaseCmp(prop->name(), name);
205  });
206 }
207 void PropertyMgr::assertUniqueName(const std::string& name) const {
208  if (UNLIKELY(hasProperty(name))) {
209  auto owner = SmartIF<INamedInterface>( m_pOuter );
210  auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>("MessageSvc");
211  MsgStream log(msgSvc, owner ? owner->name() : "PropertyMgr" );
212  log << MSG::WARNING
213  << "duplicated property name '" << name
214  << "', see https://its.cern.ch/jira/browse/GAUDI-1023"<< endmsg;
215  }
216 }
217 // =====================================================================
218 // The END
219 // =====================================================================
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
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:45
StatusCode setProperty(const Property &p) override
set the property form another property
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
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
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
IInterface * m_pOuter
Interface hub reference (ApplicationMgr)
Definition: PropertyMgr.h:180
virtual const std::string & name() const =0
Retrieve the name of the instance.
StatusCode getProperty(Property *p) const override
get the property
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:78
Interface ID class.
Definition: IInterface.h:30
Properties m_properties
Collection of all declared properties.
Definition: PropertyMgr.h:174
GAUDI_API ISvcLocator * svcLocator()
unsigned long addRef() override
Reference Interface instance.
Definition: implements.h:44
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Definition of the basic interface.
Definition: IInterface.h:234
const std::vector< Property * > & getProperties() const override
get all properties
The IMessage is the interface implemented by the message service.
Definition: IMessageSvc.h:57
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
bool hasProperty(const std::string &name) const override
Return true if we have a property with the given name.
#define UNLIKELY(x)
Definition: Kernel.h:126
Property * declareRemoteProperty(const std::string &name, IProperty *rsvc, const std::string &rname="")
Declare a remote property.
Definition: PropertyMgr.cpp:61
StatusCode queryInterface(const InterfaceID &ti, void **pp) override
Implementation of IInterface::queryInterface.
Definition: implements.h:22
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:21
list i
Definition: ana.py:128
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)
PropertyMgr(IInterface *iface=nullptr)
constructor from the interface
Definition: PropertyMgr.cpp:52
Property * property(const std::string &name) const
Definition: PropertyMgr.cpp:85
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