fw4spl
DataVisitor.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 "fwAtomConversion/DataVisitor.hpp"
8 
9 #include "fwAtomConversion/convert.hpp"
10 #include "fwAtomConversion/exception/ConversionNotManaged.hpp"
11 #include "fwAtomConversion/mapper/factory/new.hpp"
12 
13 #include <fwAtoms/Base.hpp>
14 #include <fwAtoms/Blob.hpp>
15 #include <fwAtoms/Boolean.hpp>
16 #include <fwAtoms/Map.hpp>
17 #include <fwAtoms/Numeric.hpp>
18 #include <fwAtoms/Numeric.hxx>
19 #include <fwAtoms/Sequence.hpp>
20 #include <fwAtoms/String.hpp>
21 
22 #include <fwCamp/Mapper/ValueMapper.hpp>
23 #include <fwCamp/factory/new.hpp>
24 
25 #include <fwData/Array.hpp>
26 #include <fwData/camp/mapper.hpp>
27 
28 #include <fwDataCamp/Version.hpp>
29 
30 #include <fwMedDataCamp/Version.hpp>
31 
32 #include <fwMemory/BufferObject.hpp>
33 
34 #include <fwTools/UUID.hpp>
35 
36 #include <boost/utility/enable_if.hpp>
37 
38 #include <camp/class.hpp>
39 
40 #include <string>
41 
42 
43 namespace fwAtomConversion
44 {
45 
46 static int dataCampVersion = ::fwDataCamp::Version::s_CURRENT_VERSION; // Hack to force link with fwDataCamp
47 static int medDataCampVersion = ::fwMedDataCamp::Version::s_CURRENT_VERSION; // Hack to force link with fwMedDataCamp
48 
49 const std::string DataVisitor::CLASSNAME_METAINFO = "CLASSNAME_METAINFO";
50 const std::string DataVisitor::ID_METAINFO = "ID_METAINFO";
51 
52 //-----------------------------------------------------------------------------
53 
54 struct DataConversionValueVisitor : public ::camp::ValueVisitor< ::fwAtoms::Base::sptr >
55 {
56  DataVisitor::AtomCacheType& m_cache;
57 
58  DataConversionValueVisitor( DataVisitor::AtomCacheType& cache ) : m_cache(cache)
59  {
60  }
61 
62  ::fwAtoms::Base::sptr operator()(camp::NoType value)
63  {
64  FW_RAISE_EXCEPTION( exception::ConversionNotManaged(
65  "Enter in void GetCampValueVisitor()(camp::NoType value) : case not managed" ) );
66  ::fwAtoms::Base::sptr val;
67  return val;
68  }
69 
70  ::fwAtoms::Base::sptr operator()(bool value)
71  {
72  return ::fwAtoms::Boolean::New( value );
73  }
74 
75  ::fwAtoms::Base::sptr operator()(long value)
76  {
77  return ::fwAtoms::Numeric::New( value );
78  }
79 
80  ::fwAtoms::Base::sptr operator()(double value)
81  {
82  return ::fwAtoms::Numeric::New( value );
83  }
84 
85  ::fwAtoms::Base::sptr operator()(std::string value)
86  {
87  return ::fwAtoms::String::New( value );
88  }
89 
90  ::fwAtoms::Base::sptr operator()(const camp::EnumObject& value)
91  {
92  return ::fwAtoms::String::New( value.name() );
93  }
94 
95  ::fwAtoms::Base::sptr operator()(const camp::UserObject& value)
96  {
97  ::fwAtoms::Base::sptr baseObj;
98 
99  if ( value.pointer() )
100  {
101  DataVisitor::ClassnameType classname = value.call("classname").to<std::string>();
102 
103  if( classname == "::fwMemory::BufferObject" )
104  {
105  ::fwMemory::BufferObject* ptr = value.get< ::fwMemory::BufferObject* >();
106  baseObj = ::fwAtoms::Blob::New( ptr->getSptr() );
107  }
108  else
109  {
110  // get fwData object
111  ::fwData::Object* ptr = value.get< ::fwData::Object* >();
112  ::fwData::Object::sptr dataObj = ptr->getSptr();
113 
114  baseObj = ::fwAtomConversion::convert( dataObj, m_cache );
115  }
116  }
117 
118  return baseObj;
119  }
120 };
121 
122 //-----------------------------------------------------------------------------
123 
124 DataVisitor::DataVisitor( ::fwData::Object::sptr dataObj, AtomCacheType& cache )
125  : m_campDataObj( dataObj.get() ), m_cache( cache )
126 {
127 
128  // Create atom object
129  m_atomObj = ::fwAtoms::Object::New();
130  ClassnameType classname = m_campDataObj.call("classname").to<std::string>();
131  m_atomObj->setMetaInfo( DataVisitor::CLASSNAME_METAINFO, classname );
132  ::fwTools::UUID::UUIDType uuid = ::fwTools::UUID::get(dataObj);
133  m_atomObj->setMetaInfo( DataVisitor::ID_METAINFO, uuid );
134  m_cache[uuid] = m_atomObj;
135 
136  // Fill atom object with tag
137  const camp::Class& metaclass = ::camp::classByName(classname);
138  std::size_t tagCount = metaclass.tagCount();
139  for ( std::size_t i = 0; i < tagCount; ++i )
140  {
141  const ::camp::Value& tag = metaclass.tagId(i);
142  const ::camp::Value& val = metaclass.tag(tag);
143  m_atomObj->setMetaInfo( tag.to< std::string >(), val.to< std::string >() );
144  }
145 
146 }
147 
148 //-----------------------------------------------------------------------------
149 
151 {
152 }
153 
154 //-----------------------------------------------------------------------------
155 
156 void DataVisitor::visit(const camp::SimpleProperty& property)
157 {
158  const std::string& name ( property.name() );
159  const ::camp::Value& val ( property.get( m_campDataObj ) );
160 
162  if( val.type() != camp::intType )
163  {
164  DataConversionValueVisitor visitor(m_cache);
165  ::fwAtoms::Base::sptr atom = val.visit( visitor );
166  m_atomObj->setAttribute( name, atom );
167  }
168  else
169  {
170  ::fwAtoms::Base::sptr atom = ::fwAtoms::Numeric::New( val.to<long>() );
171  m_atomObj->setAttribute( name, atom );
172  }
173 }
174 
175 //-----------------------------------------------------------------------------
176 
177 void DataVisitor::visit(const camp::EnumProperty& property)
178 {
179  const std::string& name ( property.name() );
180  const ::camp::Value& val ( property.get( m_campDataObj ) );
181 
182  DataConversionValueVisitor visitor(m_cache);
183  ::fwAtoms::Base::sptr atom = val.visit( visitor );
184  m_atomObj->setAttribute( name, atom );
185 }
186 
187 //-----------------------------------------------------------------------------
188 
190 {
191  const std::string name ( property.name() );
192  ::fwAtoms::Map::sptr atom = ::fwAtoms::Map::New();
193 
194  std::pair< ::camp::Value, ::camp::Value > value;
195  ::fwAtoms::Base::sptr valAtom;
196  ::camp::Value first;
197  ::camp::Value second;
198 
199  const size_t size = property.getSize( m_campDataObj );
200  for (size_t index = 0; index < size; ++index)
201  {
202  value = property.getElement(m_campDataObj, index);
203 
204  first = value.first;
205  second = value.second;
206 
207  DataConversionValueVisitor valVisitor(m_cache);
208  valAtom = second.visit( valVisitor );
209 
210  FW_RAISE_EXCEPTION_IF(
211  exception::ConversionNotManaged("Not managed type for map key (only support string, int and real)"),
212  first.type() != ::camp::stringType &&
213  first.type() != ::camp::intType &&
214  first.type() != ::camp::realType );
215  atom->insert( first.to< std::string >(), valAtom );
216  }
217 
218  m_atomObj->setAttribute( name, atom );
219 }
220 
221 //-----------------------------------------------------------------------------
222 
223 void DataVisitor::visit(const camp::ArrayProperty& property)
224 {
225  const std::string name ( property.name() );
226  ::fwAtoms::Sequence::sptr atom = ::fwAtoms::Sequence::New();
227 
228  ::camp::Value val;
229  ::fwAtoms::Base::sptr valAtom;
230  const size_t size = property.size( m_campDataObj );
231  for (size_t index = 0; index < size; ++index)
232  {
233  val = property.get( m_campDataObj, index );
234 
235  DataConversionValueVisitor visitor(m_cache);
236  valAtom = val.visit( visitor );
237  atom->push_back( valAtom );
238  }
239 
240  m_atomObj->setAttribute( name, atom );
241 }
242 
243 //-----------------------------------------------------------------------------
244 
245 void DataVisitor::visit(const camp::UserProperty& property)
246 {
247  const std::string& name ( property.name() );
248  const ::camp::Value& val ( property.get( m_campDataObj ) );
249 
250  DataConversionValueVisitor visitor(m_cache);
251  ::fwAtoms::Base::sptr atom = val.visit( visitor );
252  m_atomObj->setAttribute( name, atom );
253 
254 }
255 
256 //-----------------------------------------------------------------------------
257 
258 ::fwAtoms::Object::sptr DataVisitor::getAtomObject() const
259 {
260  return this->m_atomObj;
261 }
262 
263 } // fwAtomConversion
This namespace contains the necessary class for fwData <-> fwAtoms conversion.
Throw this exception when a conversion between data and atom is not managed (error message explains t...
FWATOMCONVERSION_API std::shared_ptr< ::fwAtoms::Object > getAtomObject() const
Returns the atom object (representation of dataObj in fwAtoms) . Calls this methods after the visit...
static FWATOMCONVERSION_API const std::string CLASSNAME_METAINFO
Key of the meta info to store data object classname.
Definition: DataVisitor.hpp:48
static FWTOOLS_API const UUIDType & get(::fwTools::Object::sptr object)
Return an uuid to the given object : if no one previously set then generate a new one...
Definition: UUID.cpp:50
static FWATOMCONVERSION_API const std::string ID_METAINFO
Key of the meta info to store data object ID.
Definition: DataVisitor.hpp:50
static Numeric::sptr New(T value)
Build a new numeric type.
Definition: Numeric.hxx:77
Base class for each data object.
virtual FWATOMCONVERSION_API ~DataVisitor()
Destructor. Does nothing.
Define Base class for FW4SPL buffers.
FWATOMCONVERSION_API DataVisitor(std::shared_ptr< ::fwData::Object >dataObj, AtomCacheType &cache)
Constructor. Initializes atom object and store it in the cache.
FWATOMCONVERSION_API void visit(const camp::SimpleProperty &property)
Visit simple property.
static FWATOMS_API Blob::sptr New(::fwMemory::BufferObject::sptr buffer)
create a new Blob shared ptr.
Definition: Blob.cpp:17