diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx index 968ec2a5fff7a52fb1aa9292a7b85aaf9a4728c6..4e3b75a54835bd4fdd132f431fecc2336806d0fe 100644 --- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx +++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx @@ -1578,7 +1578,7 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) if (driverShortName == "NOT-FOUND") { itkExceptionMacro( - << "GDAL Writing failed : the image file name '" << m_FileName.c_str() << "' is not recognized by GDAL."); + << "GDAL Writing failed: the image file name '" << m_FileName.c_str() << "' is not recognized by GDAL."); } if (m_CanStreamWrite) @@ -1664,9 +1664,7 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) if (m_Dataset.IsNull()) { - itkExceptionMacro( - << "GDAL Writing failed : Impossible to create the image file name '" - << m_FileName << "' : " << CPLGetLastErrorMsg() ); + itkExceptionMacro(<< CPLGetLastErrorMsg()); } /*----------------------------------------------------------------------*/ diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.h b/Modules/IO/ImageIO/include/otbImageFileReader.h index daf6c58e800fc4c14bccb519edc9dcfc47400324..631f9d7dc27fdda1020a734086e71b95607f7786 100644 --- a/Modules/IO/ImageIO/include/otbImageFileReader.h +++ b/Modules/IO/ImageIO/include/otbImageFileReader.h @@ -54,19 +54,14 @@ public: /** Constructor. */ ImageFileReaderException(const char *file, unsigned int line, - const char* message = "Error in IO", - const char* loc = "Unknown") : - ExceptionObject(file, line, message, loc) + const std::string& desc = "", + const std::string& filename = "") : + ExceptionObject(file, line, desc), + m_Filename(filename) { } - /** Constructor. */ - ImageFileReaderException(const std::string &file, unsigned int line, - const char* message = "Error in IO", - const char* loc = "Unknown") : - ExceptionObject(file, line, message, loc) - { - } + std::string m_Filename; }; /** \class ImageFileReader @@ -170,12 +165,10 @@ protected: void DoConvertBuffer(void* buffer, size_t numberOfPixels); private: - /** Test whether the given filename exist and it is readable, - this is intended to be called before attempting to use - ImageIO classes for actually reading the file. If the file - doesn't exist or it is not readable, and exception with an - appropriate message will be thrown. */ - void TestFileExistenceAndReadability(); + /** Test whether m_ImageIO is valid (not NULL). This is intended to be called + * after trying to create it via an ImageIOFactory. Throws an exception with + * an appropriate message otherwise. */ + void TestValidImageIO(); /** Generate the filename (for GDALImageI for example). If filename is a directory, look if is a * CEOS product (file "DAT...") In this case, the GdalFileName contain the open image file. @@ -196,8 +189,6 @@ private: bool m_UseStreaming; - std::string m_ExceptionMessage; - // The region that the ImageIO class will return when we ask to // produce the requested region. itk::ImageIORegion m_ActualIORegion; diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.txx b/Modules/IO/ImageIO/include/otbImageFileReader.txx index 8f529967ada3dc10cb40705210da8ac43edece85..f701d882571bd7c17dbd6dd90e162b19f450e21b 100644 --- a/Modules/IO/ImageIO/include/otbImageFileReader.txx +++ b/Modules/IO/ImageIO/include/otbImageFileReader.txx @@ -65,7 +65,6 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> m_UserSpecifiedImageIO(false), m_FileName(""), m_UseStreaming(true), - m_ExceptionMessage(""), m_ActualIORegion(), m_FilenameHelper(FNameHelperType::New()), m_AdditionalNumber(0), @@ -129,9 +128,9 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> output->SetBufferedRegion(output->GetRequestedRegion()); output->Allocate(); - // Test if the file exist and if it can be open. - // An exception will be thrown otherwise. - this->TestFileExistenceAndReadability(); + // Raise an exception if the file could not be opened + // i.e. if this->m_ImageIO is Null + this->TestValidImageIO(); // Tell the ImageIO to read the file OutputImagePixelType *buffer = @@ -242,8 +241,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> } else { - throw otb::ImageFileReaderException(__FILE__, __LINE__, - "Invalid output object type"); + throw otb::ImageFileReaderException(__FILE__, __LINE__, "Invalid output object type"); } } } @@ -253,74 +251,32 @@ void ImageFileReader<TOutputImage, ConvertPixelTraits> ::GenerateOutputInformation(void) { - typename TOutputImage::Pointer output = this->GetOutput(); - itkDebugMacro(<< "Reading file for GenerateOutputInformation()" << this->m_FileName); - // Check to see if we can read the file given the name or prefix - // if (this->m_FileName == "") - { - throw otb::ImageFileReaderException(__FILE__, __LINE__, "FileName must be specified"); - } + { + throw otb::ImageFileReaderException(__FILE__, __LINE__, "Filename must be specified."); + } // Find real image file name // !!!! Update FileName std::string lFileName; - bool found = GetGdalReadImageFileName(this->m_FileName, lFileName); - if (found == false) - { - otbMsgDebugMacro(<< "Filename was NOT unknown. May be recognized by a Image factory ! "); - } - // Update FileName - this->m_FileName = lFileName; - - // Test if the file exists and if it can be opened. - // An exception will be thrown otherwise. - // We catch the exception because some ImageIO's may not actually - // open a file. Still reports file error if no ImageIO is loaded. - - try - { - m_ExceptionMessage = ""; - this->TestFileExistenceAndReadability(); - } - catch (itk::ExceptionObject & err) - { - m_ExceptionMessage = err.GetDescription(); - } - + bool found = GetGdalReadImageFileName(this->m_FileName, lFileName); + if (found) + { + // Update FileName + this->m_FileName = lFileName; + } + if (this->m_UserSpecifiedImageIO == false) //try creating via factory - { + { this->m_ImageIO = ImageIOFactory::CreateImageIO(this->m_FileName.c_str(), otb::ImageIOFactory::ReadMode); - } - - if (this->m_ImageIO.IsNull()) - { - //this->Print(std::cerr); - otb::ImageFileReaderException e(__FILE__, __LINE__); - std::ostringstream msg; - msg << " Could not create IO object for file " - << this->m_FileName.c_str() << std::endl; - msg << " Tried to create one of the following:" << std::endl; - std::list<itk::LightObject::Pointer> allobjects = - itk::ObjectFactoryBase::CreateAllInstance("otbImageIOBase"); - for (std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin(); - i != allobjects.end(); ++i) - { - otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer()); - // IO should never be null, but we would better check for it - if(io) - msg << " " << io->GetNameOfClass() << std::endl; - } - msg << " You probably failed to set a file suffix, or" << std::endl; - msg << " set the suffix to an unsupported type." << std::endl; - e.SetDescription(msg.str().c_str()); - throw e; - return; - } + } + // Raise an exception if the file could not be opened + // i.e. if this->m_ImageIO is Null + this->TestValidImageIO(); // Get the ImageIO MetaData Dictionary itk::MetaDataDictionary& dict = this->m_ImageIO->GetMetaDataDictionary(); @@ -331,7 +287,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> bool lVectorImage = false; if (strcmp(output->GetNameOfClass(), "VectorImage") == 0) lVectorImage= true; - + this->m_ImageIO->SetOutputImagePixelType(PixelIsComplex(dummy),lVectorImage); // Pass the dataset number (used for hdf files for example) @@ -435,9 +391,9 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> if(!m_KeywordListUpToDate && !m_FilenameHelper->GetSkipGeom()) { - + std::string lFileNameOssimKeywordlist = GetDerivedDatasetSourceFileName(m_FileName); - + // Update otb Keywordlist ImageKeywordlist otb_kwl; if (!m_FilenameHelper->ExtGEOMFileNameIsSet()) @@ -450,7 +406,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName()); otbMsgDevMacro(<< "Loading external kwl"); } - + // Don't add an empty ossim keyword list if(!otb_kwl.Empty()) { @@ -511,7 +467,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> } - + // If Skip ProjectionRef is activated, remove ProjRef from dict if (m_FilenameHelper->GetSkipCarto()) { @@ -576,9 +532,9 @@ std::string ImageFileReader<TOutputImage, ConvertPixelTraits> ::GetDerivedDatasetSourceFileName(const std::string & filename) const { - + const size_t dsds_pos = filename.find(DerivedSubdatasetPrefix); - + if(dsds_pos != std::string::npos) { // Derived subdataset from gdal @@ -595,50 +551,22 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> template <class TOutputImage, class ConvertPixelTraits> void ImageFileReader<TOutputImage, ConvertPixelTraits> -::TestFileExistenceAndReadability() +::TestValidImageIO() { - // Test if the file a server name : if so the test is skipped - if (this->m_FileName.find(std::string("http://")) == 0 || - this->m_FileName.find(std::string("https://")) == 0) - { - return; - } + if (this->m_ImageIO.IsNull()) + { + std::string fileToCheck = GetDerivedDatasetSourceFileName(m_FileName); - std::string fileToCheck = GetDerivedDatasetSourceFileName(m_FileName); - - // Test if the file exists. - if (!itksys::SystemTools::FileExists(fileToCheck.c_str())) + // Test if the file exists. + if (!itksys::SystemTools::FileExists(fileToCheck.c_str())) { - otb::ImageFileReaderException e(__FILE__, __LINE__); - std::ostringstream msg; - msg << "The file doesn't exist. " - << std::endl << "Filename = " << fileToCheck - << std::endl; - e.SetDescription(msg.str().c_str()); - throw e; - return; + throw otb::ImageFileReaderException (__FILE__, __LINE__, "The file does not exist.", fileToCheck); } - - // Test if the file can be open for reading access. - //Only if m_FileName specify a filename (not a dirname) - if (itksys::SystemTools::FileExists(fileToCheck.c_str(), true)) + else { - std::ifstream readTester; - readTester.open(fileToCheck.c_str()); - if (readTester.fail()) - { - readTester.close(); - std::ostringstream msg; - msg << "The file couldn't be opened for reading. " - << std::endl << "Filename: " << fileToCheck - << std::endl; - otb::ImageFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION); - throw e; - return; - - } - readTester.close(); + throw otb::ImageFileReaderException(__FILE__, __LINE__, "Probably unsupported format or incorrect filename extension.", this->m_FileName); } + } } template <class TOutputImage, class ConvertPixelTraits> @@ -695,7 +623,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> } fic_trouve = true; } - + otbMsgDevMacro(<< "lFileNameGdal : " << GdalFileName.c_str()); otbMsgDevMacro(<< "fic_trouve : " << fic_trouve); return (fic_trouve); @@ -716,12 +644,12 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> { const std::string skip_geom_key = "skipgeom"; const std::string geom_key = "geom"; - + if (in) { // First, see if the simple filename has changed typename FNameHelperType::Pointer helper = FNameHelperType::New(); - + helper->SetExtendedFileName(in); std::string simpleFileName = helper->GetSimpleFileName(); @@ -735,7 +663,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> if(oldMap.size() != newMap.size() || !std::equal(oldMap.begin(),oldMap.end(),newMap.begin())) { this->Modified(); - + // Now check if keywordlist needs to be generated again // Condition is: one of the old or new map has the skip_geom // key and the other does not @@ -759,7 +687,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> m_KeywordListUpToDate = false; this->Modified(); } - + m_FilenameHelper = helper; } } @@ -781,15 +709,15 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> return this->m_ImageIO->GetOverviewsCount(); } - - + + template <class TOutputImage, class ConvertPixelTraits> std::vector<std::string> ImageFileReader<TOutputImage, ConvertPixelTraits> ::GetOverviewsInfo() { this->UpdateOutputInformation(); - + return this->m_ImageIO->GetOverviewsInfo(); } diff --git a/Modules/IO/ImageIO/include/otbImageFileWriter.txx b/Modules/IO/ImageIO/include/otbImageFileWriter.txx index 3224f5a3860a47e2cb59c7d24d00296bb90747dd..37bb644ed2731560caa13bc13851954290027b58 100644 --- a/Modules/IO/ImageIO/include/otbImageFileWriter.txx +++ b/Modules/IO/ImageIO/include/otbImageFileWriter.txx @@ -448,20 +448,7 @@ ImageFileWriter<TInputImage> { itk::ImageFileWriterException e(__FILE__, __LINE__); std::ostringstream msg; - msg << " Could not create IO object for file " - << m_FileName.c_str() << std::endl; - msg << " Tried to create one of the following:" << std::endl; - std::list<itk::LightObject::Pointer> allobjects = - itk::ObjectFactoryBase::CreateAllInstance("otbImageIOBase"); - for (std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin(); - i != allobjects.end(); ++i) - { - otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer()); - if(io) - msg << " " << io->GetNameOfClass() << std::endl; - } - msg << " You probably failed to set a file suffix, or" << std::endl; - msg << " set the suffix to an unsupported type." << std::endl; + msg << "Cannot write image " << m_FileName.c_str() << ". Probably unsupported format or incorrect filename extension."; e.SetDescription(msg.str().c_str()); e.SetLocation(ITK_LOCATION); throw e; diff --git a/Modules/IO/ImageIO/src/otbImageIOFactory.cxx b/Modules/IO/ImageIO/src/otbImageIOFactory.cxx index 671a62d39c2bce0ddf537ac4fee0d06ad268cc20..1f084b6afd8fa219a10e5437c4723a724db9ac9f 100644 --- a/Modules/IO/ImageIO/src/otbImageIOFactory.cxx +++ b/Modules/IO/ImageIO/src/otbImageIOFactory.cxx @@ -48,38 +48,35 @@ ImageIOFactory::CreateImageIO(const char* path, FileModeType mode) itk::ObjectFactoryBase::CreateAllInstance("otbImageIOBase"); for(std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i) - { + { otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer()); if(io) - { + { possibleImageIO.push_back(io); - } - else - { - std::cerr << "Error ImageIO factory did not return an ImageIOBase: " - << (*i)->GetNameOfClass() - << std::endl; - } } - for(std::list<otb::ImageIOBase::Pointer>::iterator k = possibleImageIO.begin(); - k != possibleImageIO.end(); ++k) + else { + itkGenericExceptionMacro(<< "ImageIO factory did not return an ImageIOBase but a " << (*i)->GetNameOfClass()); + } + } + + for(std::list<otb::ImageIOBase::Pointer>::iterator k = possibleImageIO.begin(); k != possibleImageIO.end(); ++k) + { if( mode == ReadMode ) - { + { if((*k)->CanReadFile(path)) - { + { return *k; - } } + } else if( mode == WriteMode ) - { + { if((*k)->CanWriteFile(path)) - { + { return *k; - } - } } + } return ITK_NULLPTR; } diff --git a/Modules/Visualization/Mapla/src/mvdMaplaWin32.rc.in b/Modules/Visualization/Mapla/src/mvdMaplaWin32.rc.in index 59c150741c2d6544df9fdaf41eb6de06dbf1a800..9c40a86f8cec28f6cc0cbd48d459878bc44a7ee2 100644 --- a/Modules/Visualization/Mapla/src/mvdMaplaWin32.rc.in +++ b/Modules/Visualization/Mapla/src/mvdMaplaWin32.rc.in @@ -16,7 +16,7 @@ BEGIN BLOCK "000004b0" BEGIN VALUE "CompanyName", "OrfeoToolbox" - VALUE "FileDescription", "Monteverdi 2" + VALUE "FileDescription", "Monteverdi" VALUE "FileVersion", "@Monteverdi_VERSION_MAJOR@.@Monteverdi_VERSION_MINOR@.@Monteverdi_VERSION_PATCH@.0" VALUE "LegalCopyright", "Copyright (c) 2012-2013 Centre National d'Etudes Spatiales. All rights reserved." VALUE "InternalName", "mapla" diff --git a/Modules/Visualization/Monteverdi/src/mvdWin32.rc.in b/Modules/Visualization/Monteverdi/src/mvdWin32.rc.in index fdb8647ebd9224e7b7c4e93078dd8519da12d612..c26d776103b87385ed3d05e1ac958eb35f1b99d4 100644 --- a/Modules/Visualization/Monteverdi/src/mvdWin32.rc.in +++ b/Modules/Visualization/Monteverdi/src/mvdWin32.rc.in @@ -16,12 +16,12 @@ BEGIN BLOCK "000004b0" BEGIN VALUE "CompanyName", "OrfeoToolbox" - VALUE "FileDescription", "Monteverdi 2" + VALUE "FileDescription", "Monteverdi" VALUE "FileVersion", "@Monteverdi_VERSION_MAJOR@.@Monteverdi_VERSION_MINOR@.@Monteverdi_VERSION_PATCH@.0" VALUE "LegalCopyright", "Copyright (c) 2012-2013 Centre National d'Etudes Spatiales. All rights reserved." VALUE "InternalName", "monteverdi" VALUE "OriginalFilename", "monteverdi.exe" - VALUE "ProductName", "Monteverdi 2" + VALUE "ProductName", "Monteverdi" VALUE "ProductVersion", "@Monteverdi_VERSION_MAJOR@.@Monteverdi_VERSION_MINOR@.@Monteverdi_VERSION_PATCH@.0" END END diff --git a/Modules/Wrappers/ApplicationEngine/include/otbLogger.h b/Modules/Wrappers/ApplicationEngine/include/otbLogger.h new file mode 100644 index 0000000000000000000000000000000000000000..ba43072a199e2a1e29f481dc232022e457017389 --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/include/otbLogger.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbLogger_h +#define otbLogger_h + +#include "itkLoggerBase.h" +#include "itkLogger.h" + +namespace otb { + +/** \class Logger + * \brief An ITK logger specialized for OTB + * + * Sets OTB wide settings in its constructor + * + * \ingroup OTBApplicationEngine + */ +class Logger : public itk::Logger +{ +public: + typedef Logger Self; + typedef itk::Logger Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + itkTypeMacro(Logger, Object); + itkNewMacro(Self); + + // Overwrite this to provide custom formatting of log entries + std::string BuildFormattedEntry(itk::Logger::PriorityLevelType, std::string const&) ITK_OVERRIDE; + +protected: + Logger(); + virtual ~Logger(); +}; // class Logger + +} // namespace otb + +#endif // otbLogger_h diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h index 57286317e950ee5de9fa7c64e0da5fc1470a9f72..3d944f931ca7f268d8b0b07389f97bf5cf289af6 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h @@ -26,7 +26,7 @@ #include "otbWrapperTags.h" #include "otbWrapperParameterGroup.h" -#include "itkLogger.h" +#include "otbLogger.h" #include "itkTimeProbe.h" #include "otbWrapperMacros.h" #include "otbWrapperInputImageParameter.h" @@ -40,6 +40,37 @@ namespace otb { + +/** \class ApplicationException + * \brief Exception for runtime errors in OTB Applications + * + * Usually thrown with the otbAppLogFATAL macro + * + * \ingroup OTBApplicationEngine + */ +class ApplicationException : public itk::ExceptionObject +{ +public: + /** Run-time information. */ + itkTypeMacro( ApplicationException, ExceptionObject ); + + /** Constructor. */ + ApplicationException(const char *file, unsigned int line, + const char* message = "Application error.", + const char* loc = "Unknown") : + ExceptionObject(file, line, message, loc) + { + } + + /** Constructor. */ + ApplicationException(const std::string &file, unsigned int line, + const char* message = "Application error.", + const char* loc = "Unknown") : + ExceptionObject(file, line, message, loc) + { + } +}; + namespace Wrapper { @@ -70,6 +101,7 @@ public: m_Name = name; GetDocExample()->SetApplicationName(name); this->Modified(); + m_Logger->SetName(name); } itkGetStringMacro(Name); @@ -663,7 +695,7 @@ public: */ ComplexImagePixelType GetParameterComplexOutputImagePixelType(std::string parameter); - itk::Logger* GetLogger(); + otb::Logger* GetLogger(); itk::ProcessObject* GetProgressSource() const; @@ -916,7 +948,6 @@ protected: } } - private: /* Implement this method to add parameters */ virtual void DoInit() = 0; @@ -938,7 +969,7 @@ private: std::string m_Name; std::string m_Description; ParameterGroup::Pointer m_ParameterList; - itk::Logger::Pointer m_Logger; + otb::Logger::Pointer m_Logger; itk::ProcessObject::Pointer m_ProgressSource; std::string m_ProgressSourceDescription; diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h index 94a5429f0563ef3a3cc2233ca0267d966131fa90..6b4bf70c7d66869098aa17dc42aa2a7f12fc5d4f 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h @@ -71,7 +71,9 @@ public: /** Get one specific stored image filename. */ std::string GetNthFileName( unsigned int i ) const; - /** Get one list of the stored image. */ + /** Get one list of the stored image. WARNING : if the parameter list changes, + * the returned image list may become obsolete. You should call + * GetImageList() again to make sure your image list is up-to-date. */ FloatVectorImageListType* GetImageList() const; /** Get one specific stored image. */ diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx index f8aa185cedefc55657c3cbc98c2fa6abdf78f72b..64a620f70610e941fc293f1ada0704d904fbc22b 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx @@ -56,14 +56,7 @@ InputImageParameter::GetImage() typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(m_FileName); - try - { - reader->UpdateOutputInformation(); - } - catch (itk::ExceptionObject &) - { - this->ClearValue(); - } + reader->UpdateOutputInformation(); m_Image = reader->GetOutput(); m_Reader = reader; diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h index 49da20449c4ec637e5ff474011b84b9b3e5cec66..39e4c57d938c3e58c6064b30da019aed529585bf 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h @@ -24,10 +24,15 @@ #define otbAppLogFATAL(x) \ { \ - std::ostringstream msg; \ - msg << "" x << std::endl; \ - this->GetLogger()->Write( itk::LoggerBase::FATAL, msg.str() ); \ - itkGenericExceptionMacro(<< "Fatal error caught. Aborting..."); \ + std::ostringstream msg; \ + msg << "" x << std::endl; \ + this->GetLogger()->Fatal(msg.str()); \ + { \ + std::ostringstream message; \ + message << "otb::ApplicationException " x; \ + ::otb::ApplicationException e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION); \ + throw e_; /* Explicit naming to work around Intel compiler bug. */ \ + } \ } #define otbAppLogCRITICAL(x) \ diff --git a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt index 6bfea3af16946d97709a23d8f148558cc763b7ee..3251a05d8e7f250abf1aae901438544cd7ae13eb 100644 --- a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt +++ b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt @@ -48,6 +48,7 @@ set(OTBApplicationEngine_SRC otbWrapperApplicationRegistry.cxx otbWrapperApplicationFactoryBase.cxx otbWrapperCompositeApplication.cxx + otbLogger.cxx ) add_library(OTBApplicationEngine ${OTBApplicationEngine_SRC}) diff --git a/Modules/Wrappers/ApplicationEngine/src/otbLogger.cxx b/Modules/Wrappers/ApplicationEngine/src/otbLogger.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f7994eed4db3a1830b7fc2e1028bd23344c205eb --- /dev/null +++ b/Modules/Wrappers/ApplicationEngine/src/otbLogger.cxx @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbLogger.h" +#include "itksys/SystemTools.hxx" + +namespace otb +{ + +Logger::Logger() : + itk::Logger::Logger() +{ +#if OTB_DEBUG + this->SetPriorityLevel(itk::LoggerBase::DEBUG); +#else + this->SetPriorityLevel(itk::LoggerBase::INFO); +#endif + + this->SetLevelForFlushing(itk::LoggerBase::CRITICAL); + + this->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE); + this->SetHumanReadableFormat("%Y-%m-%d %H:%M:%S"); +} + +Logger::~Logger() +{ +} + +std::string Logger::BuildFormattedEntry(itk::Logger::PriorityLevelType level, std::string const & content) +{ + static const std::string levelString[] = { "(MUSTFLUSH)", "(FATAL)", "(CRITICAL)", + "(WARNING)", "(INFO)", "(DEBUG)", "(NOTSET)" }; + + // TODO: assert(level <= std::extent<decltype(levelString)>::value); // requires C++11 + + std::ostringstream s; + + + switch ( this->m_TimeStampFormat ) + { + case REALVALUE: + { + s.precision(30); + s << m_Clock->GetTimeInSeconds(); + break; + } + case HUMANREADABLE: + { + s << itksys::SystemTools::GetCurrentDateTime( this->m_HumanReadableFormat.c_str() ); + break; + } + } + s << " " << levelString[level] << ": " << content; + + return s.str(); +} + +} // namespace otb diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx index 5c68b10c37fd720e34060e674f9434869842e25d..7a7b45bb34e6b7b329b8ce174bd916d9a2f24c4d 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx @@ -53,7 +53,7 @@ namespace Wrapper Application::Application() : m_Name(""), m_Description(""), - m_Logger(itk::Logger::New()), + m_Logger(otb::Logger::New()), m_ProgressSourceDescription(""), m_DocName(""), m_DocLongDescription(""), @@ -68,15 +68,13 @@ Application::Application() { // Don't call Init from the constructor, since it calls a virtual method ! m_Logger->SetName("Application.logger"); - m_Logger->SetPriorityLevel(itk::LoggerBase::DEBUG); - m_Logger->SetLevelForFlushing(itk::LoggerBase::CRITICAL); } Application::~Application() { } -itk::Logger* Application::GetLogger() +otb::Logger* Application::GetLogger() { return m_Logger; } @@ -199,9 +197,7 @@ void Application::SetParameterString(std::string parameter, std::string value, b else if (dynamic_cast<InputImageParameter*>(param)) { InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param); - if ( !paramDown->SetFromFileName(value) ) - otbAppLogCRITICAL( <<"Invalid image filename " << value <<"."); - + paramDown->SetFromFileName(value); } else if (dynamic_cast<ComplexInputImageParameter*>(param)) { @@ -436,7 +432,7 @@ int Application::ExecuteAndWriteOutput() std::string checkReturn = outputParam->CheckFileName(true); if (!checkReturn.empty()) { - otbAppLogWARNING("Check filename : "<<checkReturn); + otbAppLogWARNING("Check filename: "<<checkReturn); } if (useRAM) { diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx index 059dc30217c4505c0cc6de3b2af5814294c2e0af..e65e22078177f51cf6d8f85a188d68f4ac9f1416 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx @@ -43,38 +43,21 @@ InputFilenameListParameter::SetListFromFileName(const std::vector<std::string> & // First clear previous file chosen this->ClearValue(); - bool isOk = true; for(unsigned int i=0; i<filenames.size(); i++) { std::string filename = filenames[i]; - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) // File existence checked by the reader if (!filename.empty()) { StringParameter::Pointer strParameter = StringParameter::New(); strParameter->SetValue(filename); - try - { - strParameter->HasValue(); - } - catch(itk::ExceptionObject & /*err*/) - { - this->ClearValue(); - isOk = false; - break; - } + strParameter->HasValue(); // everything went fine, store the object reference m_FilenameList->PushBack(strParameter); } } - if( !isOk ) - { - return false; - } - SetActive(true); this->Modified(); return true; @@ -92,22 +75,12 @@ InputFilenameListParameter::AddNullElement() bool InputFilenameListParameter::AddFromFileName(const std::string & filename) { - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) // File existence checked by the reader if (!filename.empty()) { StringParameter::Pointer strParameter = StringParameter::New(); strParameter->SetValue(filename); - try - { - strParameter->HasValue(); - } - catch(itk::ExceptionObject & /*err*/) - { - this->ClearValue(); - return false; - } + strParameter->HasValue(); // everything went fine, store the object references m_FilenameList->PushBack(strParameter); @@ -127,22 +100,12 @@ InputFilenameListParameter::SetNthFileName( const unsigned int id, const std::st itkExceptionMacro(<< "No file "<<id<<". Only "<<m_FilenameList->Size()<<" filenames available."); } - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) // File existence checked by the reader if (!filename.empty()) { StringParameter::Pointer strParameter = StringParameter::New(); strParameter->SetValue(filename); - try - { - strParameter->HasValue(); - } - catch(itk::ExceptionObject &) - { - this->ClearValue(); - return false; - } + strParameter->HasValue(); m_FilenameList->SetNthElement(id, strParameter); SetActive(true); diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx index 01be700ea7f9055d967cd8a466dc39cc55f1e313..cd41fcf1d80f0ffd3edcfeb1980ee6195a8654dc 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx @@ -44,40 +44,23 @@ InputImageListParameter::SetListFromFileName(const std::vector<std::string> & fi // First clear previous file chosen this->ClearValue(); - bool isOk = true; for(unsigned int i=0; i<filenames.size(); i++) { const std::string filename = filenames[i]; - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) + // File existence checked by the reader if (!filename.empty()) { // Try to build a new ParameterInputImage InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New(); - tmpInputImageParameter->SetFromFileName(filename); - if(!tmpInputImageParameter->HasValue()) - { - // If loading failed - this->ClearValue(); - isOk = false; - break; - } - m_InputImageParameterVector.push_back(tmpInputImageParameter); - m_ImageList->PushBack(tmpInputImageParameter->GetFloatVectorImage()); } } - if( !isOk ) - { - return false; - } - - SetActive(true); this->Modified(); + SetActive(true); return true; } @@ -86,7 +69,6 @@ void InputImageListParameter::AddNullElement() { m_InputImageParameterVector.push_back(ITK_NULLPTR); - m_ImageList->PushBack(ITK_NULLPTR); SetActive(false); this->Modified(); } @@ -94,27 +76,16 @@ InputImageListParameter::AddNullElement() bool InputImageListParameter::AddFromFileName(const std::string & filename) { - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) // File existence checked by the reader if (!filename.empty()) { - // Try to build a new ParameterInputImage InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New(); - tmpInputImageParameter->SetFromFileName(filename); - - if(!tmpInputImageParameter->HasValue()) - { - // If loading failed - this->ClearValue(); - return false; - } - + m_InputImageParameterVector.push_back(tmpInputImageParameter); - m_ImageList->PushBack(tmpInputImageParameter->GetFloatVectorImage()); - SetActive(true); + this->Modified(); + SetActive(true); return true; } @@ -129,24 +100,14 @@ InputImageListParameter::SetNthFileName( const unsigned int id, const std::strin itkExceptionMacro(<< "No image "<<id<<". Only "<<m_InputImageParameterVector.size()<<" images available."); } - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) // File existence checked by the reader if (!filename.empty()) { InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New(); - tmpInputImageParameter->SetFromFileName(filename); - if(!tmpInputImageParameter->HasValue()) - { - this->ClearValue(); - return false; - } - m_InputImageParameterVector[id] = tmpInputImageParameter; - m_ImageList->SetNthElement(id,tmpInputImageParameter->GetFloatVectorImage()); - + this->Modified(); SetActive(true); return true; @@ -166,7 +127,7 @@ InputImageListParameter::GetFileNameList() const { filenames.push_back( (*it)->GetFileName() ); } - + return filenames; } @@ -185,36 +146,32 @@ InputImageListParameter::GetNthFileName( unsigned int i ) const FloatVectorImageListType* InputImageListParameter::GetImageList() const { + m_ImageList->Clear(); + for (unsigned int i=0 ; i < this->Size() ; ++i) + { + m_ImageList->PushBack(m_InputImageParameterVector[i]->GetFloatVectorImage()); + } return m_ImageList; } FloatVectorImageType* InputImageListParameter::GetNthImage(unsigned int i) const { - if(m_ImageList->Size()<i) + if(this->Size()<=i) { - itkExceptionMacro(<< "No image "<<i<<". Only "<<m_ImageList->Size()<<" images available."); + itkExceptionMacro(<< "No image "<<i<<". Only "<<this->Size()<<" images available."); } - return m_ImageList->GetNthElement(i); + return m_InputImageParameterVector[i]->GetFloatVectorImage(); } void InputImageListParameter::SetImageList(FloatVectorImageListType* imList) { // Check input availability - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) - try - { - for(unsigned int i=0; i<imList->Size(); i++) - { - imList->GetNthElement( i )->UpdateOutputInformation(); - } - } - catch(itk::ExceptionObject &) - { - return; - } + for(unsigned int i = 0; i < imList->Size(); i++) + { + imList->GetNthElement(i)->UpdateOutputInformation(); + } // Clear previous values this->ClearValue(); @@ -223,39 +180,33 @@ InputImageListParameter::SetImageList(FloatVectorImageListType* imList) { // Try to build a new ParameterInputImage InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New(); - + tmpInputImageParameter->SetImage(imList->GetNthElement(i)); - + m_InputImageParameterVector.push_back(tmpInputImageParameter); m_ImageList->PushBack(tmpInputImageParameter->GetFloatVectorImage()); } - + SetActive(true); this->Modified(); } void InputImageListParameter::SetNthImage(unsigned int i, ImageBaseType * img) { - if(m_ImageList->Size()<i) - { - itkExceptionMacro(<< "No image "<<i<<". Only "<<m_ImageList->Size()<<" images available."); - } - try - { - img->UpdateOutputInformation(); - } - catch(itk::ExceptionObject &) - { - return; - } - + if(this->Size()<i) + { + itkExceptionMacro(<< "No image "<<i<<". Only "<<this->Size()<<" images available."); + } + + // Check input availability + img->UpdateOutputInformation(); + // Try to build a new ParameterInputImage InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New(); - + tmpInputImageParameter->SetImage(img); m_InputImageParameterVector[i] = tmpInputImageParameter; - m_ImageList->SetNthElement(i,tmpInputImageParameter->GetFloatVectorImage()); } @@ -263,23 +214,13 @@ void InputImageListParameter::AddImage(ImageBaseType* image) { // Check input availability - // TODO : when the logger will be available, redirect the exception - // in the logger (like what is done in MsgReporter) - try - { - image->UpdateOutputInformation(); - } - catch(itk::ExceptionObject &) - { - return; - } + image->UpdateOutputInformation(); InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New(); - + tmpInputImageParameter->SetImage(image); - + m_InputImageParameterVector.push_back(tmpInputImageParameter); - m_ImageList->PushBack(tmpInputImageParameter->GetFloatVectorImage()); this->Modified(); } @@ -287,16 +228,18 @@ InputImageListParameter::AddImage(ImageBaseType* image) bool InputImageListParameter::HasValue() const { - if(m_ImageList->Size() == 0) + if(this->Size() == 0) { return false; } bool res(true); unsigned int i(0); - while(i < m_ImageList->Size() && res == true) + while(i < this->Size() && res == true) { - res = m_ImageList->GetNthElement(i).IsNotNull(); + res = (m_InputImageParameterVector[i] ? + m_InputImageParameterVector[i]->HasValue() : + false); i++; } @@ -307,12 +250,11 @@ InputImageListParameter::HasValue() const void InputImageListParameter::Erase( unsigned int id ) { - if(m_ImageList->Size()<id) + if(this->Size()<id) { - itkExceptionMacro(<< "No image "<<id<<". Only "<<m_ImageList->Size()<<" images available."); + itkExceptionMacro(<< "No image "<<id<<". Only "<<this->Size()<<" images available."); } - m_ImageList->Erase( id ); m_InputImageParameterVector.erase(m_InputImageParameterVector.begin()+id); this->Modified(); diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx index dcd9d215283d8ea80a71b816ab1a7a18d9ba84a4..08c0e1c36249954b7a18c58fd253f7df9d0d1b67 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx @@ -53,27 +53,10 @@ InputImageParameter::SetFromFileName(const std::string& filename) // - Done in the reader // - allow appending additional information to the filename // myfile.tif:2 for example, or myfile.tif:nocarto - if (!filename.empty()) - { - FloatVectorReaderType::Pointer reader = FloatVectorReaderType::New(); - - try - { - reader->SetFileName(filename); - reader->UpdateOutputInformation(); - } - catch(itk::ExceptionObject & /*err*/) - { - return false; - } - - // the specified filename is valid => store the value - m_FileName = filename; - m_UseFilename = true; - SetActive(true); - return true; - } - return false; + m_FileName = filename; + m_UseFilename = true; + SetActive(true); + return true; } diff --git a/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h b/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h index a7869e4842741e315d4adac5eb8d0e24972bf07e..c54d4a9fed22c2358c08f4589a08077ba5881443 100644 --- a/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h +++ b/Modules/Wrappers/CommandLine/include/otbWrapperCommandLineLauncher.h @@ -134,7 +134,7 @@ protected: * Pay attention, the executable paths have to be loaded or set in * the environment before calling the function. */ - void LoadApplication(); + bool LoadApplication(); /** Parse the user expression, extract the key and the associated * string and set it as value of each corresponding application diff --git a/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx b/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx index c684158fccf30be7fa54c11ddd20343cc141f96d..4c5bd8a93f43780e7d4827b260ae92e73ca9fde3 100644 --- a/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx +++ b/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx @@ -256,24 +256,28 @@ std::string CleanWord(const std::string & word) return res; } +void ShowUsage(char* argv[]) +{ + std::cerr << "Usage: " << argv[0] << " module_name [MODULEPATH] [arguments]" << std::endl; +} + int main(int argc, char* argv[]) { #ifdef OTB_USE_MPI otb::MPIConfig::Instance()->Init(argc,argv); #endif - + if (argc < 2) - { - std::cerr << "Usage : " << argv[0] << " module_name [MODULEPATH] [arguments]" << std::endl; - return EXIT_FAILURE; - } + { + ShowUsage(argv); + return false; + } std::vector<std::string> vexp; std::string exp; if (strcmp(argv[1], "-inxml") == 0) { - //exp = PrepareExpressionFromXML(argv[2]); vexp = PrepareVectorExpressionFromXML(argv[2]); } else @@ -281,15 +285,6 @@ int main(int argc, char* argv[]) // Construct the string expression for (int i = 1; i < argc; i++) { - /*if (i != argc - 1) - { - exp.append(argv[i]); - exp.append(" "); - } - else - { - exp.append(argv[i]); - }*/ std::string strarg(argv[i]); std::string cleanArg = CleanWord(strarg); if (cleanArg.empty()) @@ -300,12 +295,16 @@ int main(int argc, char* argv[]) vexp.push_back(cleanArg); } } - // std::cerr << exp << ":\n"; typedef otb::Wrapper::CommandLineLauncher LauncherType; LauncherType::Pointer launcher = LauncherType::New(); - //if (launcher->Load(exp) == true) + if (vexp.empty()) + { + ShowUsage(argv); + return false; + } + bool success = launcher->Load(vexp) && launcher->ExecuteAndWriteOutput(); // shutdown MPI after application finished diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx index 4be16ba228f5c27a3ad114f77609d011038a72e2..686d4d58cf65f248024accc8ad306cda13d73e4a 100644 --- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx +++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx @@ -49,6 +49,8 @@ #include <string> #include <iostream> +using std::string; + namespace otb { namespace Wrapper @@ -94,20 +96,15 @@ bool CommandLineLauncher::Load(const std::vector<std::string> &vexp) bool CommandLineLauncher::Load() { - if (m_VExpression.empty()) - { - itkExceptionMacro("No expression specified..."); - } - if (this->CheckParametersPrefix() == false) { - std::cerr << "ERROR: Parameter keys have to set using \"-\", not \"--\"" << std::endl; + std::cerr << "ERROR: Parameters are set using \"-\", not \"--\"." << std::endl; return false; } if (this->CheckUnicity() == false) { - std::cerr << "ERROR: At least one key is not unique in the expression..." << std::endl; + std::cerr << "ERROR: At least one parameter is not unique in the expression." << std::endl; return false; } @@ -116,14 +113,12 @@ bool CommandLineLauncher::Load() if (m_Parser->GetPathsAsString(m_VExpression).size() != 0) { std::cerr << "ERROR: At least one specified path within \"" << m_Parser->GetPathsAsString(m_VExpression) - << "\" is invalid or doesn't exist..." << std::endl; + << "\" is invalid or doesn't exist." << std::endl; return false; } } - this->LoadApplication(); - - return true; + return this->LoadApplication(); } bool CommandLineLauncher::Execute() @@ -145,31 +140,54 @@ bool CommandLineLauncher::Execute() bool CommandLineLauncher::ExecuteAndWriteOutput() { try - { + { if (this->BeforeExecute() == false) - { + { return false; - } + } if( m_Application->ExecuteAndWriteOutput() == 0 ) - { + { this->DisplayOutputParameters(); - } + } else + { return false; } + } + catch(otb::ApplicationException& err) + { + // These are thrown with otbAppLogFATAL, a macro which logs a user + // friendly error message before throwing. So log exception details only + // in debug. + m_Application->GetLogger()->Debug("Caught otb::ApplicationException during application execution:\n"); + m_Application->GetLogger()->Debug(string(err.what()) + "\n"); + return false; + } + catch(otb::ImageFileReaderException& err) + { + m_Application->GetLogger()->Debug("Caught otb::ImageFileReaderException during application execution:\n"); + m_Application->GetLogger()->Debug(string(err.what()) + "\n"); + m_Application->GetLogger()->Fatal(string("Cannot open image ") + err.m_Filename + string(". ") + err.GetDescription() + string("\n")); + return false; + } + catch(itk::ExceptionObject& err) + { + m_Application->GetLogger()->Debug("Caught itk::ExceptionObject during application execution:\n"); + m_Application->GetLogger()->Debug(string(err.what()) + "\n"); + m_Application->GetLogger()->Fatal(string(err.GetDescription()) + "\n"); + return false; + } catch(std::exception& err) - { - std::ostringstream message; - message << "The following error occurred during application execution : " << err.what() << std::endl; - m_Application->GetLogger()->Write( itk::LoggerBase::FATAL, message.str() ); + { + m_Application->GetLogger()->Fatal(std::string("Caught std::exception during application execution: ") + err.what() + "\n"); return false; - } + } catch(...) - { - m_Application->GetLogger()->Write( itk::LoggerBase::FATAL, "An unknown exception has been raised during application execution" ); + { + m_Application->GetLogger()->Fatal("Caught unknown exception during application execution.\n"); return false; - } + } return true; } @@ -177,10 +195,10 @@ bool CommandLineLauncher::ExecuteAndWriteOutput() bool CommandLineLauncher::BeforeExecute() { if (m_Application.IsNull()) - { - std::cerr << "ERROR: No loaded application..." << std::endl; + { + std::cerr << "ERROR: No loaded application." << std::endl; return false; - } + } // Check if there's keys in the expression if the application takes // at least 1 mandatory parameter @@ -189,7 +207,8 @@ bool CommandLineLauncher::BeforeExecute() if( appKeyList.size()!=0 && keyList.size()==0 ) { - std::cerr << "ERROR: Waiting for at least one parameter..." << std::endl; + std::cerr << "ERROR: Waiting for at least one parameter." << std::endl; + std::cerr << std::endl; this->DisplayHelp(); return false; } @@ -237,64 +256,22 @@ bool CommandLineLauncher::BeforeExecute() std::string unknownKey; if (this->CheckKeyValidity(unknownKey) == false) { - std::cerr << "ERROR: option -"<<unknownKey<<" does not exist in the application." << std::endl; - this->DisplayHelp(); + std::cerr << "ERROR: Parameter -" << unknownKey <<" does not exist in the application." << std::endl; return false; } - try - { - if (this->LoadParameters() != OKPARAM) - { - std::cerr << "ERROR: Troubles loading parameter, please check your line argument..." << std::endl; - // Force to reload the application, the LoadParameters can change wrong values - this->LoadApplication(); - m_Application->Init(); - this->DisplayHelp(); - return false; - } - } - catch (itk::ExceptionObject& err) - { - std::cerr << "ERROR: Troubles in parameter setting, please check your line argument..." << std::endl; - std::cerr << err.GetDescription() << std::endl; - // Force to reload the application, the LoadParameters can change wrong values - this->LoadApplication(); - m_Application->Init(); - this->DisplayHelp(); + ParamResultType result = this->LoadParameters(); + if (result == MISSINGMANDATORYPARAMETER) + { + std::cerr << std::endl; + this->DisplayHelp(); return false; - } - - // Check for the progress report - if (m_Parser->IsAttributExists("-progress", m_VExpression) == true) - { - std::vector<std::string> val; - val = m_Parser->GetAttribut("-progress", m_VExpression); - if (val.size() != 1) - { - std::cerr << "ERROR: Invalid progress argument, must be unique value..." << std::endl; - return false; - } - if (val[0] == "1" || val[0] == "true") - { - m_ReportProgress = true; - } - else - if (val[0] == "0" || val[0] == "false") - { - m_ReportProgress = false; - } - else - { - std::cerr << "ERROR: Invalid progress argument, must be 0, 1, false or true..." << std::endl; - // Force to reload the application, the LoadParameters can change wrong values - this->LoadApplication(); - this->DisplayHelp(); - - return false; - } - } + } + else if (result != OKPARAM) + { + return false; + } return true; } @@ -319,15 +296,14 @@ bool CommandLineLauncher::LoadPath() return true; } -void CommandLineLauncher::LoadApplication() +bool CommandLineLauncher::LoadApplication() { // Look for the module name std::string moduleName; - //if (m_Parser->GetModuleName(moduleName, m_Expression) != CommandLineParser::OK) if (m_Parser->GetModuleName(moduleName, m_VExpression) != CommandLineParser::OK) { - std::cerr << "ERROR: LoadApplication, no module found..." << std::endl; - return; + std::cerr << "ERROR: Invalid module name: " << m_VExpression[0] << "." << std::endl; + return false; } // Instantiate the application using the factory @@ -342,26 +318,27 @@ void CommandLineLauncher::LoadApplication() std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications(); if (list.size() == 0) { - std::cerr << "ERROR: Available modules : none." << std::endl; + std::cerr << "ERROR: Available modules: none." << std::endl; } else { - std::cerr << "ERROR: Available modules :" << std::endl; + std::cerr << "ERROR: Available modules:" << std::endl; for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it) { std::cerr << "\t" << *it << std::endl; } } + return false; } else { // Attach log output to the Application logger - m_Application->GetLogger()->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE); m_Application->GetLogger()->AddLogOutput(m_LogOutput); // Add an observer to the AddedProcess event m_Application->AddObserver(AddProcessToWatchEvent(), m_AddProcessCommand.GetPointer()); + return true; } } @@ -386,6 +363,25 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() m_Application->UpdateParameters(); } + // Check for the progress report parameter + if (m_Parser->IsAttributExists("-progress", m_VExpression) == true) + { + std::vector<std::string> val = m_Parser->GetAttribut("-progress", m_VExpression); + if (val.size() == 1 && (val[0] == "1" || val[0] == "true")) + { + m_ReportProgress = true; + } + else if (val.size() == 1 && (val[0] == "0" || val[0] == "false")) + { + m_ReportProgress = false; + } + else + { + std::cerr << "ERROR: Invalid value for parameter -progress. It must be 0, 1, false or true." << std::endl; + return WRONGPARAMETERVALUE; + } + } + const std::vector<std::string> appKeyList = m_Application->GetParametersKeys(true); // Loop over each parameter key declared in the application // FIRST PASS : set parameter values @@ -412,8 +408,7 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() // Check if there is a value associated to the attribute if ( values.empty() ) { - std::cerr << "ERROR: No value associated to the parameter : \"" << paramKey - << "\", invalid number of values " << values.size() << std::endl; + std::cerr << "ERROR: No value associated to parameter -" << paramKey << "." << std::endl; return INVALIDNUMBEROFVALUE; } @@ -468,16 +463,16 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() else if (values[1] == "double") outPixType = ImagePixelType_double; else - { + { + std::cerr << "ERROR: Invalid output type for parameter -" << paramKey << ": " << values[1] << "." << std::endl; return WRONGPARAMETERVALUE; - } + } dynamic_cast<OutputImageParameter *> (param.GetPointer())->SetPixelType(outPixType); } else - if (values.size() != 1 && values.size() != 2) + if (values.size() > 2) { - std::cerr << "ERROR: Invalid number of value for: \"" << paramKey - << "\", invalid number of values " << values.size() << std::endl; + std::cerr << "ERROR: Too many values for parameter -" << paramKey << " (expected 2 or less, got " << values.size() << ")." << std::endl; return INVALIDNUMBEROFVALUE; } } @@ -493,9 +488,10 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() else if (values[1] == "cdouble") outPixType = ComplexImagePixelType_double; else - { + { + std::cerr << "ERROR: Invalid output type for parameter -" << paramKey << ": " << values[1] << "." << std::endl; return WRONGPARAMETERVALUE; - } + } dynamic_cast<ComplexOutputImageParameter *> (param.GetPointer())->SetComplexPixelType(outPixType); } else @@ -568,11 +564,11 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() { dynamic_cast<EmptyParameter *> (param.GetPointer())->SetActive(false); } - else - { - std::cerr << "ERROR: Wrong parameter value: " << paramKey << std::endl; - return WRONGPARAMETERVALUE; - } + else + { + std::cerr << "ERROR: Wrong value for parameter -" << paramKey << "." << std::endl; + return WRONGPARAMETERVALUE; + } } // Update the flag UserValue param->SetUserValue(true); @@ -633,27 +629,26 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() } if( mustBeSet ) - { + { if (!paramExists) - { + { // If key doesn't exist and parameter hasn't default value set... if (!hasValue) - { - std::cerr << "ERROR: Missing mandatory parameter: " << paramKey << " " << m_Application->HasValue(paramKey) - << std::endl; + { + std::cerr << "ERROR: Missing mandatory parameter -" << paramKey << "." << std::endl; return MISSINGMANDATORYPARAMETER; - } } + } else - { + { values = m_Parser->GetAttribut(std::string("-").append(paramKey), m_VExpression); if (values.size() == 0 && !m_Application->HasValue(paramKey)) - { - std::cerr << "ERROR: Missing mandatory parameter: " << paramKey << std::endl; + { + std::cerr << "ERROR: Missing mandatory parameter -" << paramKey << "." << std::endl; return MISSINGPARAMETERVALUE; - } } } + } // Check if non mandatory parameter have values else { @@ -662,7 +657,7 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters() values = m_Parser->GetAttribut(std::string("-").append(paramKey), m_VExpression); if (values.size() == 0) { - std::cerr << "ERROR: Missing non-mandatory parameter: " << paramKey << std::endl; + std::cerr << "ERROR: Missing non-mandatory parameter -" << paramKey << "." << std::endl; return MISSINGPARAMETERVALUE; } } diff --git a/Modules/Wrappers/QtWidget/include/otbQtFileSelectionWidget.h b/Modules/Wrappers/QtWidget/include/otbQtFileSelectionWidget.h index f9760192c4b240e2b16167fbd1355b646934c1ba..d7b42e3083116faed0e1d51627f39c48206114d6 100644 --- a/Modules/Wrappers/QtWidget/include/otbQtFileSelectionWidget.h +++ b/Modules/Wrappers/QtWidget/include/otbQtFileSelectionWidget.h @@ -81,8 +81,12 @@ public: void SetIOMode( IOMode ); IOMode GetIOMode() const; +signals: + void FilenameChanged(); + protected slots: void SelectFile(); + void CallFilenameChanged(); private: QtFileSelectionWidget(const QtFileSelectionWidget&); //purposely not implemented diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageParameter.h index 8c2a578642ccd736d0ccc0354f2db96da64bd480..01684af9326ed3b20133ddedcce04d9f29f4c8ae 100644 --- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageParameter.h +++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageParameter.h @@ -48,8 +48,11 @@ public: inline const QLineEdit* GetInput() const; inline QLineEdit* GetInput(); +signals: + void FileNameIsSet(); + protected slots: - bool SetFileName( const QString& value ); + bool SetFileName(); void SelectFile(); private: diff --git a/Modules/Wrappers/QtWidget/src/otbQtFileSelectionWidget.cxx b/Modules/Wrappers/QtWidget/src/otbQtFileSelectionWidget.cxx index 818628ac6efec74c521db9adc15e6f9d4d10181e..37e4f3eed3ee02c97da7956d506f55d3c82ab98c 100644 --- a/Modules/Wrappers/QtWidget/src/otbQtFileSelectionWidget.cxx +++ b/Modules/Wrappers/QtWidget/src/otbQtFileSelectionWidget.cxx @@ -74,6 +74,7 @@ void QtFileSelectionWidget::DoCreateWidget() m_HLayout->addWidget(m_Checkbox); m_Input = new QLineEdit; + connect( m_Input, SIGNAL(editingFinished()), this, SLOT(CallFilenameChanged()) ); m_HLayout->addWidget(m_Input); // Set up input text edit @@ -116,8 +117,16 @@ QtFileSelectionWidget return; m_Input->setText( filename ); + + emit FilenameChanged(); } +void +QtFileSelectionWidget +::CallFilenameChanged() +{ + emit FilenameChanged(); +} } diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx index 18e3a7aa9c80e6c46737d5c6563ba69c9c73098c..8224946af0c073f5707a8ee268c2e4dfde1ebefa 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx @@ -134,7 +134,7 @@ void QtWidgetInputImageListParameter::DoCreateWidget() fileSelection->setFixedHeight(30); fileLayout->addWidget(fileSelection); m_InputImageListParam->AddNullElement(); - connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateImageList())); + connect(fileSelection, SIGNAL(FilenameChanged()), this, SLOT(UpdateImageList())); m_FileSelectionList.push_back(fileSelection); @@ -160,16 +160,14 @@ void QtWidgetInputImageListParameter::DoCreateWidget() void QtWidgetInputImageListParameter::UpdateImageList() { - /* Adding a NullElement so to make the m_FileSelectionList and -* m_InputImageList's ImageList are of same size. So that GetImageList().Size() -* seems to be happy. - */ - for(unsigned int i = m_InputImageListParam->GetImageList()->Size(); i < m_FileSelectionList.size(); i++) + // Adding a NullElement so to make the m_FileSelectionList and + // m_InputImageList's ImageList are of same size. + for(unsigned int i = m_InputImageListParam->Size(); i < m_FileSelectionList.size(); i++) { m_InputImageListParam->AddNullElement(); } - for(unsigned int j = 0; j < m_InputImageListParam->GetImageList()->Size(); j++) + for(unsigned int j = 0; j < m_InputImageListParam->Size(); j++) { if(m_InputImageListParam->SetNthFileName(j, m_FileSelectionList[j]->GetFilename()) == false) { @@ -321,8 +319,8 @@ QtWidgetInputImageListParameter::AddFile() /* No need of AddNullElement() here. Moved adding NullElement when updating the list */ //m_InputImageListParam->AddNullElement(); connect( - fileSelection->GetInput(), - SIGNAL( textChanged( const QString & ) ), + fileSelection, + SIGNAL( FilenameChanged() ), this, SLOT( UpdateImageList() ) ); @@ -374,7 +372,7 @@ QtWidgetInputImageListParameter::EraseFile() m_FileLayout->addWidget(fileSelection); m_FileSelectionList.push_back(fileSelection); m_InputImageListParam->AddNullElement(); - connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateImageList())); + connect(fileSelection, SIGNAL(FilenameChanged()), this, SLOT(UpdateImageList())); QGroupBox *mainGroup = new QGroupBox(); mainGroup->setLayout(m_FileLayout); @@ -398,7 +396,7 @@ void QtWidgetInputImageListParameter::RecreateImageList() for(unsigned int j = 0; j < m_FileSelectionList.size(); j++) { m_InputImageListParam->AddFromFileName(m_FileSelectionList[j]->GetFilename()); - connect(m_FileSelectionList[j]->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateImageList())); + connect(m_FileSelectionList[j], SIGNAL(FilenameChanged()), this, SLOT(UpdateImageList())); } emit Change(); diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx index 2f2b06519d1a69b0e0253d4f710bd2e9dad45660..2929d528a5515d1f4696b390e99e4ef46b0b0b20 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx @@ -69,8 +69,8 @@ void QtWidgetInputImageParameter::DoCreateWidget() m_HLayout->setContentsMargins(0, 0, 0, 0); m_Input = new QLineEdit; m_Input->setToolTip( m_InputImageParam->GetDescription() ); - connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) ); - connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) ); + connect( m_Input, SIGNAL(editingFinished()), this, SLOT(SetFileName()) ); + connect( this, SIGNAL(FileNameIsSet()), GetModel(), SLOT(NotifyUpdate()) ); m_HLayout->addWidget(m_Input); @@ -105,7 +105,9 @@ QtWidgetInputImageParameter if( filename.isEmpty() ) return; - if( !SetFileName( filename ) ) + m_Input->setText( filename ); + + if( !SetFileName() ) { std::ostringstream oss; @@ -119,21 +121,20 @@ QtWidgetInputImageParameter return; } - - m_Input->setText( filename ); } -bool QtWidgetInputImageParameter::SetFileName(const QString& value) +bool QtWidgetInputImageParameter::SetFileName() { bool res = true; // save value if( m_InputImageParam->SetFromFileName( - QFile::encodeName( value ).constData() ) == true ) + QFile::encodeName( m_Input->text() ).constData() ) == true ) { // notify of value change QString key( m_InputImageParam->GetKey() ); emit ParameterChanged(key); + emit FileNameIsSet(); } else res = false; diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx index 30f0da4573d846694fb636e403c7d2d6cc9226dc..1fa1e283efa1d6710096ba5c8dcb6512bf433da8 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx @@ -23,6 +23,8 @@ //Use to create command line from the application parameters #include "otbWrapperOutputProcessXMLParameter.h" +using std::string; + namespace otb { @@ -44,7 +46,6 @@ QtWidgetModel m_LogOutput = QtLogOutput::New(); // Attach log output to the Application logger - m_Application->GetLogger()->SetTimeStampFormat(itk::LoggerBase::HUMANREADABLE); m_Application->GetLogger()->AddLogOutput(m_LogOutput); m_Timer = new QTimer(this); @@ -266,41 +267,44 @@ AppliThread { int result = -1; - // - // Try to execute OTB-application. try - { + { result = m_Application->ExecuteAndWriteOutput(); - } - // - // Catch standard exceptions. - catch( std::exception& err ) - { - std::ostringstream message; - - message - << "The following error occurred during OTB-application execution: " - << err.what() - << std::endl; - - m_Application->GetLogger()->Write( itk::LoggerBase::FATAL, message.str() ); - - // Signal exception. + } + catch(otb::ApplicationException& err) + { + // These are thrown with otbAppLogFATAL, a macro which logs a user + // friendly error message before throwing. So log exception details only + // in debug. + m_Application->GetLogger()->Debug("Caught otb::ApplicationException during application execution:\n"); + m_Application->GetLogger()->Debug(string(err.what()) + "\n"); emit ExceptionRaised( err.what() ); - } - // - // Catch other exceptions. - catch( ... ) - { - m_Application->GetLogger()->Write( - itk::LoggerBase::FATAL, - "An unknown exception has been raised during OTB-application execution" - ); + } + catch(otb::ImageFileReaderException& err) + { + m_Application->GetLogger()->Debug("Caught otb::ImageFileReaderException during application execution:\n"); + m_Application->GetLogger()->Debug(string(err.what()) + "\n"); + m_Application->GetLogger()->Fatal(string("Cannot open image ") + err.m_Filename + string(". ") + err.GetDescription() + string("\n")); + emit ExceptionRaised( err.what() ); + } + catch(itk::ExceptionObject& err) + { + m_Application->GetLogger()->Debug("Caught itk::ExceptionObject during application execution:\n"); + m_Application->GetLogger()->Debug(string(err.what()) + "\n"); + m_Application->GetLogger()->Fatal(string(err.GetDescription()) + "\n"); + emit ExceptionRaised( err.what() ); + } + catch(std::exception& err) + { + m_Application->GetLogger()->Fatal(string("Caught std::exception during application execution: ") + err.what() + "\n"); + emit ExceptionRaised( err.what() ); + } + catch(...) + { + m_Application->GetLogger()->Fatal("Caught unknown exception during application execution.\n"); + emit ExceptionRaised("Unknown exception."); + } - // Signal exception. - emit ExceptionRaised( "Exception raised by OTB-application." ); - } - // // Signal OTB-application has ended with result status. emit ApplicationExecutionDone( result ); } diff --git a/Modules/Wrappers/SWIG/src/itkBase.i b/Modules/Wrappers/SWIG/src/itkBase.i index b514c3ca5e511f171fc3992dae4d6ec6d2cfb7dc..2a15719f26f03106b4bb599ac0161931bb0636a7 100644 --- a/Modules/Wrappers/SWIG/src/itkBase.i +++ b/Modules/Wrappers/SWIG/src/itkBase.i @@ -29,6 +29,10 @@ %exception { try { $action + } catch(otb::ImageFileReaderException& err) { + std::ostringstream oss; + oss << "Cannot open image " << err.m_Filename + ". " + err.GetDescription(); + SWIG_exception( SWIG_RuntimeError, oss.str().c_str() ); } catch( itk::ExceptionObject &ex ) { std::ostringstream oss; oss << "Exception thrown in otbApplication $symname: " << ex.what(); diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i index 4f548c756caf7c113e21087bd31661186303b827..72adde8bd4d3181aee5c712ea41f0822ece49f39 100644 --- a/Modules/Wrappers/SWIG/src/otbApplication.i +++ b/Modules/Wrappers/SWIG/src/otbApplication.i @@ -576,7 +576,7 @@ class ApplicationProxy(object): if attr in key_list: return self.GetParameterValue(attr.lower()) else: - raise AttributeError + raise AttributeError("Parameter {} does not exist in the application.".format(attr.lower())) def __setattr__(self, attr, value): """ @@ -593,7 +593,7 @@ class ApplicationProxy(object): if attr in key_list: self.SetParameterValue(attr.lower(), value) else: - raise AttributeError + raise AttributeError("Parameter {} does not exist in the application.".format(attr.lower())) } }