///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017 Statoil ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RicfCommandFileExecutor.h" #include "RiaLogging.h" #include "RicfCloseProject.h" #include "RicfCommandObject.h" #include "RicfOpenProject.h" #include "RicfReplaceCase.h" #include "RifcCommandFileReader.h" namespace caf { template <> void RicfCommandFileExecutor::ExportTypeEnum::setUp() { addItem( RicfCommandFileExecutor::COMPLETIONS, "COMPLETIONS", "Completions" ); addItem( RicfCommandFileExecutor::PROPERTIES, "PROPERTIES", "Properties" ); addItem( RicfCommandFileExecutor::SNAPSHOTS, "SNAPSHOTS", "Snapshots" ); addItem( RicfCommandFileExecutor::STATISTICS, "STATISTICS", "Statistics" ); addItem( RicfCommandFileExecutor::WELLPATHS, "WELLPATHS", "Well Path" ); addItem( RicfCommandFileExecutor::CELLS, "CELLS", "Cells" ); addItem( RicfCommandFileExecutor::LGRS, "LGRS", "Lgrs" ); setDefault( RicfCommandFileExecutor::COMPLETIONS ); } } // namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RicfCommandFileExecutor::RicfCommandFileExecutor() {} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RicfCommandFileExecutor::~RicfCommandFileExecutor() {} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicfCommandFileExecutor::executeCommands( QTextStream& stream ) { RicfMessages messages; std::vector executableCommands; { clearCachedData(); std::vector fileCommands = RicfCommandFileReader::readCommands( stream, caf::PdmDefaultObjectFactory::instance(), &messages ); for ( auto message : messages.m_messages ) { if ( message.first == RicfMessages::MESSAGE_WARNING ) { RiaLogging::warning( QString( "Command file parsing warning: %1" ).arg( message.second ) ); } else { RiaLogging::error( QString( "Command file parsing error: %1" ).arg( message.second ) ); for ( auto& command : fileCommands ) { delete command; command = nullptr; } return; } } for ( auto fileCommand : fileCommands ) { fileCommand->initAfterReadRecursively(); } executableCommands = RicfCommandFileExecutor::prepareFileCommandsForExecution( fileCommands ); } for ( auto& command : executableCommands ) { command->execute(); delete command; command = nullptr; } // All command objects should be deleted and grounded at this point for ( auto c : executableCommands ) { CAF_ASSERT( c == nullptr ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicfCommandFileExecutor::setExportPath( ExportType type, const QString& path ) { m_exportPaths[type] = path; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RicfCommandFileExecutor::getExportPath( ExportType type ) const { auto it = m_exportPaths.find( type ); QString path; if ( it != m_exportPaths.end() ) { path = it->second; } return path; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicfCommandFileExecutor::setLastProjectPath( const QString& path ) { m_lastProjectPath = path; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RicfCommandFileExecutor::getLastProjectPath() const { return m_lastProjectPath; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RicfCommandFileExecutor* RicfCommandFileExecutor::instance() { static RicfCommandFileExecutor* commandFileExecutorInstance = new RicfCommandFileExecutor(); return commandFileExecutorInstance; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RicfCommandFileExecutor::prepareFileCommandsForExecution( const std::vector& commandsReadFromFile ) { // This function will merge multiple RicfSingleCaseReplace object by a single RicfMultiCaseReplace object // A command file version for multi case replace was rejected by @hhgs 2018-02-02 // // The reason for this is based on two requirements // 1. Ability to aggregate info from multiple replaceCase() statements in a command file // 2. Improve performance, as a replace case is implemented by reading a project file from XML and replace file paths // during project loading std::vector executableCommands; { std::vector objectsToBeDeleted; std::vector batchOfReplaceCaseFileObjects; std::map aggregatedCasePathPairs; for ( RicfCommandObject* command : commandsReadFromFile ) { RicfSingleCaseReplace* fileReplaceCase = dynamic_cast( command ); if ( fileReplaceCase ) { aggregatedCasePathPairs[fileReplaceCase->caseId()] = fileReplaceCase->filePath(); batchOfReplaceCaseFileObjects.push_back( fileReplaceCase ); objectsToBeDeleted.push_back( fileReplaceCase ); } else { if ( !batchOfReplaceCaseFileObjects.empty() ) { RicfMultiCaseReplace* multiCaseReplace = new RicfMultiCaseReplace; multiCaseReplace->setCaseReplacePairs( aggregatedCasePathPairs ); executableCommands.push_back( multiCaseReplace ); batchOfReplaceCaseFileObjects.clear(); } if ( dynamic_cast( command ) || dynamic_cast( command ) ) { // Reset aggregation when openProject or closeProject is issued aggregatedCasePathPairs.clear(); } executableCommands.push_back( command ); } } // Delete RicfSingleCaseReplace objects, as they are replaced by RicfMultiCaseReplace for ( auto objToDelete : objectsToBeDeleted ) { delete objToDelete; objToDelete = nullptr; } } return executableCommands; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicfCommandFileExecutor::clearCachedData() { m_exportPaths.clear(); m_lastProjectPath.clear(); }