return true;
}
+/*!
+ Does nothing by default. Should be redefined in light modules
+ that want to participate in "Dump study" operation.
+*/
+bool LightApp_DataModel::dumpPython( const QString&, CAM_Study*, bool, QStringList& )
+{
+ return true;
+}
+
/*!
Emit closed()
*/
virtual bool save( QStringList& );
virtual bool saveAs( const QString&, CAM_Study*, QStringList& );
virtual bool close();
+ virtual bool dumpPython( const QString&,
+ CAM_Study*,
+ bool,
+ QStringList& );
virtual void update( LightApp_DataObject* = 0, LightApp_Study* = 0 );
return true;
}
+//=================================================================================
+// function : dumpPython()
+// purpose : Re-defined from LigthApp_DataModel in order to participate
+// in dump study process
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::dumpPython( const QString& theURL,
+ CAM_Study* theStudy,
+ bool isMultiFile,
+ QStringList& theListOfFiles )
+{
+ MESSAGE("SALOME_PYQT_DataModelLight::dumpPython()");
+
+ LightApp_DataModel::dumpPython( theURL, theStudy, isMultiFile, theListOfFiles );
+
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( theStudy );
+ SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+
+ if(!aModule || !study)
+ return false;
+
+ std::string aTmpDir = study->GetTmpDir( theURL.toLatin1().constData(), isMultiFile );
+
+ theListOfFiles.append( QString( aTmpDir.c_str() ) );
+ int oldSize = theListOfFiles.size();
+
+ aModule->dumpPython( theListOfFiles );
+
+ //Return true if some items have been added, else return false
+ return theListOfFiles.size() > oldSize;
+}
+
//=================================================================================
// function : isModified()
// purpose : default implementation, always returns false so as not to mask study's isModified()
virtual bool saveAs ( const QString&, CAM_Study*, QStringList& );
virtual bool close ();
virtual bool create ( CAM_Study* );
+ virtual bool dumpPython( const QString&,
+ CAM_Study*,
+ bool,
+ QStringList& );
virtual bool isModified () const;
virtual bool isSaved () const;
}
}
+/*
+ * Python dump request.
+ * Called when user activates dump study operation.
+ */
+void SALOME_PYQT_ModuleLight::dumpPython(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::dumpPython()")
+ // perform synchronous request to Python event dispatcher
+ class DumpEvent: public PyInterp_LockRequest
+ {
+ public:
+ DumpEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ QStringList& _files_list)
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myFilesList(_files_list) {}
+ protected:
+ virtual void execute()
+ {
+ myObj->dumpEvent(myFilesList);
+ }
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QStringList& myFilesList;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new DumpEvent( myInterp, this, theListOfFiles ) );
+}
+
+void SALOME_PYQT_ModuleLight::dumpEvent(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::dumpEvent()");
+ QStringList::Iterator it = theListOfFiles.begin();
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || (it == theListOfFiles.end()))
+ return;
+
+ if ( PyObject_HasAttrString(myModule, (char*)"dumpStudy") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"dumpStudy",
+ (char*)"s", (*it).toLatin1().constData()));
+ if( !res ) {
+ PyErr_Print();
+ }
+ else{
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res ) ) {
+ QString astr = PyString_AsString( res );
+ //SCRUTE(astr);
+ theListOfFiles.append(astr);
+ }
+ //also result can be a list...
+ else if ( PyList_Check( res ) ) {
+ int size = PyList_Size( res );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res, i );
+ if( value && PyString_Check( value ) ) {
+ theListOfFiles.append( PyString_AsString( value ) );
+ }
+ }
+ }
+ }
+ }
+}
+
/*
* Open study request.
* Called when user open study.
void setPreferenceProperty( const int, const QString&,
const QVariant& );
- void save(QStringList& theListOfFiles);
-
- bool open(QStringList theListOfFiles);
+ void save(QStringList& theListOfFiles);
+ bool open(QStringList theListOfFiles);
+ void dumpPython(QStringList& theListOfFiles);
/*create new SALOME_PYQT_DataObjectLight and return its entry*/
QString createObject(const QString& parent);
void connectView( const SUIT_ViewWindow* );
void saveEvent(QStringList& theListOfFiles);
+ void dumpEvent(QStringList& theListOfFiles);
void openEvent(QStringList theListOfFiles, bool& opened);
SALOME_PYQT_DataObjectLight* findObject(const QString& entry);
QFileInfo aFileInfo(aFileName);
if( aFileInfo.isDir() ) // IPAL19257
return;
+
+ // Issue 21377 - dump study implementation moved to SalomeApp_Study class
+ bool res = appStudy->dump( aFileName, toPublish, isMultiFile, toSaveGUI );
- int savePoint;
- _PTR(AttributeParameter) ap;
- _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
- if(ip->isDumpPython(appStudy->studyDS())) ip->setDumpPython(appStudy->studyDS()); //Unset DumpPython flag.
- if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method
- ip->setDumpPython(appStudy->studyDS());
- savePoint = SalomeApp_VisualState( this ).storeState(); //SRN: create a temporary save point
- }
- bool res = aStudy->DumpStudy( aFileInfo.absolutePath().toStdString(),
- aFileInfo.baseName().toStdString(),
- toPublish,
- isMultiFile);
- if ( toSaveGUI )
- appStudy->removeSavePoint(savePoint); //SRN: remove the created temporary save point.
if ( !res )
SUIT_MessageBox::warning( desktop(),
QObject::tr("WRN_WARNING"),
return &_lcc;
}
-/*!Return default engine IOR for light modules*/
-QString SalomeApp_Application::defaultEngineIOR()
-{
- /// Look for a default module engine (needed for CORBAless modules to use SALOMEDS persistence)
- QString anIOR( "" );
- CORBA::Object_ptr anEngine = namingService()->Resolve( "/SalomeAppEngine" );
- if ( !CORBA::is_nil( anEngine ) )
- {
- CORBA::String_var objStr = orb()->object_to_string( anEngine );
- anIOR = QString( objStr.in() );
- }
- return anIOR;
-}
-
/*!Private SLOT. On preferences.*/
void SalomeApp_Application::onProperties()
{
static SALOMEDSClient_StudyManager* studyMgr();
static SALOME_NamingService* namingService();
static SALOME_LifeCycleCORBA* lcc();
- static QString defaultEngineIOR();
SUIT_ViewManager* newViewManager(const QString&);
void updateSavePointDataObjects( SalomeApp_Study* );
#include <QCoreApplication>
#include <QEvent>
+#include <QFileInfo>
#include "SALOME_Event.h"
#include "Basics_Utils.hxx"
QListIterator<CAM_DataModel*> it( list );
QStringList listOfFiles;
while ( it.hasNext() ) {
- if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() ) {
+ // Cast to LightApp class in order to give a chance
+ // to light modules to save their data
+ if ( LightApp_DataModel* aModel =
+ dynamic_cast<LightApp_DataModel*>( it.next() ) ) {
listOfFiles.clear();
aModel->saveAs( theFileName, this, listOfFiles );
if ( !listOfFiles.isEmpty() )
QListIterator<CAM_DataModel*> it( list );
QStringList listOfFiles;
while ( it.hasNext() ) {
- if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() ) {
+ // Cast to LightApp class in order to give a chance
+ // to light modules to save their data
+ if ( LightApp_DataModel* aModel =
+ dynamic_cast<LightApp_DataModel*>( it.next() ) ) {
listOfFiles.clear();
aModel->save(listOfFiles);
if ( !listOfFiles.isEmpty() )
}
}
+/*!
+ Dump study operation. Writes a Python dump file using
+ SALOMEDS services. Additionally, gives a chance to light modules
+ to participate in dump study operation.
+
+ \param theFileName - full path to the output Python file
+ \param toPublish - if true, all objects are published in a study
+ by the output script, including those not orignally present
+ in the current study.
+ \param isMultiFile - if true, each module's dump is written into
+ a separate Python file, otherwise a single output file is written
+ \param toSaveGUI - if true, the GUI state is written
+
+ \return - true if the operation succeeds, and false otherwise.
+*/
+bool SalomeApp_Study::dump( const QString& theFileName,
+ bool toPublish,
+ bool isMultiFile,
+ bool toSaveGUI )
+{
+ int savePoint;
+ _PTR(AttributeParameter) ap;
+ _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
+ _PTR(Study) aStudy = studyDS();
+
+ if( ip->isDumpPython( aStudy ) )
+ ip->setDumpPython( aStudy ); //Unset DumpPython flag.
+
+ if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method
+ ip->setDumpPython( aStudy );
+ //SRN: create a temporary save point
+ savePoint = SalomeApp_VisualState(
+ dynamic_cast<SalomeApp_Application*>( application() ) ).storeState();
+ }
+
+ // Issue 21377 - Each data model is asked to dump its data not present in SALOMEDS study.
+ // This is an optional but important step, it gives a chance to light modules
+ // to dump their data as a part of common dump study operation
+ ModelList list;
+ dataModels( list );
+
+ QListIterator<CAM_DataModel*> it( list );
+ QStringList listOfFiles;
+ while ( it.hasNext() ) {
+ if ( LightApp_DataModel* aModel =
+ dynamic_cast<LightApp_DataModel*>( it.next() ) ) {
+ listOfFiles.clear();
+ if ( aModel->dumpPython( theFileName, this, isMultiFile, listOfFiles ) &&
+ !listOfFiles.isEmpty() )
+ // This call simply passes the data model's dump output to SalomeApp_Engine servant.
+ // This code is shared with persistence mechanism.
+ // NOTE: this should be revised if behavior of saveModuleData() changes!
+ saveModuleData(aModel->module()->name(), listOfFiles);
+ }
+ }
+
+ // Now dump SALOMEDS part that also involves SalomeApp_Engine in case if
+ // any light module is present in the current configuration
+ QFileInfo aFileInfo( theFileName );
+ bool res = aStudy->DumpStudy( aFileInfo.absolutePath().toStdString(),
+ aFileInfo.baseName().toStdString(),
+ toPublish,
+ isMultiFile);
+ if ( toSaveGUI )
+ removeSavePoint( savePoint ); //SRN: remove the created temporary save point.
+
+ // Issue 21377 - Clean up light module data in SalomeApp_Engine servant
+ // This code is shared with persistence mechanism.
+ // NOTE: this should be revised if behavior of saveStudyData() changes!
+ saveStudyData( theFileName );
+
+ return res;
+}
+
/*!
\return true, if study is modified in comparison with last open/save
*/
}
/*!
- Saves data from study
+ Re-implemented from LightApp_Study, actually does not save anything but
+ simply cleans up light modules' data
*/
bool SalomeApp_Study::saveStudyData( const QString& theFileName )
{
ModelList list; dataModels( list );
QListIterator<CAM_DataModel*> it( list );
std::vector<std::string> listOfFiles(0);
- while ( it.hasNext() )
- if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() )
- SetListOfFiles(aModel->module()->name().toStdString().c_str(), listOfFiles);
+ while ( it.hasNext() ){
+ LightApp_DataModel* aLModel =
+ dynamic_cast<LightApp_DataModel*>( it.next() );
+ // It is safe to call SetListOfFiles() for any kind of module
+ // because SetListOfFiles() does nothing for full modules :)
+ if ( aLModel )
+ SetListOfFiles(aLModel->module()->name().toStdString().c_str(), listOfFiles);
+ }
return true;
}
_PTR(SComponent) aComp = aStudy->FindComponent(
theDataModel->module()->name().toStdString() );
- if ( aComp )
+ if ( !aComp )
return res;
res = new SalomeApp_ModuleObject( theDataModel, aComp, theParent );
_PTR(Study) aStudy = studyDS();
if (!aStudy)
return;
- _PTR(SComponent) aComp = aStudy->FindComponent(dm->module()->name().toStdString());
+
+ std::string aCompDataType = dm->module()->name().toStdString();
+
+ _PTR(SComponent) aComp = aStudy->FindComponent(aCompDataType);
if (!aComp) {
// Create SComponent
_PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
- aComp = aBuilder->NewComponent(dm->module()->name().toStdString());
+ aComp = aBuilder->NewComponent(aCompDataType);
aBuilder->SetName(aComp, dm->module()->moduleName().toStdString());
QString anIconName = dm->module()->iconName();
if (!anIconName.isEmpty()) {
if (anAttr)
anAttr->SetPixMap(anIconName.toStdString());
}
+
// Set default engine IOR
- aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().toStdString());
+ // Issue 21377 - using separate engine for each type of light module
+ std::string anEngineIOR = SalomeApp_Engine_i::EngineIORForComponent( aCompDataType.c_str(),
+ true );
+ aBuilder->DefineComponentInstance(aComp, anEngineIOR);
//SalomeApp_DataModel::BuildTree( aComp, root(), this, /*skipExisitng=*/true );
SalomeApp_DataModel::synchronize( aComp, this );
}
QString anEngine;
// 1. aModule == 0 means that this is a light module (no CORBA enigine)
if (!aModule) {
- anEngine = SalomeApp_Application::defaultEngineIOR();
- aSComp = aStudy->FindComponent(dm->module()->name().toStdString());
+ // Issue 21377 - using separate engine for each type of light module
+ std::string aCompDataType = dm->module()->name().toStdString();
+ anEngine = SalomeApp_Engine_i::EngineIORForComponent( aCompDataType.c_str(), true ).c_str();
+ aSComp = aStudy->FindComponent( aCompDataType );
}
else {
SalomeApp_DataModel* aDM = dynamic_cast<SalomeApp_DataModel*>( dm );
}
/*!
+ Note that this method does not create or activate SalomeApp_Engine_i instance,
+ therefore it can be called safely for any kind of module, but for full
+ modules it returns an empty list.
\return list of files used by module: to be used by CORBAless modules
\param theModuleName - name of module
*/
std::vector<std::string> SalomeApp_Study::GetListOfFiles( const char* theModuleName ) const
{
- SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
+ // Issue 21377 - using separate engine for each type of light module
+ SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance( theModuleName, false );
if (aDefaultEngine)
- return aDefaultEngine->GetListOfFiles(id(), theModuleName);
+ return aDefaultEngine->GetListOfFiles(id());
std::vector<std::string> aListOfFiles;
return aListOfFiles;
}
/*!
- Sets list of files used by module: to be used by CORBAless modules
+ Sets list of files used by module: to be used by CORBAless modules.
+ Note that this method does not create or activate SalomeApp_Engine_i instance,
+ therefore it can be called safely for any kind of module, but for full
+ modules it simply does nothing.
\param theModuleName - name of module
\param theListOfFiles - list of files
*/
void SalomeApp_Study::SetListOfFiles ( const char* theModuleName,
const std::vector<std::string> theListOfFiles )
{
- SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
+ // Issue 21377 - using separate engine for each type of light module
+ SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance( theModuleName, false );
if (aDefaultEngine)
- aDefaultEngine->SetListOfFiles(theListOfFiles, id(), theModuleName);
+ aDefaultEngine->SetListOfFiles(theListOfFiles, id());
}
/*!
virtual void closeDocument(bool permanently = true);
+ virtual bool dump( const QString&, bool, bool, bool );
+
virtual bool isSaved() const;
virtual bool isModified() const;
virtual void Modified();
//
#include "SalomeApp_Engine_i.hxx"
-#include "SALOMEDS_Tool.hxx"
+#include <SALOME_NamingService.hxx>
+#include <SALOMEDS_Tool.hxx>
+#include <Utils_ORB_INIT.hxx>
+#include <Utils_SINGLETON.hxx>
+#include <Utils_SALOME_Exception.hxx>
+#include <utilities.h>
+
+#include <QApplication>
+#include <QDir>
+#include <QFile>
#include <iostream>
using namespace std;
-SalomeApp_Engine_i* SalomeApp_Engine_i::myInstance = NULL;
-
/*!
Constructor
*/
-SalomeApp_Engine_i::SalomeApp_Engine_i()
+SalomeApp_Engine_i::SalomeApp_Engine_i( const char* theComponentName )
{
- myInstance = this;
+ myComponentName = theComponentName;
+ MESSAGE("SalomeApp_Engine_i::SalomeApp_Engine_i(): myComponentName = "<<
+ myComponentName << ", this = " << this);
}
/*!
*/
SalomeApp_Engine_i::~SalomeApp_Engine_i()
{
+ MESSAGE("SalomeApp_Engine_i::~SalomeApp_Engine_i(): myComponentName = " << myComponentName <<
+ myComponentName << ", this = " << this);
}
SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theComponent,
{
SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile;
- cout << "SalomeApp_Engine_i::Save() isMultiFile = " << isMultiFile << endl;
if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy()))
return aStreamFile._retn();
const int studyId = theComponent->GetStudy()->StudyId();
- cout << "SalomeApp_Engine_i::Save() - studyId = " << studyId << endl;
// Get a temporary directory to store a file
//std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir();
if (myMap.count(studyId)) {
- cout << "SalomeApp_Engine_i::Save() - myMap.count(studyId)" << endl;
- MapOfListOfFiles mapOfListOfFiles = myMap[studyId];
std::string componentName (theComponent->ComponentDataType());
- cout << "SalomeApp_Engine_i::Save() - componentName = " << componentName << endl;
- ListOfFiles listOfFiles = mapOfListOfFiles[componentName];
+
+ // Error somewhere outside - Save() called with
+ // wrong SComponent instance
+ if ( myComponentName != componentName )
+ return aStreamFile._retn();
+
+ const ListOfFiles& listOfFiles = myMap[studyId];
// listOfFiles must contain temporary directory name in its first item
// and names of files (relatively the temporary directory) in the others
if (n > 0) { // there are some files, containing persistent data of the component
std::string aTmpDir = listOfFiles[0];
- cout << "SalomeApp_Engine_i::Save() - aTmpDir = " << aTmpDir << endl;
// Create a list to store names of created files
SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy()))
return false;
+ // Error somewhere outside - Load() called with
+ // wrong SComponent instance
+ std::string componentName (theComponent->ComponentDataType());
+ if ( myComponentName != componentName )
+ return false;
+
const int studyId = theComponent->GetStudy()->StudyId();
// Create a temporary directory for the component's data files
for (int i = 1; i < n; i++)
listOfFiles[i] = std::string(aSeq[i - 1]);
- //MapOfListOfFiles mapOfListOfFiles;
- //if (myMap.count(studyId))
- // mapOfListOfFiles = myMap[studyId];
- //std::string componentName (theComponent->ComponentDataType());
- //mapOfListOfFiles[componentName] = listOfFiles;
- //myMap[studyId] = mapOfListOfFiles;
-
- SetListOfFiles(listOfFiles, studyId, theComponent->ComponentDataType());
+ SetListOfFiles(listOfFiles, studyId);
return true;
}
-SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles (const int theStudyId,
- const char* theComponentName)
+SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles (const int theStudyId)
{
ListOfFiles aListOfFiles;
- if (myMap.count(theStudyId))
+ if (myMap.find(theStudyId) != myMap.end())
{
- MapOfListOfFiles mapOfListOfFiles = myMap[theStudyId];
- std::string componentName (theComponentName);
- if (mapOfListOfFiles.count(componentName))
- aListOfFiles = mapOfListOfFiles[componentName];
+ aListOfFiles = myMap[theStudyId];
}
return aListOfFiles;
}
-void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles theListOfFiles,
- const int theStudyId,
- const char* theComponentName)
+void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles& theListOfFiles,
+ const int theStudyId)
{
- //if (!myMap.count(theStudyId)) {
- // MapOfListOfFiles mapOfListOfFiles;
- // myMap[theStudyId] = mapOfListOfFiles;
- //}
-
- MapOfListOfFiles& mapOfListOfFiles = myMap[theStudyId];
- std::string componentName (theComponentName);
- mapOfListOfFiles[componentName] = theListOfFiles;
+ myMap[theStudyId] = theListOfFiles;
+}
+
+/*!
+ * DumpPython implementation for light modules
+ */
+Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy,
+ CORBA::Boolean isPublished,
+ CORBA::Boolean isMultiFile,
+ CORBA::Boolean& isValidScript)
+{
+ MESSAGE("SalomeApp_Engine_i::DumpPython(): myComponentName = "<<
+ myComponentName << ", this = " << this);
+
+ // Temporary solution: returning a non-empty sequence
+ // even if there's nothing to dump, to avoid crashes in SALOMEDS
+ // TODO: Improve SALOMEDSImpl_Study::DumpStudy() by skipping the components
+ // with isValidScript == false, and initialize isValidScript by false below.
+ Engines::TMPFile_var aStreamFile = new Engines::TMPFile(1);
+ aStreamFile->length( 1 );
+ aStreamFile[0] = '\0';
+ isValidScript = true;
+
+ if (CORBA::is_nil(theStudy))
+ return aStreamFile._retn();
+
+ SALOMEDS::Study_var studyDS = SALOMEDS::Study::_narrow( theStudy );
+ const int studyId = studyDS->StudyId();
+
+ if (!myMap.count(studyId))
+ return aStreamFile._retn();
+
+ ListOfFiles listOfFiles = myMap[studyId];
+
+ // listOfFiles must contain temporary directory name in its first item
+ // and names of files (relatively the temporary directory) in the others
+ if ( listOfFiles.size() < 2 )
+ return aStreamFile._retn();
+
+ // there are some files, containing persistent data of the component
+ QString aTmpPath( listOfFiles.front().c_str() );
+ QDir aTmpDir( aTmpPath );
+ if ( !aTmpDir.exists() )
+ return aStreamFile._retn();
+
+ // Calculate file sizes
+ QStringList aFilePaths;
+ QList<qint64> aFileSizes;
+ qint64 aBuffSize = 0;
+ ListOfFiles::const_iterator aFIt = listOfFiles.begin();
+ ListOfFiles::const_iterator aFEnd = listOfFiles.end();
+ aFIt++;
+ for (; aFIt != aFEnd; aFIt++){
+ QString aFileName( (*aFIt).c_str() );
+ if ( !aTmpDir.exists( aFileName ) ){
+ continue;
+ }
+
+ QFile aFile( aTmpDir.filePath( aFileName ) );
+ if ( !aFile.open( QIODevice::ReadOnly ) ){
+ continue;
+ }
+
+ aFilePaths.push_back( aTmpDir.filePath( aFileName ) );
+ aFileSizes.push_back( aFile.size() );
+ aBuffSize += aFileSizes.back();
+
+ aFile.close();
+ }
+
+ if ( !aFilePaths.size() || !aBuffSize )
+ return aStreamFile._retn();
+
+ char* aBuffer = new char[aBuffSize + 1];
+ if ( !aBuffer )
+ return aStreamFile._retn();
+
+ // Convert the file(s) to the byte stream, multiple files are simply
+ // concatenated
+ // TODO: imporve multi-script support if necessary...
+ qint64 aCurrPos = 0;
+ QStringList::const_iterator aFileIt = aFilePaths.begin();
+ QStringList::const_iterator aFileEnd = aFilePaths.end();
+ QList<qint64>::const_iterator aSIt = aFileSizes.begin();
+ for ( ; aFileIt != aFileEnd; aFileIt++, aSIt++ ){
+ QFile aFile( aTmpDir.filePath( *aFileIt ) );
+ if ( !aFile.open( QIODevice::ReadOnly ) ){
+ continue;
+ }
+
+ // Incorrect size of file
+ // Do not remove the bad file to have some diagnostic means
+ if ( aFile.read( aBuffer + aCurrPos, *aSIt ) != *aSIt ){
+ aFile.close();
+ return aStreamFile._retn();
+ }
+
+ aCurrPos += (*aSIt);
+ aFile.remove();
+ }
+
+ // Here we should end up with empty aTmpDir
+ // TODO: Handle QDir::rmdir() error status somehow...
+ aTmpDir.rmdir( aTmpPath );
+
+ aBuffer[aBuffSize] = '\0';
+ CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer;
+ aStreamFile = new Engines::TMPFile(aBuffSize + 1, aBuffSize + 1, anOctetBuf, 1);
+
+ return aStreamFile._retn();
}
/*!
- \return shared instance of engine
+ \return Component data type string for this instance of the engine
*/
-SalomeApp_Engine_i* SalomeApp_Engine_i::GetInstance()
+char* SalomeApp_Engine_i::ComponentDataType()
{
- return myInstance;
+ return const_cast<char*>( myComponentName.c_str() );
}
+
+/*!
+ \return
+*/
+CORBA::ORB_var SalomeApp_Engine_i::orb()
+{
+ ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
+ // TODO: using QApplication here looks ugly, think how to
+ // obtain the ORB reference in a nicer way...
+ static CORBA::ORB_var _orb = init( qApp->argc(), qApp->argv() );
+ return _orb;
+}
+
+/*!
+ \return
+*/
+PortableServer::POA_var SalomeApp_Engine_i::poa()
+{
+ static PortableServer::POA_var _poa;
+ if ( CORBA::is_nil( _poa ) ){
+ CORBA::Object_var obj = orb()->resolve_initial_references( "RootPOA" );
+ _poa = PortableServer::POA::_narrow( obj );
+ }
+ return _poa;
+}
+
+/*!
+ \return
+*/
+SALOME_NamingService* SalomeApp_Engine_i::namingService()
+{
+ static SALOME_NamingService _ns(orb());
+ return &_ns;
+}
+
+/*!
+ Internal method, creates a CORBA engine for a light SALOME module
+ with the given "component data type" string,
+ activates it and registers in SALOME naming service with
+ /SalomeAppEngine/comp_data_type path. If the engine is already in the
+ naming service, simply returns and object reference to it.
+ \param theComponentName - synthetic "component data type" used to identify a given light module
+ \return Object reference to the CORBA engine
+*/
+CORBA::Object_ptr SalomeApp_Engine_i::engineForComponent( const char* theComponentName,
+ bool toCreate )
+{
+ CORBA::Object_var anEngine;
+ if ( !theComponentName || !strlen( theComponentName ) )
+ return anEngine._retn();
+
+ std::string aPath( "/SalomeAppEngine/" );
+ aPath += theComponentName;
+ anEngine = namingService()->Resolve( aPath.c_str() );
+
+ // Activating a new instance of the servant
+ if ( toCreate && CORBA::is_nil( anEngine ) ){
+ try {
+ SalomeApp_Engine_i* aServant = new SalomeApp_Engine_i( theComponentName );
+ PortableServer::ObjectId_var id = poa()->activate_object( aServant );
+ anEngine = aServant->_this();
+ aServant->_remove_ref();
+ namingService()->Register( anEngine.in(), aPath.c_str() );
+ }
+ catch (CORBA::SystemException&) {
+ INFOS("Caught CORBA::SystemException.");
+ }
+ catch (CORBA::Exception&) {
+ INFOS("Caught CORBA::Exception.");
+ }
+ catch (...) {
+ INFOS("Caught unknown exception.");
+ }
+ }
+
+ return anEngine._retn();
+}
+
+/*!
+ \param theComponentName - synthetic "component data type" used to identify a given light module
+ \return IOR string for the CORBA engine for a light SALOME module
+ with the given "component data type" string
+ \sa GetInstance( const char* theComponentName )
+*/
+std::string SalomeApp_Engine_i::EngineIORForComponent( const char* theComponentName,
+ bool toCreate )
+{
+ std::string anIOR( "" );
+ CORBA::Object_var anEngine = engineForComponent( theComponentName, toCreate );
+ if ( !CORBA::is_nil( anEngine ) )
+ {
+ CORBA::String_var objStr = orb()->object_to_string( anEngine.in() );
+ anIOR = std::string( objStr.in() );
+ }
+ return anIOR;
+}
+
+/*!
+ \param theComponentName - synthetic "component data type" used to identify a given light module
+ \return A pointer to corresponding C++ engine instance, null means some internal problems.
+ \sa EngineIORForComponent( const char* theComponentName )
+*/
+SalomeApp_Engine_i* SalomeApp_Engine_i::GetInstance( const char* theComponentName,
+ bool toCreate )
+{
+ SalomeApp_Engine_i* aServant = 0;
+ CORBA::Object_var anEngine = engineForComponent( theComponentName, toCreate );
+ if ( !CORBA::is_nil( anEngine ) )
+ {
+ PortableServer::Servant aServantBase = poa()->reference_to_servant( anEngine.in() );
+ aServant = dynamic_cast<SalomeApp_Engine_i*>( aServantBase );
+ }
+ MESSAGE("SalomeApp_Engine_i::GetInstance(): theComponentName = " <<
+ theComponentName << ", aServant = " << aServant);
+ return aServant;
+}
+
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SalomeApp_Engine)
+class SALOME_NamingService;
+
class SESSION_EXPORT SalomeApp_Engine_i: public POA_SalomeApp::Engine,
- public Engines_Component_i
+ public Engines_Component_i
{
public:
- SalomeApp_Engine_i();
+ SalomeApp_Engine_i( const char* theComponentName );
~SalomeApp_Engine_i();
SALOMEDS::TMPFile* Save( SALOMEDS::SComponent_ptr theComponent,
const char* theURL,
bool isMultiFile );
+ virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy,
+ CORBA::Boolean isPublished,
+ CORBA::Boolean isMultiFile,
+ CORBA::Boolean& isValidScript);
+
public:
typedef std::vector<std::string> ListOfFiles;
- ListOfFiles GetListOfFiles (const int theStudyId,
- const char* theComponentName);
-
- void SetListOfFiles (const ListOfFiles theListOfFiles,
- const int theStudyId,
- const char* theComponentName);
+ ListOfFiles GetListOfFiles (const int theStudyId);
+ void SetListOfFiles (const ListOfFiles& theListOfFiles,
+ const int theStudyId);
- static SalomeApp_Engine_i* GetInstance();
+ static std::string EngineIORForComponent( const char* theComponentName,
+ bool toCreate );
+ static SalomeApp_Engine_i* GetInstance ( const char* theComponentName,
+ bool toCreate );
public:
// methods from SALOMEDS::Driver without implementation. Must be redefined because
SALOMEDS::TMPFile* SaveASCII( SALOMEDS::SComponent_ptr, const char*, bool ) {return 0;}
CORBA::Boolean LoadASCII( SALOMEDS::SComponent_ptr, const SALOMEDS::TMPFile&, const char*, bool ) {return 0;}
void Close( SALOMEDS::SComponent_ptr ) {}
- char* ComponentDataType() {return 0;}
+ char* ComponentDataType();
char* IORToLocalPersistentID( SALOMEDS::SObject_ptr, const char*, CORBA::Boolean, CORBA::Boolean ) {return 0;}
char* LocalPersistentIDToIOR( SALOMEDS::SObject_ptr, const char*, CORBA::Boolean, CORBA::Boolean ) {return 0;}
bool CanPublishInStudy( CORBA::Object_ptr ) {return 0;}
SALOMEDS::SObject_ptr PasteInto( const SALOMEDS::TMPFile&, CORBA::Long, SALOMEDS::SObject_ptr ) {return 0;}
private:
- typedef std::map<std::string, ListOfFiles> MapOfListOfFiles;
- typedef std::map<int, MapOfListOfFiles> MapOfMapOfListOfFiles;
- MapOfMapOfListOfFiles myMap;
+ static CORBA::ORB_var orb();
+ static PortableServer::POA_var poa();
+ static SALOME_NamingService* namingService();
+ static CORBA::Object_ptr engineForComponent( const char* theComponentName,
+ bool toCreate );
+
+private:
+ typedef std::map<int, ListOfFiles> MapOfListOfFiles;
+ MapOfListOfFiles myMap;
- static SalomeApp_Engine_i* myInstance;
+ std::string myComponentName;
};
#endif
}
case 1: // looking for server type
{
+ // Temporary solution
+ // Issue 21337 - no more SalomeApp_Engine_i activation here
+ // TODO: To be removed as soon as any trace of SalomeAppEngine
+ // has been eliminated from KERNEL scripts
+ if (strcmp(_argv[iarg], "SalomeAppEngine")==0){
+ argState = 0;
+ iarg += 2; // skipping "()"
+ break;
+ }
+ // Temporary solution
+
for (int i=0; i<Session_ServerThread::NB_SRV_TYP; i++)
if (strcmp(_argv[iarg],Session_ServerThread::_serverTypes[i])==0)
{
#include <RegistryService.hxx>
#include "Session_Session_i.hxx"
-#include "SalomeApp_Engine_i.hxx"
#include <Utils_ORB_INIT.hxx>
#include <Utils_SINGLETON.hxx>
using namespace std;
-const int Session_ServerThread::NB_SRV_TYP = 7;
+const int Session_ServerThread::NB_SRV_TYP = 6;
const char* Session_ServerThread::_serverTypes[NB_SRV_TYP] = {"Container",
"ModuleCatalog",
"Registry",
"SALOMEDS",
"Session",
- "SalomeAppEngine",
"ContainerManager"};
/*!
ActivateSession(_argc, _argv);
break;
}
- case 5: // SalomeApp_Engine
- {
- NamingService_WaitForServerReadiness(_NS,"/myStudyManager");
- ActivateEngine(_argc, _argv);
- break;
- }
- case 6: // Container Manager
+ case 5: // Container Manager
{
NamingService_WaitForServerReadiness(_NS,"");
ActivateContainerManager(_argc, _argv);
}
}
-void Session_ServerThread::ActivateEngine(int /*argc*/, char ** /*argv*/)
-{
- try {
- MESSAGE("SalomeApp_Engine thread started");
- SalomeApp_Engine_i* anEngine = new SalomeApp_Engine_i();
- PortableServer::ObjectId_var id =_root_poa->activate_object( anEngine );
- MESSAGE("poa->activate_object( SalomeApp_Engine )");
-
- CORBA::Object_var obj = anEngine->_this();
- anEngine->_remove_ref();
- _NS->Register( obj ,"/SalomeAppEngine");
- }
- catch (CORBA::SystemException&) {
- INFOS("Caught CORBA::SystemException.");
- }
- catch (CORBA::Exception&) {
- INFOS("Caught CORBA::Exception.");
- }
- catch (...) {
- INFOS("Caught unknown exception.");
- }
-}
-
void Session_ServerThread::ActivateSession(int argc,
char ** argv)
{