fw4spl
GetObject.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2016.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include <boost/utility/enable_if.hpp>
8 
9 #include <fwData/camp/mapper.hpp>
10 #include <fwData/Float.hpp>
11 #include <fwData/Boolean.hpp>
12 #include <fwData/String.hpp>
13 #include <fwData/Integer.hpp>
14 
15 #include "fwDataCamp/visitor/GetObject.hpp"
16 
17 #include "fwDataCamp/exception/NullPointer.hpp"
18 #include "fwDataCamp/exception/ObjectNotFound.hpp"
19 
20 namespace fwDataCamp
21 {
22 
23 namespace visitor
24 {
25 
26 struct GetCampValueVisitor : public camp::ValueVisitor< ::fwData::Object::sptr >
27 {
28  std::string m_subObjPath;
29  PathVisitor::sptr m_pathVisitor;
30 
31  GetCampValueVisitor( const std::string& subObjPath, PathVisitor::sptr pathVisitor) :
32  m_subObjPath(subObjPath), m_pathVisitor(pathVisitor)
33  {
34  }
35 
36  ::fwData::Object::sptr operator()(camp::NoType value)
37  {
38  SLM_FATAL("Enter in void GetCampValueVisitor()(camp::NoType value) : case not managed");
39  ::fwData::Object::sptr val;
40  return val;
41  }
42 
43  ::fwData::Object::sptr operator()(bool value)
44  {
45  return ::fwData::Boolean::New(value);
46  }
47 
48  ::fwData::Object::sptr operator()(long value)
49  {
50  return ::fwData::Integer::New(value);
51  }
52 
53  ::fwData::Object::sptr operator()(double value)
54  {
55  return ::fwData::Float::New(value);
56  }
57 
58  ::fwData::Object::sptr operator()(const std::string& value)
59  {
60  return ::fwData::String::New(value);
61  }
62 
63  ::fwData::Object::sptr operator()(const camp::EnumObject& value)
64  {
65  SLM_FATAL("Enter in void GetCampValueVisitor()(camp::EnumObject value) : case not managed");
66  ::fwData::Object::sptr val;
67  return val;
68  }
69 
70  ::fwData::Object::sptr operator()(const camp::UserObject& value)
71  {
72  ::fwData::Object::sptr val;
73  const camp::Class& metaclass = value.getClass();
74  if ( value.pointer() )
75  {
76  if ( !m_subObjPath.empty() )
77  {
78  OSLM_DEBUG( "visit class= '" << metaclass.name() << "' ( classname = '"<< value.call(
79  "classname") <<"' )" );
80  ::fwData::Object* ptr = value.get< ::fwData::Object* >();
81  ::fwDataCamp::visitor::GetObject visitor( ptr->getSptr(), m_subObjPath );
82  val = visitor.get();
83  m_pathVisitor->merge(visitor.getPathVisitor());
84  }
85  else
86  {
87  ::fwData::Object* ptr = value.get< ::fwData::Object* >();
88  val = ptr->getSptr();
89  }
90  }
91  else
92  {
93  FW_RAISE_EXCEPTION( ::fwDataCamp::exception::NullPointer(
94  "Object '" + metaclass.name() + "' not instanced.")
95  );
96  }
97 
98  return val;
99  }
100 };
101 
102 //-----------------------------------------------------------------------------
103 
104 GetObject::GetObject( ::fwData::Object::csptr object, const std::string& subObjPath ) :
105  m_object(object), m_subObjPath(subObjPath),
106  m_newSubObjPath(subObjPath),
107  m_pathVisitor(std::make_shared<PathVisitor>(subObjPath))
108 {
109  SLM_FATAL_IF("Cannot retrieve an object with an empty path.", subObjPath.empty());
110  m_campObj = camp::UserObject( *object );
111  m_propertyName = this->getNextPropertyName();
112 }
113 
114 //-----------------------------------------------------------------------------
115 
116 GetObject::~GetObject()
117 {
118 }
119 
120 //-----------------------------------------------------------------------------
121 
122 void GetObject::visit(const camp::SimpleProperty& property)
123 {
124  SLM_TRACE_FUNC();
125  const std::string name ( property.name() );
126  OSLM_DEBUG( "SimpleProperty name =" << name );
127  if( name == m_propertyName )
128  {
129  m_pathVisitor->addObject(name);
130  OSLM_DEBUG( "Ok SimpleProperty name =" << name );
131  ::camp::Value elemValue = property.get( m_campObj );
132  GetCampValueVisitor visitor(m_newSubObjPath, m_pathVisitor);
133  m_subObject = elemValue.visit( visitor );
134  }
135 }
136 
137 //-----------------------------------------------------------------------------
138 
139 void GetObject::visit(const camp::EnumProperty& property)
140 {
141  SLM_TRACE_FUNC();
142  OSLM_FATAL_IF( "EnumProperty is not still managed : name =" << property.name(),
143  property.name() == m_propertyName );
144 }
145 
146 //-----------------------------------------------------------------------------
147 
148 void GetObject::visit(const camp::MapProperty& property)
149 {
150  SLM_TRACE_FUNC();
151  const std::string name ( property.name() );
152  OSLM_DEBUG( "MapProperty name =" << name);
153  if( name == m_propertyName )
154  {
155  m_pathVisitor->addObject(name);
156  OSLM_DEBUG( "Ok MapProperty name =" << name );
157  std::string key = this->getNextPropertyName();
158 
159  std::pair< ::camp::Value, ::camp::Value > value;
160  std::string mapKey;
161  for (unsigned int var = 0; var < property.getSize(m_campObj); ++var)
162  {
163  value = property.getElement(m_campObj, var);
164  mapKey = value.first.to< std::string >();
165  if ( key == mapKey )
166  {
167  m_pathVisitor->addObject(key);
168  GetCampValueVisitor visitor( m_newSubObjPath, m_pathVisitor );
169  m_subObject = value.second.visit( visitor );
170  }
171  }
172  }
173 }
174 
175 //-----------------------------------------------------------------------------
176 
177 void GetObject::visit(const camp::ArrayProperty& property)
178 {
179  SLM_TRACE_FUNC();
180  const std::string name ( property.name() );
181  OSLM_DEBUG( "ArrayProperty name =" << name );
182  if( name == m_propertyName )
183  {
184  m_pathVisitor->addObject(name);
185  OSLM_DEBUG( "Ok ArrayProperty name =" << name );
186  std::string key = this->getNextPropertyName();
187 
188  size_t index = ::boost::lexical_cast< size_t >( key );
189 
190  m_pathVisitor->addObject(key);
191 
192  // If the index is out of range, camp throws an exception
193  // We need to catch it because this means we failed to reach the object
194  ::camp::Value elemValue;
195  try
196  {
197  elemValue = property.get( m_campObj, index );
198  }
199  catch(::camp::OutOfRange e)
200  {
201  FW_RAISE_EXCEPTION_MSG( ::fwDataCamp::exception::NullPointer,
202  "Index '" << index << "' not found in array property '" << name << "'.");
203  }
204 
205  GetCampValueVisitor visitor(m_newSubObjPath, m_pathVisitor);
206  m_subObject = elemValue.visit( visitor );
207  }
208 }
209 
210 //-----------------------------------------------------------------------------
211 
212 void GetObject::visit(const camp::UserProperty& property)
213 {
214  SLM_TRACE_FUNC();
215  const std::string name ( property.name() );
216  OSLM_DEBUG( "UserProperty name =" << name );
217  if( name == m_propertyName )
218  {
219  m_pathVisitor->addObject(name);
220  OSLM_DEBUG( "Ok UserProperty name =" << name );
221  ::camp::Value elemValue = property.get( m_campObj );
222  GetCampValueVisitor visitor(m_newSubObjPath, m_pathVisitor);
223  m_subObject = elemValue.visit( visitor );
224  }
225 }
226 
227 //-----------------------------------------------------------------------------
228 
229 void GetObject::visit(const camp::Function& function)
230 {
231  SLM_TRACE_FUNC();
232 }
233 
234 //-----------------------------------------------------------------------------
235 
236 std::string GetObject::getNextPropertyName()
237 {
238  SLM_FATAL_IF( "Path is empty.", m_newSubObjPath.empty() );
239  size_t dotPos = m_newSubObjPath.find(".");
240  std::string nextItem;
241  if ( dotPos != std::string::npos )
242  {
243  nextItem = m_newSubObjPath.substr( 0, dotPos );
244  m_newSubObjPath = m_newSubObjPath.substr( dotPos+1 );
245  }
246  else
247  {
248  nextItem = m_newSubObjPath;
249  m_newSubObjPath = "";
250  }
251  OSLM_DEBUG( "nextItem = " << nextItem );
252  OSLM_DEBUG( "m_newSubObjPath = " << m_newSubObjPath );
253  return nextItem;
254 }
255 
256 //-----------------------------------------------------------------------------
257 
258 ::fwData::Object::sptr GetObject::get()
259 {
260  const camp::Class& camClass = ::camp::classByName( m_object->getClassname() );
261  camClass.visit( *this );
262  return m_subObject;
263 }
264 
265 //-----------------------------------------------------------------------------
266 
268 {
269  return m_pathVisitor->allObjectsFound();
270 }
271 
272 //-----------------------------------------------------------------------------
273 
274 } // visitor
275 
276 } // fwDataCamp
277 
FWDATACAMP_API::fwData::Object::sptr get()
Launches visit process and returns the object designated by m_subObjPath.
Definition: GetObject.cpp:258
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
STL namespace.
Check if object introspection process mathes a given path.
Definition: GetObject.hpp:26
#define SLM_FATAL(message)
Definition: spyLog.hpp:283
This namespace contains data object descriptions used for introspection.
PathVisitor::sptr m_pathVisitor
Path visitor.
Definition: GetObject.hpp:151
Base class for each data object.
#define SLM_FATAL_IF(message, cond)
Definition: spyLog.hpp:287
FWDATACAMP_API GetObject(::fwData::Object::csptr object, const std::string &subObjPath)
Constructor.
Definition: GetObject.cpp:104
FWDATACAMP_API bool objectsFound() const
Returns true if introspection process matched child object path.
Definition: GetObject.cpp:267
#define OSLM_FATAL_IF(message, cond)
Definition: spyLog.hpp:289
This class is an helper to introspect a data and find an object (contained into this data) from a nor...
Definition: GetObject.hpp:80
#define OSLM_DEBUG(message)
Definition: spyLog.hpp:241