7 #include "ioAtoms/SReader.hpp" 9 #include <fwAtomConversion/convert.hpp> 11 #include <fwAtomsBoostIO/Reader.hpp> 12 #include <fwAtomsBoostIO/types.hpp> 14 #include <fwAtomsFilter/factory/new.hpp> 15 #include <fwAtomsFilter/IFilter.hpp> 17 #include <fwAtomsPatch/PatchingManager.hpp> 19 #include <fwCom/Signal.hxx> 21 #include <fwData/Array.hpp> 22 #include <fwData/Composite.hpp> 23 #include <fwData/location/Folder.hpp> 24 #include <fwData/location/SingleFile.hpp> 26 #include <fwDataTools/helper/Composite.hpp> 28 #include <fwGui/Cursor.hpp> 29 #include <fwGui/dialog/LocationDialog.hpp> 30 #include <fwGui/dialog/MessageDialog.hpp> 32 #include <fwJobs/Aggregator.hpp> 33 #include <fwJobs/Job.hpp> 35 #include <fwMDSemanticPatch/PatchLoader.hpp> 37 #include <fwServices/macros.hpp> 39 #include <fwZip/ReadDirArchive.hpp> 40 #include <fwZip/ReadZipArchive.hpp> 42 #include <boost/algorithm/string/join.hpp> 43 #include <boost/assign/list_of.hpp> 44 #include <boost/filesystem/path.hpp> 51 static const ::fwCom::Signals::SignalKeyType JOB_CREATED_SIGNAL =
"jobCreated";
54 = ::boost::assign::map_list_of(
".xml",
"XML")
55 (
".xmlz",
"Zipped XML")
57 (
".jsonz",
"Zipped JSON");
63 m_uuidPolicy(
"Change"),
64 m_useAtomsPatcher(false),
65 m_context(
"Undefined"),
66 m_version(
"Undefined"),
69 m_sigJobCreated = newSignal< JobCreatedSignalType >( JOB_CREATED_SIGNAL );
71 for(SReader::FileExtension2NameType::value_type ext :
s_EXTENSIONS)
73 m_allowedExts.insert(m_allowedExts.end(), ext.first);
89 this->
setOutput(::fwIO::s_DATA_KEY,
nullptr);
100 m_allowedExtLabels.clear();
104 const auto archiveCfgs = config.equal_range(
"archive");
106 for (
auto it = archiveCfgs.first; it != archiveCfgs.second; ++it)
108 const std::string backend = it->second.get<std::string>(
"<xmlattr>.backend");
109 SLM_ASSERT(
"No backend attribute given in archive tag", backend !=
"");
112 const auto extCfgs = it->second.equal_range(
"extension");
114 for (
auto itExt = extCfgs.first; itExt != extCfgs.second; ++itExt)
116 const std::string extension = itExt->second.get<std::string>(
"");
117 SLM_ASSERT(
"No extension given for backend '" + backend +
"'", !extension.empty());
118 SLM_ASSERT(
"Extension must begin with '.'", extension[0] ==
'.');
120 m_customExts[extension] = backend;
121 m_allowedExtLabels[extension] = itExt->second.get(
"<xmlattr>.label",
"");
125 const auto extensionsCfg = config.get_child_optional(
"extensions");
129 m_allowedExts.clear();
131 const auto extCfgs = extensionsCfg->equal_range(
"extension");
132 for (
auto it = extCfgs.first; it != extCfgs.second; ++it)
134 const std::string ext = it->second.get<std::string>(
"");
137 FileExtension2NameType::const_iterator itKnown =
s_EXTENSIONS.find(ext);
138 FileExtension2NameType::const_iterator itCustom = m_customExts.find(ext);
140 const bool extIsKnown = (itKnown != SReader::s_EXTENSIONS.end() || itCustom != m_customExts.end());
141 SLM_ASSERT(
"Extension '" + ext +
"' is not allowed in configuration", extIsKnown);
145 m_allowedExts.insert(m_allowedExts.end(), ext);
146 m_allowedExtLabels[ext] = it->second.get(
"<xmlattr>.label",
"");
152 m_allowedExts.clear();
154 for(FileExtension2NameType::value_type ext : m_customExts)
156 m_allowedExts.insert(m_allowedExts.end(), ext.first);
159 for(SReader::FileExtension2NameType::value_type ext : SReader::s_EXTENSIONS)
161 m_allowedExts.insert(m_allowedExts.end(), ext.first);
162 m_allowedExtLabels[ext.first] = ext.second;
166 m_filter = config.get(
"filter",
"");
167 m_uuidPolicy = config.get(
"uuidPolicy", m_uuidPolicy);
171 "', available policies : 'Strict','Change' or 'Reuse'.",
172 "Strict" == m_uuidPolicy ||
"Change" == m_uuidPolicy ||
"Reuse" == m_uuidPolicy );
174 const auto patcherCfg = config.get_child_optional(
"patcher");
178 m_context = patcherCfg->get<std::string>(
"<xmlattr>.context",
"MedicalData");
179 m_version = patcherCfg->get<std::string>(
"<xmlattr>.version",
181 m_useAtomsPatcher =
true;
184 const std::string output = config.get<std::string>(
"out.<xmlattr>.key",
"");
185 if (output == ::fwIO::s_DATA_KEY )
190 SLM_ASSERT(
"'Reuse' policy is only available when data is set as 'out'", m_outputMode ||
"Reuse" != m_uuidPolicy);
199 ::fwData::Object::sptr data = this->getInOut< ::fwData::Object >(::fwIO::s_DATA_KEY);
200 if (!m_outputMode && !data)
203 data = this->getObject< ::fwData::Object >();
207 cursor.
setCursor(::fwGui::ICursor::BUSY);
211 const ::boost::filesystem::path& filePath = this->
getFile();
212 const ::boost::filesystem::path folderPath = filePath.parent_path();
213 const ::boost::filesystem::path filename = filePath.filename();
214 std::string extension = ::boost::filesystem::extension(filePath);
216 FW_RAISE_IF(
"Unable to guess file format (missing extension)", extension.empty() );
218 if(m_customExts.find(extension) != m_customExts.end())
220 extension =
"." + m_customExts[extension];
223 ::fwAtoms::Object::sptr atom;
225 const unsigned int progressBarOffset = 10;
231 runningJob.
doneWork(progressBarOffset);
234 ::fwZip::IReadArchive::sptr readArchive;
235 ::boost::filesystem::path archiveRootName;
236 ::fwAtomsBoostIO::FormatType format = ::fwAtomsBoostIO::UNSPECIFIED;
238 if ( extension ==
".json" )
240 readArchive = ::fwZip::ReadDirArchive::New(folderPath.string());
241 archiveRootName = filename;
242 format = ::fwAtomsBoostIO::JSON;
244 else if ( extension ==
".jsonz" )
246 readArchive = ::fwZip::ReadZipArchive::New(filePath.string());
247 archiveRootName =
"root.json";
248 format = ::fwAtomsBoostIO::JSON;
250 else if ( extension ==
".xml" )
252 readArchive = ::fwZip::ReadDirArchive::New(folderPath.string());
253 archiveRootName = filename;
254 format = ::fwAtomsBoostIO::XML;
256 else if ( extension ==
".xmlz" )
258 readArchive = ::fwZip::ReadZipArchive::New(filePath.string());
259 archiveRootName =
"root.xml";
260 format = ::fwAtomsBoostIO::XML;
264 FW_RAISE(
"This file extension '" << extension <<
"' is not managed" );
268 atom = ::fwAtoms::Object::dynamicCast( reader.read( readArchive, archiveRootName, format ) );
270 FW_RAISE_IF(
"Invalid atoms file :'" << filePath <<
"'", !atom );
272 runningJob.
doneWork(progressBarOffset);
287 runningJob.
doneWork(progressBarOffset);
290 if ( m_useAtomsPatcher )
292 FW_RAISE_IF(
"Unable to load data, found '" << atom->getMetaInfo(
"context")
293 <<
"' context, but '" << m_context <<
295 atom->getMetaInfo(
"context") != m_context);
298 atom = globalPatcher.transformTo( m_version );
301 if(!m_filter.empty())
303 ::fwAtomsFilter::IFilter::sptr filter = ::fwAtomsFilter::factory::New(m_filter);
304 OSLM_ASSERT(
"Failed to create IFilter implementation '" << m_filter <<
"'", filter);
310 ::fwData::Object::sptr newData;
316 runningJob.
doneWork(progressBarOffset);
321 if(
"Strict" == m_uuidPolicy)
325 else if(
"Reuse" == m_uuidPolicy)
338 jobs->add(fileReadingJob);
339 jobs->add(patchingJob);
340 jobs->add(atomToDataJob);
342 m_sigJobCreated->emit(jobs);
346 if(jobs->getState() == ::fwJobs::IJob::CANCELED)
351 FW_RAISE_IF(
"Unable to load '" << filePath <<
"' : invalid data.", !newData );
355 this->
setOutput(::fwIO::s_DATA_KEY, newData);
359 SLM_ASSERT(
"'" + ::fwIO::s_DATA_KEY +
"' key is not defined", data);
361 FW_RAISE_IF(
"Unable to load '" << filePath
362 <<
"' : trying to load a '" << newData->getClassname()
363 <<
"' where a '" << data->getClassname() <<
"' was expected",
364 newData->getClassname() != data->getClassname() );
371 ::fwData::Array::dynamicCast(data)->swap( ::fwData::Array::dynamicCast(newData) );
375 data->shallowCopy(newData);
378 this->notificationOfUpdate();
381 catch( std::exception& e )
385 ::fwGui::dialog::MessageDialog::CRITICAL);
390 ::fwGui::dialog::MessageDialog::CRITICAL);
393 cursor.setDefaultCursor();
407 void SReader::notificationOfUpdate()
409 ::fwData::Object::sptr
object = this->getInOut< ::fwData::Object >(::fwIO::s_DATA_KEY);
413 object = this->getObject< ::fwData::Object >();
426 static ::boost::filesystem::path _sDefaultPath;
431 dialogFile.
setType(::fwGui::dialog::ILocationDialog::SINGLE_FILE);
432 dialogFile.
setOption(::fwGui::dialog::ILocationDialog::READ);
433 dialogFile.
setOption(::fwGui::dialog::LocationDialog::FILE_MUST_EXIST);
435 dialogFile.
addFilter(
"Medical data",
"*" + ::boost::algorithm::join(m_allowedExts,
" *"));
437 for(
const std::string& ext : m_allowedExts)
439 dialogFile.
addFilter(m_allowedExtLabels[ext],
"*" + ext);
442 ::fwData::location::SingleFile::sptr result
443 = ::fwData::location::SingleFile::dynamicCast( dialogFile.
show() );
447 _sDefaultPath = result->getPath();
448 this->
setFile( _sDefaultPath );
449 dialogFile.
saveDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath.parent_path()) );
#define FW_DEPRECATED_KEY(newKey, access, version)
Use this macro when deprecating a service key to warn the developer.
virtual FWGUI_API void setCursor(::fwGui::ICursor::CursorType cursor) override
Set the cursor.
This policy throws an exception if the loaded uuid is not available.
IOATOMS_API void configuring() override
Parse the configuration.
IOATOMS_API void starting() override
Does nothing.
std::string m_windowTitle
Title of the window that will open when the configureWithIHM slot is called.
FWJOBS_API void doneWork(std::uint64_t units)
Setter on done work units.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
Class allowing to block a Connection.
IOATOMS_API::fwIO::IOPathType getIOPathType() const override
Returns managed path type, here service manages only single file.
FWIO_API bool hasLocationDefined() const
Returns if a location has been defined ( by the configuration process or directly by user ) ...
virtual FWIO_API void configuring() override
This method proposes to parse xml configuration to retrieve file/files/folder paths.
static FWGUI_API IMessageDialog::Buttons showMessageDialog(const std::string &title, const std::string &message,::fwGui::dialog::IMessageDialog::Icons icon=INFO)
std::map< std::string, std::string > FileExtension2NameType
Maps file extension to format name.
static const std::string & classname()
return object's classname without its namespace, i.e. BaseObject
virtual FWGUI_API void setDefaultLocation(::fwData::location::ILocation::sptr loc) override
Set the initial location for the dialog.
FWGUI_API::fwGui::dialog::ILocationDialog & setOption(::fwGui::dialog::ILocationDialog::Options option) override
allow to set option to the file dialog mode=READ/WRITE, check=FILE_MUST_EXIST
FWGUI_API::fwData::location::ILocation::sptr show() override
Display the dialog.
FWGUI_API void addFilter(const std::string &filterName, const std::string &wildcardList) override
specify some filtering when browsing files:
IOATOMS_API void stopping() override
Does nothing.
This policy changes data's uuid if it already exists.
std::shared_ptr< ::fwJobs::Aggregator > sptr
Aggregator container type.
FWJOBS_API const bool & cancelRequested() const
Returns the job canceling status.
FWIO_APIconst::boost::filesystem::path & getFile() const
Returns the file path set by the user or set during service configuration.
UpdateSlotType::sptr m_slotUpdate
Slot to call update method.
This class encapsulate a task that will report it's progression The embeded task will be run at most ...
FWSERVICES_API void setOutput(const ::fwServices::IService::KeyType &key, const ::fwData::Object::sptr &object, size_t index=0)
Register an output object at a given key in the OSR, replacing it if it already exists.
static FWMDSEMANTICPATCH_API std::string getCurrentVersion()
Returns current MedicalData version.
FWIO_API void setFile(const ::boost::filesystem::path &file)
Sets file path.
#define OSLM_ERROR(message)
Reader service API. It manages extension points definition and extension configuration.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
IOATOMS_API void updating() override
Tests file extension, applies the good atom reader, and converts atom in fwData::Composite.
static const FileExtension2NameType s_EXTENSIONS
Managed file extensions.
This policy reuses the data associated with an existing uuid.
Base class for each data object.
Atoms reader. Service to load data from Atoms format.
IOPathType
IOPathType defines different type of paths used by service readers/writers.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
static FWJOBS_API sptr New(const std::string &name, Task task, const std::shared_ptr< ::fwThread::Worker > &worker=nullptr)
Construct a new job and return a smart pointer of it.
FWGUI_API void setTitle(const std::string &title) override
Set the title for the dialog.
Defines the generic file/folder selector dialog for IHM.
Defines the generic cursor for IHM. Use the Delegate design pattern.
std::shared_ptr< ::fwThread::Worker > m_associatedWorker
Associated worker.
FWJOBS_API void done()
Set done work units to total work units.
Contains services to read and write data via atom conversion.
FWGUI_API void setType(::fwGui::dialog::ILocationDialog::Types type) override
Set the type of location for the dialog (SINGLE_FILE, FORLDER, MULTI_FILES)
FWIO_API void clearLocations()
Clear any location set by the setFile/setFiles/setFolder setter.
FWGUI_API void saveDefaultLocation(::fwData::location::ILocation::sptr loc) override
Save the specified default location for the dialog in preferences (if available)
static FWJOBS_API sptr New(const std::string &name="")
Create a new Aggregator smart pointer.
std::shared_ptr< ::fwJobs::Job > sptr
Task type.
IOATOMS_API void configureWithIHM() override
Propose to choose a medical data file (*.json,*.jsonz,*.xml or *.xmlz)
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.