]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
This commit was generated by cvs2git to create tag 'V4_1_0rc1'. V4_1_0rc1
authoradmin <salome-admin@opencascade.com>
Thu, 17 Jul 2008 11:09:28 +0000 (11:09 +0000)
committeradmin <salome-admin@opencascade.com>
Thu, 17 Jul 2008 11:09:28 +0000 (11:09 +0000)
Sprout from BR_Dev_For_4_0 2007-11-08 11:20:28 UTC mkr <mkr@opencascade.com> 'IMP NPAL13547: Checkbox to kill SALOME completely.'
Cherrypick from V4_1_0_maintainance 2008-07-17 11:09:26 UTC jfa <jfa@opencascade.com> 'Bug 0019869: Compile KERNEL in Werror mode. Integrating KERNEL_SRC_20080710.patch.':
    bin/salome_utilities.py
    doc/salome/salome_application.dox
    src/Batch/Batch_BatchManager_eClient.cxx
    src/Batch/Batch_BatchManager_eClient.hxx
    src/Batch/Batch_BatchManager_eLSF.cxx
    src/Batch/Batch_BatchManager_eLSF.hxx
    src/Batch/Batch_BatchManager_ePBS.cxx
    src/Batch/Batch_BatchManager_ePBS.hxx
    src/Batch/Batch_FactBatchManager_eClient.cxx
    src/Batch/Batch_FactBatchManager_eClient.hxx
    src/Batch/Batch_FactBatchManager_eLSF.cxx
    src/Batch/Batch_FactBatchManager_eLSF.hxx
    src/Batch/Batch_FactBatchManager_ePBS.cxx
    src/Batch/Batch_FactBatchManager_ePBS.hxx
    src/Batch/Batch_JobInfo_eLSF.cxx
    src/Batch/Batch_JobInfo_eLSF.hxx
    src/Batch/Batch_JobInfo_ePBS.cxx
    src/Batch/Batch_JobInfo_ePBS.hxx
    src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx
    src/DSC/DSC_User/Datastream/Calcium/calciumE.h
    src/Launcher/BatchTest.cxx
    src/Launcher/BatchTest.hxx
    src/Launcher/Launcher.cxx
    src/Launcher/Launcher.hxx
    src/ResourcesManager/ResourcesManager.cxx
    src/ResourcesManager/ResourcesManager.hxx
Cherrypick from master 2008-03-07 07:43:41 UTC jfa <jfa@opencascade.com> 'Join modifications from BR_Dev_For_4_0 tag V4_1_1.':
    bin/appliskel/getAppliPath.py
    bin/waitNS.sh
    doc/salome/batch.dox
    doc/salome/install.dox
    doc/salome/kernel_resources.dox
    doc/salome/kernel_services.dox
    doc/salome/main.dox
    doc/salome/salome_file.dox
    doc/salome/tui/KERNEL/sources/kernel_about_4.png
    doc/salome/unittests.dox
    src/DSC/DSC.dox
    src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx
    src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx

39 files changed:
bin/appliskel/getAppliPath.py [new file with mode: 0755]
bin/salome_utilities.py [new file with mode: 0644]
bin/waitNS.sh [new file with mode: 0755]
doc/salome/batch.dox [new file with mode: 0644]
doc/salome/install.dox [new file with mode: 0644]
doc/salome/kernel_resources.dox [new file with mode: 0644]
doc/salome/kernel_services.dox [new file with mode: 0644]
doc/salome/main.dox [new file with mode: 0644]
doc/salome/salome_application.dox [new file with mode: 0644]
doc/salome/salome_file.dox [new file with mode: 0644]
doc/salome/tui/KERNEL/sources/kernel_about_4.png [new file with mode: 0644]
doc/salome/unittests.dox [new file with mode: 0644]
src/Batch/Batch_BatchManager_eClient.cxx [new file with mode: 0644]
src/Batch/Batch_BatchManager_eClient.hxx [new file with mode: 0644]
src/Batch/Batch_BatchManager_eLSF.cxx [new file with mode: 0644]
src/Batch/Batch_BatchManager_eLSF.hxx [new file with mode: 0644]
src/Batch/Batch_BatchManager_ePBS.cxx [new file with mode: 0644]
src/Batch/Batch_BatchManager_ePBS.hxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_eClient.cxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_eClient.hxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_eLSF.cxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_eLSF.hxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_ePBS.cxx [new file with mode: 0644]
src/Batch/Batch_FactBatchManager_ePBS.hxx [new file with mode: 0644]
src/Batch/Batch_JobInfo_eLSF.cxx [new file with mode: 0644]
src/Batch/Batch_JobInfo_eLSF.hxx [new file with mode: 0644]
src/Batch/Batch_JobInfo_ePBS.cxx [new file with mode: 0644]
src/Batch/Batch_JobInfo_ePBS.hxx [new file with mode: 0644]
src/DSC/DSC.dox [new file with mode: 0644]
src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx [new file with mode: 0644]
src/DSC/DSC_User/Datastream/Calcium/calciumE.h [new file with mode: 0644]
src/Launcher/BatchTest.cxx [new file with mode: 0644]
src/Launcher/BatchTest.hxx [new file with mode: 0644]
src/Launcher/Launcher.cxx [new file with mode: 0644]
src/Launcher/Launcher.hxx [new file with mode: 0644]
src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx [new file with mode: 0644]
src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx [new file with mode: 0644]
src/ResourcesManager/ResourcesManager.cxx [new file with mode: 0644]
src/ResourcesManager/ResourcesManager.hxx [new file with mode: 0644]

diff --git a/bin/appliskel/getAppliPath.py b/bin/appliskel/getAppliPath.py
new file mode 100755 (executable)
index 0000000..bac311d
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+import os
+
+def relpath(target, base):
+    """ Find relative path from base to target
+        if target== "/local/chris/appli" and base== "/local/chris" the result is appli
+        if target== /tmp/appli and base /local/chris the result is ../../tmp/appli
+    """
+    target=target.split(os.path.sep)
+    base=base.split(os.path.sep)
+    for i in xrange(len(base)):
+      if base[i] != target[i]:
+        i=i-1
+        #not in base
+        break
+    p=['..']*(len(base)-i-1)+target[i+1:]
+    if p == []:
+      return '.'
+    return os.path.join( *p )
+
+def set_var(VAR, strpath):
+    """Set VAR environment variable """
+    value = "%r" % strpath
+    shell = os.getenv('SHELL')
+    if shell and shell.endswith('csh'):
+        return "setenv %s %s" % (VAR, value)
+    else:
+        return "export %s=%s" % (VAR, value)
+       
+
+applipath=relpath(os.path.abspath(os.path.dirname(__file__)),os.path.abspath(os.getenv('HOME')))
+
+#print set_var('APPLI', applipath)
+print applipath
diff --git a/bin/salome_utilities.py b/bin/salome_utilities.py
new file mode 100644 (file)
index 0000000..b4349cd
--- /dev/null
@@ -0,0 +1,346 @@
+# Copyright (C) 2005  OPEN CASCADE, CEA, EDF R&D, LEG
+#           PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# ---
+#
+# File   : salome_utilities.py
+# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+#
+# ---
+
+"""
+Set of utility functions used by SALOME python scripts.
+"""
+
+#
+# Exported functions
+#
+__all__ = [
+    'getORBcfgInfo',
+    'getHostFromORBcfg',
+    'getPortFromORBcfg',
+    'getUserName',
+    'getHostName',
+    'getShortHostName',
+    'getAppName',
+    'getPortNumber',
+    'getTmpDir',
+    'generateFileName',
+    ]
+
+# ---
+
+def _try_bool( arg ):
+    """
+    Check if specified parameter represents boolean value and returns its value.
+    String values like 'True', 'TRUE', 'YES', 'Yes', 'y', 'NO', 'false', 'n', etc
+    are supported.
+    If <arg> does not represent a boolean, an exception is raised.
+    """
+    import types
+    if type( arg ) == types.BooleanType  :
+        return arg
+    elif type( arg ) == types.StringType  :
+        v = str( arg ).lower()
+        if   v in [ "yes", "y", "true"  ]: return True
+        elif v in [ "no",  "n", "false" ]: return False
+        pass
+    raise Exception("Not boolean value")
+
+# ---
+
+def getORBcfgInfo():
+    """
+    Get omniORB current configuration.
+    Returns a list of three values: [ orb_version, host_name, port_number ].
+    
+    The information is retrieved from the omniORB configuration file defined
+    by the OMNIORB_CONFIG environment variable.
+    If omniORB configuration file can not be accessed, a list of three empty
+    strings is returned.
+    """
+    import os, re
+    ret = [ "", "", "" ]
+    try:
+        f = open( os.getenv( "OMNIORB_CONFIG" ) )
+        lines = f.readlines()
+        f.close()
+        regvar = re.compile( "(ORB)?InitRef.*corbaname::(.*):(\d+)\s*$" )
+        for l in lines:
+            try:
+                m = regvar.match( l )
+                if m:
+                    if m.group(1) is None:
+                        ret[0] = "4"
+                    else:
+                        ret[0] = "3"
+                        pass
+                    ret[1] = m.group(2)
+                    ret[2] = m.group(3)
+                    break
+                pass
+            except:
+                pass
+            pass
+        pass
+    except:
+        pass
+    return ret
+
+# ---
+
+def getHostFromORBcfg():
+    """
+    Get current omniORB host.
+    """
+    return getORBcfgInfo()[1]
+# ---
+
+def getPortFromORBcfg():
+    """
+    Get current omniORB port.
+    """
+    return getORBcfgInfo()[2]
+
+# ---
+
+def getUserName():
+    """
+    Get user name:
+    1. try USER environment variable
+    2. if fails, return 'unknown' as default user name
+    """
+    import os
+    return os.getenv( "USER", "unknown" ) # 'unknown' is default user name
+
+# ---
+
+def getHostName():
+    """
+    Get host name:
+    1. try socket python module gethostname() function
+    2. if fails, try HOSTNAME environment variable
+    3. if fails, try HOST environment variable
+    4. if fails, return 'unknown' as default host name
+    """
+    import os
+    try:
+        import socket
+        host = socket.gethostname()
+    except:
+        host = None
+        pass
+    if not host: host = os.getenv("HOSTNAME")
+    if not host: host = os.getenv("HOST")
+    if not host: host = "unknown"           # 'unknown' is default host name
+    return host
+
+# ---
+
+def getShortHostName():
+    """
+    Get short host name:
+    1. try socket python module gethostname() function
+    2. if fails, try HOSTNAME environment variable
+    3. if fails, try HOST environment variable
+    4. if fails, return 'unknown' as default host name
+    """
+    try:
+        return getHostName().split('.')[0]
+    except:
+        pass
+    return "unknown"           # 'unknown' is default host name
+    
+# ---
+
+def getAppName():
+    """
+    Get application name:
+    1. try APPNAME environment variable
+    2. if fails, return 'SALOME' as default application name
+    """
+    import os
+    return os.getenv( "APPNAME", "SALOME" ) # 'SALOME' is default user name
+
+# ---
+
+def getPortNumber():
+    """
+    Get current naming server port number:
+    1. try NSPORT environment variable
+    1. if fails, try to parse config file defined by OMNIORB_CONFIG environment variable
+    2. if fails, return 2809 as default port number
+    """
+    import os
+    try:
+        return int( os.getenv( "NSPORT" ) )
+    except:
+        pass
+    port = getPortFromORBcfg()
+    if port is not None: return port
+    return 2809      # '2809' is default port number
+
+# ---
+
+def getTmpDir():
+    """
+    Get directory to be used for the temporary files.
+    """
+    import os, sys
+    if sys.platform == "win32":
+        # for Windows: temporarily using home directory for tmp files;
+        # to be replaced with TEMP environment variable later...
+        dir = os.getenv("HOME")
+    else:
+        # for Linux: use /tmp/logs/{user} folder
+        dir = os.path.join( '/tmp', 'logs', getUserName() )
+        pass
+    return dir
+
+# ---
+
+def generateFileName( dir, prefix = None, suffix = None, extension = None,
+                      unique = False, separator = "_", hidden = False, **kwargs ):
+    """
+    Generate file name by sepecified parameters. If necessary, file name
+    can be generated to be unique.
+
+    Parameters:
+    - dir       : directory path
+    - prefix    : file prefix (not added by default)
+    - suffix    : file suffix (not added by default)
+    - extension : file extension (not added by default)
+    - unique    : if this parameter is True, the unique file name is generated:
+    in this case, if the file with the generated name already exists
+    in the <dir> directory, an integer suffix is added to the end of the
+    file name. This parameter is False by default.
+    - separator : separator of the words ('_' by default)
+    - hidden    : if this parameter is True, the file name is prepended by . (dot)
+    symbol. This parameter is False by default.
+
+    Other keyword parameters are:
+    - with_username : 'add user name' flag/option:
+      * boolean value can be passed to determine user name automatically
+      * string value to be used as user name
+    - with_hostname : 'add host name' flag/option:
+      * boolean value can be passed to determine host name automatically
+      * string value to be used as host name
+    - with_port     : 'add port number' flag/option:
+      * boolean value can be passed to determine port number automatically
+      * string value to be used as port number
+    - with_app      : 'add application name' flag/option:
+      * boolean value can be passed to determine application name automatically
+      * string value to be used as application name
+    All <with_...> parameters are optional.
+    """
+    supported = [ 'with_username', 'with_hostname', 'with_port', 'with_app' ]
+    from launchConfigureParser import verbose
+    filename = []
+    # separator
+    if separator is None:
+        separator = ""
+        pass
+    else:
+        separator = str( separator )
+        pass
+    # prefix (if specified)
+    if prefix is not None:
+        filename.append( str( prefix ) )
+        pass
+    # additional keywords
+    ### check unsupported parameters
+    for kw in kwargs:
+        if kw not in supported and verbose():
+            print 'Warning! salome_utilitie.py: generateFileName(): parameter %s is not supported' % kw
+            pass
+        pass
+    ### process supported keywords
+    for kw in supported:
+        if kw not in kwargs: continue
+        ### user name
+        if kw == 'with_username':
+            try:
+                # auto user name ?
+                if _try_bool( kwargs[kw] ): filename.append( getUserName() )
+                pass
+            except:
+                # user name given as parameter
+                filename.append( kwargs[kw] )
+                pass
+            pass
+        ### host name
+        elif kw == 'with_hostname':
+            try:
+                # auto host name ?
+                if _try_bool( kwargs[kw] ): filename.append( getShortHostName() )
+                pass
+            except:
+                # host name given as parameter
+                filename.append( kwargs[kw] )
+                pass
+            pass
+        ### port number
+        elif kw == 'with_port':
+            try:
+                # auto port number ?
+                if _try_bool( kwargs[kw] ): filename.append( str( getPortNumber() ) )
+                pass
+            except:
+                # port number given as parameter
+                filename.append( str( kwargs[kw] ) )
+                pass
+            pass
+        ### application name
+        elif kw == 'with_app':
+            try:
+                # auto application name ?
+                if _try_bool( kwargs[kw] ): filename.append( getAppName() )
+                pass
+            except:
+                # application name given as parameter
+                filename.append( kwargs[kw] )
+                pass
+            pass
+        pass
+    # suffix (if specified)
+    if suffix is not None:
+        filename.append( str( suffix ) )
+        pass
+    # raise an exception if file name is empty
+    if not filename:
+        raise Exception("Empty file name")
+    #
+    if extension is not None and extension.startswith("."): extension = extension[1:]
+    #
+    import os
+    name = separator.join( filename )
+    if hidden: name = "." + name                       # add dot for hidden files
+    if extension: name = name + "." + str( extension ) # add extension if defined
+    name = os.path.join( dir, name )
+    if unique:
+        # create unique file name
+        index = 0
+        while os.path.exists( name ):
+            index = index + 1
+            name = separator.join( filename ) + separator + str( index )
+            if hidden: name = "." + name                       # add dot for hidden files
+            if extension: name = name + "." + str( extension ) # add extension if defined
+            name = os.path.join( dir, name )
+            pass
+        pass
+    return name
diff --git a/bin/waitNS.sh b/bin/waitNS.sh
new file mode 100755 (executable)
index 0000000..3d875f9
--- /dev/null
@@ -0,0 +1,9 @@
+#! /bin/sh
+status=1
+while [ $status -ne 0 ]; do
+  ls $HOME/$APPLI/.omniORB_last.cfg >& /dev/null
+  status=$?
+  sleep 1
+  echo -n "#"
+done
+./runSession waitNS.py
\ No newline at end of file
diff --git a/doc/salome/batch.dox b/doc/salome/batch.dox
new file mode 100644 (file)
index 0000000..7e0e4e2
--- /dev/null
@@ -0,0 +1,10 @@
+/*!
+
+\page batch_page Batch
+
+<a href="Batch.html/index.html"> Batch documentation </a>
+
+*/
+
+
+
diff --git a/doc/salome/install.dox b/doc/salome/install.dox
new file mode 100644 (file)
index 0000000..8090ff9
--- /dev/null
@@ -0,0 +1,378 @@
+/*!
+  \page INSTALL Installation instructions
+
+<b>NOT UP TO DATE %SALOME 4</b>
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+You'll find here generic instructions for installing the SALOME2 platform.
+
+\section Summary
+
+<ol>
+<li> \ref S1_install </li>
+<li> \ref S2_install </li>
+<li> \ref S3_install </li>
+<li> \ref S4_install </li>
+<li> \ref S5_install </li>
+<li> \ref S6_install </li>
+<li> \ref S7_install </li>
+<li> \ref S8_install </li>
+</ol>
+
+\section S1_install Quick Overview
+
+First of all, you have to check (or install if needed) the dependant
+software programs on your system. These programs are:
+
+- common development tools as gcc, automake, autoconf and libtools.
+- third party softwares used in SALOME building or runtime process
+  (python, OCC, VTK, ...)
+
+Further details can be found in sections [2] and [3].
+
+If the dependencies are installed on your system, then you have to set
+your shell environment to get access to the software components
+(cf. [4]. "Preparing the shell environment").
+
+The next step is to install the KERNEL (cf. [5] "Installing KERNEL"):
+
+\code
+$ mkdir <kernel_build>
+$ mkdir <kernel_install>
+$ cd <kernel_src>
+$ ./build_configure
+$ cd <kernel_build>
+$ <kernel_src>/configure --prefix=<kernel_install>
+$ make
+$ make install
+\endcode
+
+Then, the %SALOME components GEOM, MED, VISU, ... can be installed
+with a similar procedure (cf. [6]).
+
+Eventually, the platform ccodean be run by executing the shell script
+runSalome (cf. [7]). Here, somme additionnal variables have to be set
+to describe the %SALOME runtime configuration (<COMPONENT>_ROOT_DIR,
+OMNIORB_CONFIG)
+
+The following provides you with specific instructions for each step.
+
+
+\section S2_install System configuration
+
+%SALOME is compiled and tested on differents platforms with native packages:
+- Debian sarge
+- Mandrake 10.1
+- ...
+
+If you have another platform, we suggest the following configuration
+for building process:
+
+- gcc-3.3.x or 3.4.x
+- automake-1.7 or more (only aclocal is used)
+- autoconf-2.59
+- libtool-1.5.6
+
+remarks:
+
+- This is the minimum level of automake, autoconf and libtool, if you need
+  to compile all the third party softwares (included OpenCascade 5.2.x).
+
+\section S3_install Third-party dependencies
+
+The %SALOME platform relies on a set of third-party softwares. The
+current version depends on the following list
+(versions given here are from Debian Sarge, except OpenCascade, VTK and MED,
+which are not Debian packages):
+
+- CAS-5.2.4            OpenCascade (try binaries,a source patch is needed)
+- VTK-4.2.6            VTK 3D-viewer
+- PyQt-3.13            Python-Qt Wrapper
+- Python-2.3.5         Python interpreter
+- SWIG-1.3.24          SWIG library
+- boost-1_32_0         C++ library (only include templates are used)
+- hdf5-1.6.2           Files Database library
+- med-2.2.2            MED Data Format support for file records 
+- omniORB-4.0.5                ORB used in %SALOME
+- qt-x11-free-3.3.3    Qt library
+- qwt-4.2              Graph components for Qt
+- sip4-4.1.1           langage binding software 
+
+And, in order to build the documentation:
+
+- doxygen-1.4.2
+- graphviz-2.2.1
+
+
+Additionnal software may be installed for optional features: 
+
+- netgen4.3 + patch
+- tix8.1.4
+- openpbs-2.3.16
+- lsf-???
+
+<b>To Do</b>
+
+- Instructions for installing these software programs can be found in a
+  special note doc/configuration_examples/install-prerequis.
+- Installation shell scripts are also provided.
+  These scripts have to be adapted to your own configuration.
+
+- See doc/configuration_examples/*
+
+In the following, we assume that all the third-party softwares are
+installed in the same root directory, named <salomeroot>/prerequis.
+Then, your file system should probably look like::
+
+\code
+<salomeroot>/prerequis/Python-2.2.2
+<salomeroot>/prerequis/omniORB-3.0.5
+<salomeroot>/prerequis/qt-x11-free-3.0.5
+...
+\endcode
+
+\section S4_install Preparing the shell environment
+
+Some variables have to be set to get acces to third-party software
+components (include files, executable, library, ...) during building
+process and runtime.
+
+The shell file prerequis.sh, embedded in the KERNEL source package,
+provides a template for setting those variables. In this example, all the
+softwares are supposed to be installed in the same root directory,
+named here INSTALLROOT.
+
+Copy the prerequis.sh in a working directory and adjust the settings
+to your own configuration. To get the shell prepared, just
+execute the following command in the building shell:
+
+\code
+$ source prerequis.sh
+\endcode
+
+(we assume here a ksh or bash mode)
+
+
+\section S5_install Installing the KERNEL component
+
+We use here the notation <kernel_src> to specify the source directory
+of the KERNEL component. The shell environment is supposed to have
+been set (cf. 4).
+
+Installing the KERNEL from a source package needs three directories:
+
+- the source directory, denoted here by <kernel_src>.
+
+- the build directory, denoted by <kernel_build> in the following. This
+  directory can't be the same directory as <kernel_src>.
+
+- the install directory, denoted by <kernel_install> in the following. This
+  directory can't be the same directory as <kernel_src> or
+  <kernel_build>.
+
+The installing process is:
+
+<b>STEP 1:</b>
+  preparing directories
+
+  create the <kernel_build> and the <kernel_install> directories:
+
+  \code
+$ mkdir <kernel_build>
+$ mkdir <kernel_install>
+\endcode
+
+<b>STEP 2:</b>
+  build configure script
+
+  go to <kernel_src> directory and generate the "configure" script:
+
+  \code
+$ cd <kernel_src>
+$ ./build_configure
+  \endcode
+
+  If it doesn't work, check your system automake tools as specified in
+  section [2].
+
+<b>STEP 3:</b>
+  configure the building process
+  go to the build directory and execute the configuration process::
+
+  \code
+$ cd <kernel_build>
+$ <kernel_src>/configure --prefix=<kernel_install>
+  \endcode
+
+  Note that <kernel_install> must be an absolute path.
+
+  When the configure process is complete, check the status of
+  third-party softwares detection. You should have a status like::
+
+  \code
+    ---------------------------------------------
+    Summary
+    ---------------------------------------------
+    Configure
+           cc : yes
+        boost : yes
+     lex_yacc : yes
+       python : yes
+         swig : yes
+      threads : yes
+       OpenGL : yes
+           qt : yes
+          vtk : yes
+         hdf5 : yes
+         med2 : yes
+      omniORB : yes
+          occ : yes
+          sip : yes
+         pyqt : yes
+          qwt : yes
+      doxygen : yes
+     graphviz : no
+      openpbs : no
+          lsf : no
+    Default ORB   : omniORB
+    ----------------------------------------------
+  \endcode
+
+If a software get a status "no", then it's not "seen" in the system:
+
+- the software is not installed, or
+- the shell environment is not set correctly. 
+
+In this example, the software programs graphviz, openpbs and lsf are not
+installed (optional for most usages).
+
+
+<b>STEP 4 :</b>
+  Building the binary files
+
+  Execute make in the <kernel_build> directory::
+
+  \code
+$ make
+  \endcode
+
+<b>STEP 5:</b>
+  Installing binary files, scripts and documentation
+
+  Execute install target in the <kernel_build> directory::
+
+  \code
+$ make install
+  \endcode
+
+\section S6_install Installing the SALOME components
+
+TInstalling a component <COMPONENT> is done by following the same
+instructions as given for the KERNEL, replacing KERNEL by
+<COMPONENT> (build_configure, configure, make, make install).
+
+You just have to be aware of the dependencies between components:
+
+- MED    depends on KERNEL
+- GEOM   depends on KERNEL
+- SMESH  depends on KERNEL, MED, GEOM
+- VISU   depends on KERNEL, MED
+- SUPERV depends on KERNEL
+
+For example, installing the component SMESH needs the previous
+installation of the KERNEL component, and then the GEOM and MED components.
+
+The building process uses the variables <COMPONENT>_ROOT_DIR to
+localize the dependant components. The variables must be set to the
+install path directory of the components <COMPONENT> (ex:
+KERNEL_ROOT_DIR=<kernel_install>). 
+In the above example, the three variables KERNEL_ROOT_DIR,
+GEOM_ROOT_DIR and MED_ROOT_DIR have to be set before configuring the
+building process of the SMESH component (STEP 3).
+
+
+\section S7_install Runtime
+
+See SALOME_Application to define your own configuration of %SALOME and run it
+on one or several computers. This is the recommended way of configuration.
+
+The following explains the general principles.
+
+To run the %SALOME platform, the procedure is:
+
+- set the shell environment to get acces to third-party softwares:
+
+\code
+$ source prerequis.sh
+\endcode
+
+- define the %SALOME configuration by setting the whole set of
+  variables <COMPONENT>_ROOT_DIR. Here, you just have to set the
+  kernel and the components you need::
+
+  \code
+$ export KERNEL_ROOT_DIR=<kernel_install>
+$ export MED_ROOT_DIR=<med_install>
+$ ...
+  \endcode
+
+- define the CORBA configuration file by setting the variable
+  OMNIORB_CONFIG. This variable must be set to a writable file
+  path. The file may be arbitrary chosen and doesn't need to exist
+  before running. We suggest::
+
+  \code
+$ export OMNIORB_CONFIG=$HOME/.omniORB.cfg
+  \endcode
+
+- run the %SALOME platform by executing the script runSalome:
+
+  \code
+$KERNEL_ROOT_DIR/bin/salome/runSalome
+  \endcode
+
+\section S8_install Suggestions and advices
+
+For convenience or customization, we suggest the following organisation:
+
+- chose and create a root directory for the %SALOME platform, say
+  <salomeroot>.
+
+- install the third-party softwares in a sub-directory "prerequis"
+
+- install the %SALOME components in a sub-directory "SALOME2"
+
+- make personnal copies of the files prerequis.sh and runSalome in
+  <salomeroot>:
+
+  \code
+$ cp <kernel_src>/prerequis.sh <rundir>/.
+$ cp <kernel_install>/bin/salome/runSalome <rundir>/.
+  \endcode
+
+  Edit the file prerequis.sh and adjust it to your own configuration.
+
+- define the SALOME2 configuration
+
+  This step consists in setting the KERNEL_ROOT_DIR, the whole set of
+  variables <COMPONENT>_ROOT_DIR you need, and the OMNIORB_CONFIG
+  variable.
+
+  We suggest to create a shell file envSalome.sh containing those
+  settings. Then the configuration consists in loading envSalome.sh in
+  the runtime shell:
+
+\code
+$ source envSalome.sh
+\endcode
+
+- When installed with this file organisation, running %SALOME is done
+  with the following shell commands::
+
+  \code
+    $ source <salomeroot>/prerequis.sh
+    $ source <salomeroot>/envSalome.sh
+    $ ./runSalome
+  \endcode
+*/
diff --git a/doc/salome/kernel_resources.dox b/doc/salome/kernel_resources.dox
new file mode 100644 (file)
index 0000000..6401e94
--- /dev/null
@@ -0,0 +1,559 @@
+/*!
+
+\page kernel_resources SALOME Kernel resources for developer
+
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+
+\section S1_kernel_res Abstract
+
+This document describes the development environment for 
+C++ and Python. Makefiles generation and usage are 
+introduced in another document: "using the %SALOME 
+configuration and building system environment". 
+Development environment is intended here as: trace and 
+debug macros usage; %SALOME exceptions usage, in C++ and 
+Python; user CORBA exceptions usage, in C++ and Python, 
+with and without Graphical User Interface; some general 
+purpose services such as singleton, used for CORBA 
+connection and disconnection.
+
+\section S2_kernel_res Trace and debug Utilities
+
+During the development process, an execution log is 
+useful to identify problems. This log contains 
+messages, variables values, source files names and line 
+numbers. It is recommended to verify assertions on 
+variables values and if necessary, to stop the 
+execution at debug time, in order to validate all parts 
+of code.
+
+<ol>
+<li>
+<b>Two modes: debug and release</b>
+
+The goal of debug mode is to check as many features as 
+possible during the early stages of the development 
+process. The purpose of the utilities provided in 
+%SALOME is to help the developer to add detailed traces 
+and check variables values, without writing a lot of code.
+
+When the code is assumed to be valid, the release mode 
+optimizes execution, in terms of speed, memory, and 
+display only user level messages.
+
+But, some informations must always be displayed in both 
+modes: especially messages concerning environment or 
+internal errors, with version identification. When an 
+end user is confronted to such a message, he may refer 
+to a configuration documentation or send the message to 
+the people in charge of %SALOME installation, or to the 
+development team, following the kind of error.
+</li>
+<li>
+<b>C++ Macros for trace and debug</b>
+
+%SALOME provides C++ macros for trace and debug. These 
+macros are in:
+
+\code
+KERNEL_SRC/src/SALOMELocalTrace/utilities.h
+\endcode
+
+This file must be included in C++ source. Some 
+macros are activated only in debug mode, others are 
+always activated. To activate the debug mode, ``_DEBUG_``
+must be defined, which is the case when %SALOME 
+Makefiles are generated from configure, without 
+options. When ``_DEBUG_`` is undefined (release mode: 
+``configure --disable-debug --enable-production``), the 
+debug mode macros are defined empty (they do nothing). 
+So, when switching from debug to release, it is 
+possible (and recommended) to let the macro calls 
+unchanged in the source.
+
+All the macros generate trace messages, stored in a 
+circular buffer pool. %A separate %thread reads the 
+messages in the buffer pool, and, depending on options 
+given at %SALOME start, writes the messages on the 
+standard output, a file, or send them via CORBA, in 
+case of a multi machine configuration.
+
+Three informations are systematically added in front of 
+the information displayed:
+
+- the %thread number from which the message come from;
+
+- the name of the source file in which the macros is set;
+
+- the line number of the source file at which the macro 
+  is set.
+
+<ol>  
+<li>
+<b>Macros defined in debug and release modes</b>
+\n
+<b>INFOS_COMPILATION</b>
+
+   The C++ macro INFOS_COMPILATION writes on the trace 
+   buffer pool informations about the compiling process: 
+
+   - the name of the compiler : g++, KCC, CC, pgCC;
+
+   - the date and the time of the compiling processing process.
+
+   This macro INFOS_COMPILATION does not have any 
+   argument. Moreover, it is defined in both compiling 
+   mode : _DEBUG_ and _RELEASE_.
+
+   Example:
+
+   \code
+#include "utilities.h"
+int main(int argc , char **argv) 
+{ 
+  INFOS_COMPILATION;
+  ...
+}
+INFOS(str)
+  \endcode
+\n
+<b>INFOS</b>
+
+   In both compiling mode _DEBUG_ and _RELEASE_, The C++ 
+   macro INFOS writes on the trace buffer pool %the string 
+   which has been passed in argument by the user.
+
+   Example:
+
+   \code
+#include "utilities.h"
+int main(int argc , char **argv)
+{ 
+  ... 
+  INFOS("NORMAL END OF THE PROCESS"); 
+  return 0; 
+}
+   \endcode
+
+   Displays:
+
+   \code
+main.cxx [5] : NORMAL END OF THE PROCESS
+   \endcode
+\n
+<b>INTERRUPTION(str)</b>
+
+   In both compiling mode _DEBUG_ and _RELEASE_, The C++ 
+   macro INTERRUPTION writes on the trace buffer pool the 
+   %string, with a special ABORT type. When the %thread in 
+   charge of collecting messages finds this message, it 
+   terminates the application, after message treatment.
+
+<b>IMMEDIATE_ABORT(str)</b>
+
+   In both compiling mode _DEBUG_ and _RELEASE_, The C++ 
+   macro IMMEDIATE_ABORT writes the message str immediately on 
+   standard error and exits the application. Remaining 
+   messages not treated by the message collector %thread 
+   are lost.
+
+</li>
+<li>
+<b>Macros defined only in debug mode</b>
+\n 
+<b>MESSAGE(str)</b>
+
+   In _DEBUG_ compiling mode only, the C++ macro MESSAGE 
+   writes on the trace buffer pool the %string which has 
+   been passed in argument by the user. In _RELEASE_ 
+   compiling mode, this macro is blank.
+
+   Example:
+
+   \code
+#include "utilities.h" 
+#include <string> 
+
+using namespace std; 
+
+int main(int argc , char **argv) 
+{ 
+  ... 
+  const char *str = "Salome";
+  MESSAGE(str);
+  ... const string st; 
+  st = "Aster"; 
+  MESSAGE(c_str(st+" and CASTEM")); 
+  return 0;
+}
+
+   \endcode
+
+   Displays:
+
+   \code
+- Trace main.cxx [8] : Salome
+- Trace main.cxx [12] : Aster and CASTEM
+   \endcode
+
+\n
+<b>BEGIN_OF(func_name)</b>
+
+   In _DEBUG_ compiling mode, The C++ macro BEGIN_OF 
+   appends the %string "Begin of " to the one passed in 
+   argument by the user and displays the result on the 
+   trace buffer pool. In _RELEASE_ compiling mode, this 
+   macro is blank.
+
+   Example:
+
+   \code
+#include "utilities.h" 
+int main(int argc , char **argv) 
+{ 
+  BEGIN_OF(argv[0]);
+  return 0;
+}
+   \endcode
+
+   Displays:
+
+   \code
+     - Trace main.cxx [3] : Begin of a.out
+   \endcode
+\n
+<b>END_OF(func_name)</b>
+
+   In _DEBUG_ compiling mode, The C++ macro END_OF appends 
+   the %string "Normal end of " to the one passed in 
+   argument by the user and displays the result on the 
+   trace buffer pool. In _RELEASE_ compiling mode, this 
+   macro is blank.
+
+   Example:
+
+   \code
+#include "utilities.h" 
+int main(int argc , char **argv) 
+{ 
+  END_OF(argv[0]);
+  return 0; 
+}
+  \endcode
+
+   Displays:
+
+   \code
+- Trace main.cxx [4] : Normal end of a.out
+   \endcode
+\n
+<b>SCRUTE(var)</b>
+
+   In _DEBUG_ compiling mode, The C++ macro SCRUTE 
+   displays its argument which is an application variable 
+   followed by the value of the variable. In _RELEASE_ 
+   compiling mode, this macro is blank.
+
+   Example:
+
+   \code
+#include "utilities.h"
+int main(int argc , char **argv) 
+{ 
+  const int i=999;
+  if( i > 0 ) SCRUTE(i) ; i=i+1;
+  return 0;
+}
+   \endcode
+
+   Displays:
+
+   \code
+- Trace main.cxx [5] : i=999
+   \endcode
+\n
+<b>ASSERT(condition)</b>
+
+   In _DEBUG_ compiling mode only, The C++ macro ASSERT 
+   checks the expression passed in argument to be not 
+   NULL. If it is NULL the condition is written with the 
+   macro INTERRUPTION (see above). The process exits after 
+   trace of this last message. In _RELEASE_ compiling 
+   mode, this macro is blank. N.B. : if ASSERT is already 
+   defined, this macro is ignored.
+
+   Example:
+
+   \code
+#include "utilities.h" 
+... 
+const char *ptrS = fonc();
+ASSERT(ptrS!=NULL); 
+cout << strlen(ptrS); 
+float table[10];
+int k;
+... 
+ASSERT(k<10);
+cout << table[k];
+   \endcode
+
+</li>
+</ol>
+</li>
+</ol>
+
+\section S3_kernel_res Exceptions
+
+<ol>
+<li>
+<b>C++ exceptions: class SALOME_Exception</b>
+
+<ol>
+<li>
+<b>definition</b>
+
+The class SALOME_Exception provides a generic method to 
+send a message, with optional source file name and line 
+number. This class is intended to serve as a base class 
+for all kinds of exceptions %SALOME code. All the 
+exceptions derived from SALOME_Exception could be 
+handled in a single catch, in which the message 
+associated to the exception is displayed, or sent to a 
+log file.
+
+The class SALOME_Exception inherits its behavior from 
+the STL class exception.
+</li>
+<li>
+<b>usage</b>
+
+The header %SALOME/src/utils/utils_SALOME_Exception.hxx 
+must be included in the C++ source, when raised or trapped:
+
+\code
+#include "utils_SALOME_Exception.hxx"
+\endcode
+
+The SALOME_Exception constructor is:
+
+\code
+SALOME_Exception( const char *text,
+                  const char *fileName=0, 
+                  const unsigned int lineNumber=0 );
+\endcode
+
+The exception is raised like this:
+
+\code
+throw SALOME_Exception("my pertinent message");
+\endcode
+
+or like this:
+
+\code
+throw SALOME_Exception(LOCALIZED("my pertinent message"));
+\endcode
+
+where LOCALIZED is a macro provided with 
+``utils_SALOME_Exception.hxx`` which gives file name and 
+line number.
+
+The exception is handled like this:
+
+\code
+   try
+{
+  ...
+}
+catch (const SALOME_Exception &ex)
+{
+  cerr << ex.what() <<endl;
+}
+\endcode
+
+The what() method overrides the one defined in the STL 
+exception class.
+</li>
+</ol>
+</li>
+<li>
+<b>CORBA exceptions</b>
+
+<ol>
+<li>
+<b>definition</b>
+
+The idl SALOME_Exception provides a generic CORBA 
+exception for %SALOME, with an attribute that gives an 
+exception type,a message, plus optional source file 
+name and line number. 
+
+This idl is intended to serve for all user CORBA 
+exceptions raised in %SALOME code, as IDL specification 
+does not support exception inheritance. So, all the 
+user CORBA exceptions from %SALOME could be handled in a 
+single catch.
+
+The exception types defined in idl are:
+
+  - COMM CORBA communication problem,
+
+  - BAD_PARAM Bad User parameters,
+
+  - INTERNAL_ERROR application level problem (often irrecoverable).
+
+CORBA system and user exceptions already defined in the 
+packages used within %SALOME, such as OmniORB 
+exceptions, must be handled separately.
+
+</li>
+<li>
+<b>usage</b>
+<ol>
+<li>
+<b>CORBA servant, C++</b>
+
+   The CORBA Server header for SALOME_Exception and a 
+   macro to throw the exception are provided with the 
+   header ``KERNEL_SRC/src/Utils/Utils_CorbaException.hxx``:
+
+   \code
+#include "Utils_CorbaException.hxx"
+   \endcode
+
+   The exception is raised with a macro which appends file 
+   name and line number:
+
+   \code
+if (myStudyName.size() == 0)
+  THROW_SALOME_CORBA_EXCEPTION("No Study Name given", 
+                               SALOME::BAD_PARAM);
+   \endcode
+
+</li>
+<li>
+<b>CORBA Client, GUI Qt C++</b>
+
+   <b>NO MORE AVAILABLE in %SALOME 3.x</b>
+
+   The CORBA Client header for SALOME_Exception and a Qt 
+   function header that displays a message box are 
+   provided in:
+
+     ``KERNEL_SRC/src/SALOMEGUI/SALOMEGUI_QtCatchCorbaException.hxx``
+
+   \code
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+   \endcode
+
+   %A typical exchange with a CORBA Servant will be:
+
+   \code
+try
+{
+ ... // one ore more CORBA calls
+}
+
+catch (const SALOME::SALOME_Exception & S_ex)
+{
+  QtCatchCorbaException(S_ex);
+}
+   \endcode
+
+</li>
+<li>
+<b>CORBA Client, C++, without GUI</b>
+
+  Nothing specific has been provided to the developer 
+  yet. See the idl or the Qt function 
+  SALOMEGUI_QtCatchCorbaException.hxx to see how to get 
+  the information given by the exception %object.
+
+</li>
+</ol>
+</li>
+</ol>
+</ol>
+
+\section S4_kernel_res Miscellaneous tools
+
+<ol>
+<li>
+<b>Singleton</b>
+<ol>
+<li>
+<b>Definition</b>
+
+%A singleton is an application data which is created and 
+deleted only once at the end of the application 
+process. The C++ compiler allows the user to create a 
+static singleton data before the first executable 
+statement. They are deleted after the last statement execution.
+
+The ``SINGLETON_`` template class deals with dynamic 
+singleton. It is useful for functor objects. For 
+example, an %object that connects the application to a 
+system at creation and disconnects the application at deletion.
+
+</li>
+<li>
+<b>Usage</b>
+
+To create a single instance of a POINT %object:
+
+\code
+# include "Utils_SINGLETON.hxx"
+... 
+POINT *ptrPoint=SINGLETON_<POINT>::Instance() ; 
+assert(ptrPoint!=NULL) ;
+\endcode
+
+No need to delete ptrPoint. Deletion is achieved 
+automatically at exit. If the user tries to create more 
+than one singleton by using the class method 
+SINGLETON_<TYPE>::Instance(), the pointer is returned 
+with the same value even if this is done in different 
+functions (threads ?):
+
+\code
+POINT *p1=SINGLETON_<POINT>::Instance() ;
+... 
+POINT *p2=SINGLETON_<POINT>::Instance() ; 
+
+assert(p1==p2)
+\endcode
+
+</li>
+<li>
+<b>Design description</b>
+
+Here are the principles features of the singleton 
+design:
+
+- the user creates an %object of class TYPE by using the 
+  class method ``SINGLETON_<TYPE>::Instance()`` which 
+  returns a pointer to the single %object ;
+
+- to create an %object, ``SINGLETON_<TYPE>::Instance()`` 
+  uses the default constructor of class TYPE ;
+
+- at the same time, this class method creates a 
+  destructor %object which is added to the generic list 
+  of destructor objects to be executed at the end of 
+  the application (atexit) ;
+
+- at the end of the application process all the 
+  deletions are performed by the ``Nettoyage()`` C function 
+  which executes the destruction objects end then 
+  deletes the destructions objects themselves ;
+
+- the ``Nettoyage()`` C  function using ``atexit()`` C  function 
+  is embedded in a static single %object ``ATEXIT_()``.
+
+</li>
+</ol>
+</li>
+</ol>
+
+*/
diff --git a/doc/salome/kernel_services.dox b/doc/salome/kernel_services.dox
new file mode 100644 (file)
index 0000000..d363c84
--- /dev/null
@@ -0,0 +1,236 @@
+/*!
+  \page KERNEL_Services KERNEL Services for end user (Python interface)
+
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+In a %SALOME application, distributed components, servers and clients use
+the CORBA middleware for comunication. CORBA interfaces are defined via idl
+files. All the different CORBA interfaces are available for users in Python,
+see CORBA interfaces below.
+
+For some general purpose services, CORBA interfaces have been encapsulated
+in order to provide a simple interface (encapsulation is generally done in
+C++ classes, and a Python SWIG interface is also generated from C++, to 
+ensure a consistent behavior between C++ modules and Python modules or user
+script).
+
+\section S1_kernel_ser General purpose services
+
+<ol>
+<li>
+<b>%SALOME services access from a Python shell</b>
+
+See \ref SALOME_Application for detailed instructions to launch a Python
+interpreter with full acces to the %SALOME environment and services.
+
+You can use the embedded Python interpreter in Grahic User Interface, or an
+external interpreter, with:
+
+\code
+./runSession
+python
+\endcode
+
+In either cases, %SALOME services access is done with:
+
+\code
+import salome
+salome.salome_init()
+\endcode
+
+In the embedded interpreter, it is already done, but there is no problem to
+do it several times, so it is preferable to add these instructions
+systematically in your scripts, to allow them to work in all configurations.
+
+</li>
+<li>
+<b>Container and component instanciation</b>
+
+See LifeCycleCORBA for the C++ interface (Python interface obtained with SWIG
+is very similar).
+
+In the following example, a test component provided in KERNEL is launched
+in the local container, "FactoryServer", created when %SALOME starts:
+
+\code
+import salome
+salome.salome_init()
+   
+import LifeCycleCORBA
+lcc = LifeCycleCORBA.LifeCycleCORBA()
+obj=lcc.FindOrLoad_Component("FactoryServer","SalomeTestComponent")
+   
+import Engines
+comp=obj._narrow(Engines.TestComponent)
+comp.Coucou(1)
+\endcode   
+
+The answer is something like:
+
+\code
+'TestComponent_i : L = 1'
+\endcode
+
+The _narrow() instruction is not always mandatory in Python, but sometimes 
+useful to be sure you have got the right type of %object. Here, Testcomponent
+interface is defined in CORBA module Engines. With this example, it works also
+without the _narrow() instruction:
+
+\code
+   obj.Coucou(1)
+\endcode
+
+In the next example, a component instance is created in a specific Container
+defined by it's computer hostname and it's name. Here we use the local
+computer. Note that in Utils_Identity, getShortHostName() gives the short
+hostname of the computer, without domain suffixes, which is used in %SALOME.
+The container process is created here if it does not exists, and a new
+component instance is created:
+
+\code
+import salome
+salome.salome_init()
+import LifeCycleCORBA
+lcc = LifeCycleCORBA.LifeCycleCORBA()
+
+import Utils_Identity
+host  = Utils_Identity.getShortHostName()
+
+import Engines
+params={}
+params['hostname']=host
+params['container_name']='myContainer'
+comp=lcc.LoadComponent(params,'SalomeTestComponent')
+comp.Coucou(1)
+\endcode
+
+If you want to get a list of containers and component instances, client %object
+from orbmodule provides a list:
+
+\code
+import orbmodule
+clt=orbmodule.client()
+clt.showNS()
+\endcode
+
+The list looks like:
+
+\code
+Logger.
+ContainerManager.object
+Containers.dir
+  cli70ac.dir
+    FactoryServerPy.object
+    SuperVisionContainer.object
+    FactoryServer.object
+    FactoryServer.dir
+      SalomeTestComponent_inst_1.object
+    myContainer.object
+    myContainer.dir
+      SalomeTestComponent_inst_1.object
+      SalomeTestComponent_inst_2.object
+Registry.object
+Kernel.dir
+  ModulCatalog.object
+  Session.object
+Study.dir
+  Study2.object
+  extStudy_1.object
+  extStudy_2.object
+  extStudy_3.object
+myStudyManager.object
+SalomeAppEngine.object
+\endcode
+
+</li>
+<li>
+<b>File transfer service</b>
+
+See SALOME_FileTransferCORBA for the C++ interface (Python interface obtained with
+SWIG is very similar).
+
+The following example shows how to tranfer a file from a remote host to the
+client computer. Remote hostname is 'cli76cc', we would like to copy
+'tkcvs_8_0_3.tar.gz' from remote to local computer. %A full pathname is
+required. %A container is created on remote computer if it does not exist,
+to handle the file transfer:
+
+\code
+import salome
+salome.salome_init()
+
+import LifeCycleCORBA
+remotefile="/home/prascle/tkcvs_8_0_3.tar.gz"
+aFileTransfer=LifeCycleCORBA.SALOME_FileTransferCORBA('cli76cc',remotefile)
+localFile=aFileTransfer.getLocalFile()
+\endcode
+
+</li>
+<li>
+<b>CORBA Naming service access</b>
+
+See SALOME_NamingService for the C++ interface. The Python interface
+SALOME_NamingServicePy is not yet derived from the C++ interface and offers
+only the most useful functions.
+
+</li>
+<li>
+<b>Batch services</b>
+
+See \ref batch_page documentation (in french only).
+
+</li>
+</ol>
+
+\section S2_kernel_ser All IDL Interfaces
+
+<ol>
+<li>
+<b>Containers and component life cycle, File transfer service</b>
+
+- Engines : engines CORBA module.                         
+- Engines::Component : generic component interface. All %SALOME components inherit this interface.
+- Engines::Container : host for C++ and Python components components instances                          
+- Engines::fileTransfer : agent for file transfer created by a container copy a local file to a distent client         
+- Engines::fileRef : reference to a file, used by a container for file transfers                                
+- Engines::ContainerManager : unique instance, in charge of container creation on remote computers                  
+- Engines::MPIContainer : an exemple of parallel implementation for containers and components                     
+- Engines::MPIObject
+
+</li>
+<li>
+<b>Study management</b>
+
+- SALOMEDS : SALOMEDS CORBA module
+- SALOMEDS.idl
+- SALOMEDS_Attributes.idl
+
+</li>
+<li>
+<b>High speed transfer, object life cycle, exceptions, GUI interface...</b>
+
+- SALOME : %SALOME CORBA module
+- SALOME_Comm.idl
+- SALOME_GenericObj.idl
+- SALOME_Exception
+- SALOME_Session.idl
+
+</li>
+<li>
+<b>Miscelleanous</b>
+
+- SALOME_ModuleCatalog
+- SALOME_RessourcesCatalog
+- SALOME_Registry.idl
+- Logger.idl
+
+<b>Other idl for test purposes</b>
+\n
+- nstest.idl
+- SALOME_TestComponent.idl
+- SALOME_TestModuleCatalog.idl
+- SALOME_TestMPIComponent.idl
+- TestNotif.idl
+
+*/
diff --git a/doc/salome/main.dox b/doc/salome/main.dox
new file mode 100644 (file)
index 0000000..7515c35
--- /dev/null
@@ -0,0 +1,82 @@
+/*! \mainpage  SALOME KERNEL Reference Documentation
+    \image html kernel_about_4.png
+
+    \section S1_main Introduction
+
+    Welcome to the %SALOME KERNEL documentation !
+
+    Following your kind of usage of %SALOME, you will find some specific 
+    introductory documentation, listed below.
+
+    \section S2_main End user
+
+<ol>
+  <li> 
+    <b>How to configure a %SALOME application</b>
+    \n The end user may have to configure his own %SALOME application by selection of a
+    subset of availables %SALOME modules. He also may want to install his
+    application on several computers. 
+    See \subpage SALOME_Application to define your own configuration of %SALOME and run it  
+    on one or several computers. This is the recommended way of configuration.
+  </li>
+  <li>
+    <b>How to launch %SALOME in a %SALOME application</b>
+    \n See \ref SALOME_Application.
+  </li>
+  <li>
+    <b>How to use KERNEL services in Python scripts</b>
+    \n The %SALOME KERNEL offers a list of services available in Python. See \subpage KERNEL_Services.
+  </li>
+</ol>  
+
+    \section S3_main Application Integrator
+
+    Applications integrators are in charge of configuration and installation of
+    specific %SALOME applications over a local network. Application Integrators 
+    built %SALOME modules binaries from sources tarballs.
+
+<ol>
+  <li> 
+    <b>How to install %SALOME</b>
+    \n See \subpage INSTALL for general information on required configuration and 
+    prerequisites, compilation procedure, setting environment principles.
+  </li>
+  <li>
+    <b>How to configure a %SALOME application</b>
+    \n See \ref SALOME_Application to define your own configuration of %SALOME and run it  
+    on one or several computers. This is the recommended way of configuration.
+  </li>
+</ol>
+
+    \section S4_main Module maintainer
+
+    Module maintainers are in charge of the development and debug of the %SALOME
+    modules. Each %SALOME module is stored in a CVS base. CVS bases are organised
+    in separate branches for developments and debug. All official or development
+    releases are identified by a CVS tag.
+
+<ol>
+  <li> 
+    <b>Source code structuration and Unit Tests</b>
+    \n See \subpage UnitTests for general information on code directories structure,
+    unit tests associated to the different kind of classes, and how to run
+    the unit tests.
+  </li>
+  <li> 
+    <b>Some development utilities</b> 
+    \n See \subpage kernel_resources for information on basic utilities for C++ and Python
+    development, like trace and debug, exceptions, singleton.
+  </li>
+</ol>
+
+    \section S5_main SALOME programming model
+
+    You will find in the next pages informations about
+    specific points of %SALOME Kernel :
+
+    - \subpage dsc_page : DSC documentation page.
+    - \subpage salome_file_page : Salome_file documentation page.
+    - \subpage batch_page : BATCH documentation page.
+
+*/
+
diff --git a/doc/salome/salome_application.dox b/doc/salome/salome_application.dox
new file mode 100644 (file)
index 0000000..d970338
--- /dev/null
@@ -0,0 +1,377 @@
+/*!
+  \page SALOME_Application SALOME Application Concept 
+
+  <b>Configuration for one or more computers</b>
+
+
+<b> **WORK in PROGRESS, INCOMPLETE DOCUMENT** </b>
+
+The following explains how to configure your own application with your list of
+modules, how to define and run this application on one or more computers.
+
+\section S1_sal_appl General principles
+
+%A %SALOME application is defined by a set of modules (GEOM, SMESH, ASTER...).
+
+%A %SALOME User can define several %SALOME Applications. These applications are
+runnable from the same user account. These applications may share the same 
+KERNEL and modules. Thus, the application configuration is independant of
+KERNEL and must not be put in KERNEL_ROOT_DIR.
+
+Furthermore, prerequisites may not be the same on all the applications.
+
+%A %SALOME Session can run on a several computers.
+
+Binary modules and prerequisites are installed on the different computers.
+There is no need to have all the modules on each computer (the minimum is
+KERNEL).
+
+There is no need of standardization or centralised information on the details
+of configuration on each computer (PATH, LD_LIBRARY_PATH, environment
+variables) provided the application modules are version - compatible. Details
+of configuration stay private to the computer, and are held by scripts on each
+computer.
+
+There is no hierarchy between the computers (for example only one master
+computer used to launch application).
+
+The %SALOME user has an account on all the computers. Access between
+account@computer is via rsh or ssh and must be configured for use without
+password (key exchange for ssh). Account may be different on each
+computer.
+
+\section S2_sal_appl Application Directory
+
+There are two ways for creation of an application directory, <b>the recommended way is
+the second, easier to configure.</b>
+
+<ol>
+  <li> 
+    <b>First way - references to different module directories</b>
+
+The script createAppli.sh in ${KERNEL_ROOT_DIR}/bin/salome creates an
+application directory with the given path in parameter. The path given, ${APPLI}, is 
+relative to ${HOME}.
+
+The directory is only a skeleton, the user has to edit several files to
+configure his own application. These files are described after, the list is:
+
+- env.d/atFirst.sh
+- env.d/envProducts.sh
+- env.d/envSALOME.sh
+- CatalogResources.xml
+- SALOMEApp.xml
+
+  </li>
+  <li>
+  <b>Second and easiest way - one single virtual install directory</b>
+
+The user must create a %SALOME application configuration file by modifying a
+copy of ${KERNEL_ROOT_DIR}/bin/salome/config_appli.xml.
+The file describes the list of %SALOME modules used in the application, with
+their respective installation path. The configuration file also defines the
+path of an existing script which sets the %SALOME prerequisites,
+and optionnaly, the path of samples directory (SAMPLES_SRC).
+The following command::
+
+\code
+python <KERNEL_ROOT_DIR>/bin/salome/appli_gen.py --prefix=<install directory> --config=<configuration file>
+\endcode
+
+creates a virtual installation of %SALOME in the application directory ${APPLI}
+(bin, lib, doc, share...), with, for each file (executable, script, data,
+library, resources...), symbolic links to the actual file.
+<b>Note: it is recommended to set the environment for %SALOME prerequisites
+before invoking the above command, in order to use the same python as SALOME,
+otherwise installation may be wrong</b>
+
+Providing an existing script for %SALOME prerequisites (the same one
+used for modules compilation, or given with the modules installation), the
+installation works without further modification for a single computer (unless
+some modules needs a special environment not defined in the above script).
+For a distributed application (several computers), one must copy and adapt
+CatalogResources.xml from ${KERNEL_ROOT_DIR}/bin/salome/appliskel (see below).
+  </li>
+</ol>  
+
+\section S3_sal_appl General rules
+
+Directory ${APPLI} must be created on each computer of the application.
+The easiest way is to use the same relative path (to ${HOME}) on each computer.
+(Sometimes it is not possible to use the same path everywhere, for instance
+when ${HOME} is shared with NFS, so it is possible to define different path
+following the computers).
+
+The ${APPLI} directory contains scripts for environment and runs. Environment
+scripts must be configured (by the user) on each computer. All the environment
+scripts are in the ${APPLI}/env.d directory. 
+
+The script  ${APPLI}/envd sources **all** the files (\*.sh) in ${APPLI}/env.d
+in alphanumeric order (after edition, think to remove backup files). the envd
+script is used by run scripts.
+
+<ol>
+  <li>
+<b>env.d scripts</b>
+
+With the first way of installation, each user **must define** his own
+configuration for these scripts, following the above rules.
+<b>With the virtual installation (second way, above), env.d
+scripts are built automatically.</b>
+
+ **The following is only an example proposed by createAppli.sh, (first way of installation) not working as it is**.
+
+- atFirst.sh
+    Sets the computer configuration not directly related to %SALOME,
+    like useful tools, default PATH.
+
+- envProducts.sh
+    Sets the %SALOME prerequisites.
+
+- envSALOME.sh
+    Sets all the MODULE_ROOT_DIR that can be used in the %SALOME application.
+
+    SALOMEAppConfig is also defined by:
+
+\code
+export SALOMEAppConfig=${HOME}/${APPLI}
+\endcode
+
+    where SALOMEAppConfig designates the directory containing SALOMEApp.xml. 
+    Note that ${APPLI} is already defined by the calling scripts when 
+    env.d/envSALOME.sh is sourced.
+  </li>
+  <li>
+<b>User run scripts</b>
+
+The %SALOME user can use 4 scripts:
+
+- runAppli
+   Launches a %SALOME Session
+   (similar to ${KERNEL_ROOT_DIR}/bin/salome/runSalome but with a different
+   name to avoid confusions). See parameters below.
+
+- runSession
+   Launches a shell script in the %SALOME application environment, with access
+   to the current (last launched) %SALOME session (naming service), if any.
+   Without arguments, the script is interactive. With arguments, the script
+   executes the command in the %SALOME application environment.
+
+- runConsole
+   Gives a python console connected to the current %SALOME Session.
+   It is also possible to use runSession, then python.
+
+- runTests
+   Similar to runSession, used for unit testing, but runSession tries to use an
+   already existing naming service definition from a running session (hostname
+   and port number), and runTests defines a new configuration for naming service
+   (new port number).
+  </li>
+  <li>
+<b>%SALOME internal run scripts</b>
+
+- envd
+   Sets %SALOME application environment, envd is sourced by other scripts.
+
+For remote calls, %SALOME uses one script.
+
+- runRemote.sh
+   This script is mainly used to launch containers. The first 3 arguments
+   define the hostname and port userd for naming service, plus a working directory, the remaining
+   arguments define the command to execute.
+  </li>
+  <li>
+<b>Other configuration files</b>
+
+- SALOMEApp.xml
+   This file is similar to the default given
+   in ${GUI_ROOT_DIR}/share/SALOME/resources/gui
+
+
+- CatalogRessources.xml
+   This files describes all the computers the application can use. The given
+   example is minimal and suppose ${APPLI} is the same relative path
+   to ${HOME}, on all the computers. %A different directory can be set on a
+   particular computer with a line:
+
+\code
+appliPath="my/specific/path/on/this/computer"
+\endcode
+
+  </li>
+</ol>
+
+\section S4_sal_appl Examples of use
+
+<ol>
+  <li>
+<b>Launch a %SALOME session with a GUI interface</b>
+
+Launch is done with a command like::
+
+\code
+./runAppli --logger
+\endcode
+
+The --logger option means here : collect all the traces from the all the
+distributed process, via CORBA, in a single file : logger.log.
+
+There are a lot of options, a complete list is given by::
+
+\code
+./runAppli --help
+\endcode
+
+Note that, without argument, runAppli is a non interactive Python application,
+and, with arguments, runAppli is an interactive Python interpreter.
+
+Several options are already defined by default in SALOMEApp.xml files. Optional
+arguments given in the command override the SALOMEApp.xml configuration.
+
+Several sessions can run simultaneously, each session use a different port for
+CORBA naming service, so the sessions are totally separated from each other.
+
+When the GUI is closed, the different %SALOME servers are still running.
+  </li>
+  <li>
+<b>Close a %SALOME session, kill all the servers</b>
+
+Inside the interactive python interpreter you get when you use runAppli
+with arguments, you can kill all the servers of your session with::
+
+\code
+>>> killLocalPort()
+\endcode
+
+or the servers of all the sessions with::
+
+\code
+>>> killAllPorts()
+\endcode
+
+If you have no active Python interpreter connected to your session, you can
+kill all the %SALOME servers of **all the sessions** on a given computer::
+
+\code
+./runSession killSalome.py
+\endcode
+
+Remember! it's the same idea in <b>Windows (R) operating system</b> (Microsoft and Windows are either registered trademarks or trademarks of
+       Microsoft Corporation in the United States and/or other countries) :
+use the start menu to stop...
+
+When you use only one session at a time, you don't need more.
+
+To kill a given session (when several session are running), one needs
+the naming service port number::
+
+\code
+./runSession killSalomeWithPort 2810
+\endcode
+
+Note that the port number of the last launched session can be found on Linux,
+in the prompt, within a runSession shell (see below).
+
+It is also possible to get the Naming Service host and port number of
+the last launched session with::
+
+\code
+./runSession NSparam.py
+\endcode
+
+  </li>
+  <li>
+<b>Launch a %SALOME session without GUI interface</b>
+
+This is used to launch a %SALOME Python script without GUI
+(no GUI %server = SALOME_session_server)
+
+Example of script (test_session_geom.py):
+
+\code
+import salome_session
+salome_session.startSession(modules=["GEOM"])
+import GEOM_usinggeom
+raw_input("Press a key and the servers will be killed ...")
+\endcode
+
+This script is run in a non interactive way with::
+
+\code
+./runSession python test_session_geom.py
+\endcode
+
+All the process are automatically killed when Python is closed
+(with SALOME_session delete).
+  </li>
+  <li>
+<b>Add an external Python interpretor to a running session</b>
+
+It's often easier to develop and try Python scripts outside the GUI embedded
+Python interpreter. Imagine, for instance, you are writing a script involving
+geometry and mesh modules.
+first, launch a %SALOME session with gui, then, on another terminal::
+
+\code
+./runSession
+python
+\endcode
+
+Import %SALOME module. salome_init() without arguments creates a new study
+in the running session (note: SALOME_init(n) attachs to a running session whose
+studyId is n)::
+
+\code
+import salome
+salome.salome_init()
+\endcode
+
+An example of script given with SMESH::
+
+\code
+import ex01_cube2build
+\endcode
+
+It is possible to connect the GUI interface to the study created in the above
+script with the file/connect menu, then browse study and display objects.
+Further modifications on study can be done either with GUI or external script
+(use refresh popup in GUI %object browser to see study modifications generated
+by the external script). **AVOID modifications with GUI when a Python script
+is running**. Not all the modules are protected against concurrent actions...
+  </li>
+  <li>
+<b>Different uses of the runSession shell interpreter</b>
+
+runSession invoked without arguments gives an interactive shell with the full
+environment of %SALOME (PATH, LD_LIBRARY_PATH, PYTHONPATH, other variables).
+If there are running sessions of the same %SALOME application, runSession
+connects to the last launched session (i.e. gets the naming service references
+of the session: hostname and port)
+
+On Linux, the shell prompt (bash) gives information on naming service
+references, hostname and port::
+
+\code
+[NS=cli76cc:2811]prascle@cli76cc:~/SALOME2/Run/Virtual$
+\endcode
+
+If there is no running session, prompt looks like::
+
+\code
+[NS=:]prascle@cli76cc:~/SALOME2/Run/Virtual$
+\endcode
+
+runSession is useful to launch any script or program which needs the complete
+%SALOME environment, with or without a session already running.
+For instance, to launch the ddd debugger interface on the gui %server, first
+launch a %SALOME session with gui, then, on another terminal::
+
+\code
+./runSession ddd
+\endcode
+
+Then attach to the running SALOME_Session_Server process.
+  </li>
+</ol>  
+
+*/
diff --git a/doc/salome/salome_file.dox b/doc/salome/salome_file.dox
new file mode 100644 (file)
index 0000000..dffb378
--- /dev/null
@@ -0,0 +1,123 @@
+/*!
+
+\page salome_file_page Salome_file
+
+This page introduces the Salome_file feature. Salome_file is based on the 
+SALOME_FileTransfer. It extends it to enable a higher model for managing files into
+%SALOME applications.
+
+\section S1_Salome_file Principles
+
+Salome_file is a CORBA %object. It's role is to managed many system files. When a Salome_file
+is created, no files are managed. Then, files are added using Salome_file interface. %A file is represented
+by a <b>name</b> and a <b>path</b>.
+
+There is two different cases when a file is added :
+
+- <b>Local file</b> : the file added exists or it will be created by the user with the path and the name used in
+its registration.
+- <b>Distributed file</b> : the file added exists into a distributed localization.
+
+To be able to get a distributed file, the Salome_file has to be connected with an another Salome_file that
+managed this file. This distributed Salome_file could be located into a distributed resource.
+
+\section S2_Salome_file Simple example
+
+This section shows a simple example of the use of Salome_file. The objective is to create
+two Salome_file; one is managing a local file, the other is managing a distributed file.
+Then, these Salome_files are connected to enable the copy of the real file gbetween the two Salome_files.
+
+Firstly, two Salome_files are created :
+
+\code
+#include "Salome_file_i.hxx"
+
+int main (int argc, char * argv[])
+{
+  Salome_file_i file_source;
+  Salome_file_i file_dest;
+
+\endcode
+
+Secondly, the real files are registered into the Salome_files.
+
+\code
+ file_source.setLocalFile("/bin/cat");
+ file_dest.setDistributedFile("/tmp/cat_copy");
+\endcode
+
+Thirdly, we connect the destination file with the source file :
+
+\code
+  file_dest.connect(file_source);
+\endcode
+
+Finally, the file is sended using Salome_file interface.
+
+\code
+  file_dest.recvFiles();
+  // Status check
+  state = file_dest.getSalome_fileState();
+  print_state(state); // You have to implement this function.
+};
+\endcode
+
+\section S3_Salome_file Advanced example
+
+This advanced example illustrates a part of the Salome_file API dedicated
+for situations where multiple files are managed.
+
+This is the situation :
+
+\code
+
+#include "Salome_file_i.hxx"
+
+int main (int argc, char * argv[])
+{
+  Salome_file_i file_source_a;
+  Salome_file_i file_source_b;
+  Salome_file_i file_dest;
+
+  file_source_a.setLocalFile("/bin/cat");
+  file_source_a.setLocalFile("/bin/ls");
+
+  file_source_b.setLocalFile("/bin/echo");
+  file_source_b.setLocalFile("/bin/cp");
+
+  file_dest.setDistributedFile("/tmp/cat_copy");
+  file_dest.setDistributedFile("/tmp/echo_copy");
+\endcode
+
+There is two problems in this case. 
+
+The first problem is in the <b>file_dest</b> Salome_file, there is two files. If
+the method connect is used, the Salome_file cannot know if the reference is for <b>cat_copy</b> or
+<b>echo_copy</b>. Indeed <b>echo_copy</b> could be provided by another Salome_file that for <b>cat_copy</b>.
+
+The second problem comes from the two files of <b>file_source_a</b> Salome_file. Indeed when connect is used, 
+there is no information about the choice of the source file into the source Salome_file. For
+<b>cat_copy</b>, did the used want <b>cat</b> or <b>echo</b> ?
+
+To avoid these cases, Salome_file API provides advanced methods :
+
+\code
+  file_dest.connectDistributedFile("cat_copy", file_source_a);
+  file_dest.setDistributedSourceFile("cat_copy", "cat");
+
+  file_dest.connectDistributedFile("cat_echo", file_source_b);
+  file_dest.setDistributedSourceFile("cat_echo", "echo");
+
+  file_dest.recvFiles();
+  // Status check
+  state = file_dest.getSalome_fileState();
+  print_state(state); // You have to implement this function.
+};
+\endcode
+
+\section S3_Salome_file Using Salome_file into %SALOME services
+
+Currently you can't use Salome_file into YACS schema. In the next version of %SALOME,
+files ports will be available to connect output files to input files.
+
+*/
diff --git a/doc/salome/tui/KERNEL/sources/kernel_about_4.png b/doc/salome/tui/KERNEL/sources/kernel_about_4.png
new file mode 100644 (file)
index 0000000..5c9c09a
Binary files /dev/null and b/doc/salome/tui/KERNEL/sources/kernel_about_4.png differ
diff --git a/doc/salome/unittests.dox b/doc/salome/unittests.dox
new file mode 100644 (file)
index 0000000..fc5ebdd
--- /dev/null
@@ -0,0 +1,207 @@
+/*!
+
+\page UnitTests Source code structuration and Unit Tests
+
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+You will find here general information on code directories structure,
+unit tests associated to the different kind of classes, and how to run
+the unit tests.
+
+\section S1_unit SALOME KERNEL source code structuration
+
+<ol>
+<li> <b>General structure of KERNEL_SRC</b>
+
+- KERNEL_SRC :
+   Some README files and configuration tools for build
+
+- KERNEL_SRC/adm_local :
+   Part of the configuration files, other modules have a directory with the
+   same name. Not used in KERNEL.
+
+- KERNEL_SRC/bin :
+   Python and shell scripts used at run time.
+   Kit to install a %SALOME Application.
+
+- KERNEL_SRC/doc :
+   Kit for KERNEL end user documentation production:
+   public interfaces, Python, CORBA.
+   Integrator and Developper documentation.
+
+- KERNEL_SRC/idl :
+   All CORBA interfaces from KERNEL are regrouped here.
+
+- KERNEL_SRC/resources :
+   Configuration files for servers (examples).
+   Interfaces definitions for KERNEL test components.
+
+- KERNEL_SRC/salome_adm :
+   Configuration files used by autotools (M4 macros & co.)
+
+- KERNEL_SRC/src :
+   The source code (C++ and Python)
+
+</li> 
+<li>
+<b>Directory src: C++ and Python source code</b>
+
+<ol>
+<li>
+<b>Basic services non related to CORBA</b>
+
+- Basics
+  %A set of general purpose C++ services, not related to CORBA.
+  Some general purpose services that are in Utils directory (CORBA related),
+  are progressivley moved here, as they are not related to CORBA.
+  
+
+- SALOMELocalTrace
+  %A multithread trace system that allows message tracing on standard error
+  or a file. 
+
+- CASCatch
+  Exceptions and signal handler.
+
+- HDFPersist
+  %A C++ interface to HDF.
+
+</li>
+
+<li>
+<b>Basic CORBA services</b>
+
+- Logger :
+  %A CORBA %server that collects the trace messages from differents CORBA 
+  process. 
+
+- SALOMETraceCollector :
+  %A multithread trace system derived from SALOMELocalTrace, that sends messages
+  to Logger %server via CORBA.
+
+- Utils :
+  %A set of general purpose services related to CORBA, such as basic CORBA
+  exception system. See also Basics directory above.
+
+- NamingService :
+  C++ and Python interfaces to name, store and retrieve CORBA objects
+
+- GenericObj :
+  %A generic CORBA interface for CORBA objects, to count distributed references,
+  and to allow destruction by client. 
+
+</li>
+<li>
+<b>Miscellaneous CORBA servers</b>
+
+- %Registry :
+  Implements SALOME_registry.idl.
+  Provides a CORBA %server library and a separate %server program.
+
+- ModuleCatalog :
+  Implements SALOME_moduleCatalog.idl.
+  Provide a CORBA %server library and separate %server and client programs.
+
+- ModuleGenerator :
+  Tool to generate a module catalog from CORBA idl
+
+- ResourcesManager :
+  library included in container %server
+
+- Notification :
+  library included in differents servers (container)
+
+- NOTIFICATION_SWIG
+
+</li>
+
+<li>
+<b>CORBA Containers for %SALOME Modules</b>
+
+- Container
+
+- TestContainer
+
+- LifeCycleCORBA
+
+- LifeCycleCORBA_SWIG
+
+</li>
+
+<li>
+<b>STUDY %server and related interfaces and tools</b>
+
+- SALOMEDSClient
+
+- TOOLSDS
+
+- SALOMEDSImpl
+
+- SALOMEDS
+
+</li>
+<li>
+<b>Python interface to %SALOME</b>
+- KERNEL_PY
+
+</li>
+<li>
+<b>Efficient CORBA transfer services</b>
+
+- Communication
+
+- Communication_SWIG
+
+</li>
+<li>
+<b>%A Parallel container with MPI</b>
+
+- MPIContainer
+
+- TestMPIContainer
+
+</li>
+<li>
+<b>Batch interface library</b>
+
+- Batch
+
+- Batch_SWIG
+
+</li>
+<li>
+<b>Unit tests</b>
+
+- UnitTests
+
+</li>
+</ol>
+</li>
+</ol>
+
+\section S2_unit Tools and principles used for Unit testing
+
+<b>**TO BE COMPLETED**</b>
+
+Unit Testing rely on cppunit package for C++ testing, and on unittest module
+for Python. See these products for general principles of unit testing.
+
+The cppunit package is optional. When the prerequisite is detected, the unit
+tests are compiled.
+
+Unit Tests sources are in directories Test under the src/directories
+containing the classes to test.
+
+Test are ordered following the order of directories given above.
+
+Tests can be run as a whole, or for a particular directory. In this case, only
+a partial test is run (the classes to test, and the classes used, i.e. the 
+preceding test directories).
+
+
+Today, only some tests are written as an example. There are not yet python
+scripts in KERNEL_SRC, but it's a matter of days, there are working scripts
+to test LifeCycleCORBA_SWIG interface.
+
+*/
diff --git a/src/Batch/Batch_BatchManager_eClient.cxx b/src/Batch/Batch_BatchManager_eClient.cxx
new file mode 100644 (file)
index 0000000..41ce47c
--- /dev/null
@@ -0,0 +1,235 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.cxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+#include "Batch_BatchManager_eClient.hxx"
+
+namespace Batch {
+
+  BatchManager_eClient::BatchManager_eClient(const Batch::FactBatchManager * parent, const char* host, const char* protocol, const char* mpiImpl) : BatchManager(parent, host), _protocol(protocol), _username("")
+  {
+    // instanciation of mpi implementation needed to launch executable in batch script
+    _mpiImpl = FactoryMpiImpl(mpiImpl);
+  }
+
+  // Destructeur
+  BatchManager_eClient::~BatchManager_eClient()
+  {
+    // Nothing to do
+    delete _mpiImpl;
+  }
+
+  void BatchManager_eClient::exportInputFiles(const Job& job) throw(EmulationException)
+  {
+    int status;
+    Parametre params = job.getParametre();
+    Versatile V = params[INFILE];
+    Versatile::iterator Vit;
+    string command;
+    string copy_command;
+    _username = string(params[USER]);
+
+    // Test protocol
+    if( _protocol == "rsh" )
+      copy_command = "rcp ";
+    else if( _protocol == "ssh" )
+      copy_command = "scp ";
+    else
+      throw EmulationException("Unknown protocol : only rsh and ssh are known !");
+    
+    // First step : creating batch tmp files directory
+    command = _protocol;
+    command += " ";
+    if(_username != ""){
+      command += _username;
+      command += "@";
+    }
+    command += _hostname;
+    command += " \"mkdir -p ";
+    command += string(params[TMPDIR]);
+    command += "\"" ;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status) {
+      std::ostringstream oss;
+      oss << status;
+      std::string ex_mess("Error of connection on remote host ! status = ");
+      ex_mess += oss.str();
+      throw EmulationException(ex_mess.c_str());
+    }
+
+    // Second step : copy fileToExecute into
+    // batch tmp files directory
+    command = copy_command;
+    command += string(params[EXECUTABLE]);
+    command += " ";
+    if(_username != ""){
+      command += _username;
+      command += "@";
+    }
+    command += _hostname;
+    command += ":";
+    command += string(params[TMPDIR]);
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status) {
+      std::ostringstream oss;
+      oss << status;
+      std::string ex_mess("Error of connection on remote host ! status = ");
+      ex_mess += oss.str();
+      throw EmulationException(ex_mess.c_str());
+    }
+    
+    // Third step : copy filesToExportList into
+    // batch tmp files directory
+    for(Vit=V.begin(); Vit!=V.end(); Vit++) {
+      CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
+      Couple inputFile = cpt;
+      command = copy_command;
+      command += inputFile.getLocal();
+      command += " ";
+      if(_username != ""){
+       command += _username;
+       command += "@";
+      }
+      command += _hostname;
+      command += ":";
+      command += inputFile.getRemote();
+      cerr << command.c_str() << endl;
+      status = system(command.c_str());
+      if(status) {
+       std::ostringstream oss;
+       oss << status;
+       std::string ex_mess("Error of connection on remote host ! status = ");
+       ex_mess += oss.str();
+       throw EmulationException(ex_mess.c_str());
+      }
+    }
+
+  }
+
+  void BatchManager_eClient::importOutputFiles( const Job & job, const string directory ) throw(EmulationException)
+  {
+    string command;
+    int status;
+
+    Parametre params = job.getParametre();
+    Versatile V = params[OUTFILE];
+    Versatile::iterator Vit;
+    for(Vit=V.begin(); Vit!=V.end(); Vit++) {
+      CoupleType cpt  = *static_cast< CoupleType * >(*Vit);
+      Couple outputFile = cpt;
+      if( _protocol == "rsh" )
+       command = "rcp ";
+      else if( _protocol == "ssh" )
+       command = "scp ";
+      else
+       throw EmulationException("Unknown protocol");
+
+      if (_username != ""){
+       command += _username;
+       command += "@";
+      }
+      command += _hostname;
+      command += ":";
+      command += outputFile.getRemote();
+      command += " ";
+      command += directory;
+      cerr << command.c_str() << endl;
+      status = system(command.c_str());
+      if(status) 
+      {
+       // Try to get what we can (logs files)
+       // throw BatchException("Error of connection on remote host");    
+       std::string mess("Copy command failed ! status is :");
+       ostringstream status_str;
+       status_str << status;
+       mess += status_str.str();
+       cerr << mess << endl;
+      }
+    }
+
+  }
+
+  MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl) throw(EmulationException)
+  {
+    if(mpiImpl == "lam")
+      return new MpiImpl_LAM();
+    else if(mpiImpl == "mpich1")
+      return new MpiImpl_MPICH1();
+    else if(mpiImpl == "mpich2")
+      return new MpiImpl_MPICH2();
+    else if(mpiImpl == "openmpi")
+      return new MpiImpl_OPENMPI();
+    else if(mpiImpl == "slurm")
+      return new MpiImpl_SLURM();
+    else{
+      ostringstream oss;
+      oss << mpiImpl << " : not yet implemented";
+      throw EmulationException(oss.str().c_str());
+    }
+  }
+
+  string BatchManager_eClient::BuildTemporaryFileName() const
+  {
+    //build more complex file name to support multiple salome session
+    char *temp = new char[19];
+    strcpy(temp, "/tmp/command");
+    strcat(temp, "XXXXXX");
+#ifndef WNT
+    mkstemp(temp);
+#else
+    char aPID[80];
+    itoa(getpid(), aPID, 10);
+    strcat(temp, aPID);
+#endif
+
+    string command(temp);
+    delete [] temp;
+    command += ".sh";
+    return command;
+  }
+
+  void BatchManager_eClient::RmTmpFile(std::string & TemporaryFileName)
+  {
+    string command = "rm ";
+    command += TemporaryFileName;
+    char *temp = strdup(command.c_str());
+    int lgthTemp = strlen(temp);
+    temp[lgthTemp - 3] = '*';
+    temp[lgthTemp - 2] = '\0';
+    system(temp);
+    free(temp);
+  }
+
+}
diff --git a/src/Batch/Batch_BatchManager_eClient.hxx b/src/Batch/Batch_BatchManager_eClient.hxx
new file mode 100644 (file)
index 0000000..717eae6
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.hxx : emulation of client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#ifndef _BATCHMANAGER_eClient_H_
+#define _BATCHMANAGER_eClient_H_
+
+
+#include "MpiImpl.hxx"
+#include "Batch_BatchManager.hxx"
+
+namespace Batch {
+
+  class Job;
+
+  class EmulationException
+  {
+  public:
+    const std::string msg;
+    
+    EmulationException(const std::string m) : msg(m) {}
+  };
+
+  class BatchManager_eClient : public BatchManager
+  {
+  public:
+    // Constructeur et destructeur
+    BatchManager_eClient(const Batch::FactBatchManager * parent, const char* host="localhost", const char* protocol="ssh", const char* mpiImpl="indif");
+    virtual ~BatchManager_eClient();
+    void importOutputFiles( const Job & job, const std::string directory ) throw(EmulationException);
+
+  protected:
+    std::string _protocol; // protocol to access _hostname
+    std::string _username; // username to access _hostname
+    MpiImpl *_mpiImpl; // Mpi implementation to launch executable in batch script
+
+    std::string BuildTemporaryFileName() const;
+    void RmTmpFile(std::string & TemporaryFileName);
+    MpiImpl* FactoryMpiImpl(string mpiImpl) throw(EmulationException);
+    void exportInputFiles(const Job & job) throw(EmulationException);
+
+  private:
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_BatchManager_eLSF.cxx b/src/Batch/Batch_BatchManager_eLSF.cxx
new file mode 100644 (file)
index 0000000..d1c44e6
--- /dev/null
@@ -0,0 +1,310 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.cxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+#include "Batch_BatchManager_eLSF.hxx"
+
+namespace Batch {
+
+  BatchManager_eLSF::BatchManager_eLSF(const FactBatchManager * parent, const char * host, const char * protocol, const char * mpiImpl) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager_eClient(parent,host,protocol,mpiImpl)
+  {
+    // Nothing to do
+  }
+
+  // Destructeur
+  BatchManager_eLSF::~BatchManager_eLSF()
+  {
+    // Nothing to do
+  }
+
+  // Methode pour le controle des jobs : soumet un job au gestionnaire
+  const JobId BatchManager_eLSF::submitJob(const Job & job)
+  {
+    int status;
+    Parametre params = job.getParametre();
+    const std::string dirForTmpFiles = params[TMPDIR];
+    const string fileToExecute = params[EXECUTABLE];
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+    // export input files on cluster
+    exportInputFiles(job);
+
+    // build batch script for job
+    buildBatchScript(job);
+
+    // define name of log file
+    string logFile="/tmp/logs/";
+    logFile += getenv("USER");
+    logFile += "/batchSalome_";
+    srand ( time(NULL) );
+    int ir = rand();
+    ostringstream oss;
+    oss << ir;
+    logFile += oss.str();
+    logFile += ".log";
+
+    string command;
+
+    // define command to submit batch
+    command = _protocol;
+    command += " ";
+
+    if(_username != ""){
+      command += _username;
+      command += "@";
+    }
+
+    command += _hostname;
+    command += " \"cd " ;
+    command += dirForTmpFiles ;
+    command += "; bsub < " ;
+    command += fileNameToExecute ;
+    command += "_Batch.sh\" > ";
+    command += logFile;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");
+
+    // read id of submitted job in log file
+    char line[128];
+    FILE *fp = fopen(logFile.c_str(),"r");
+    fgets( line, 128, fp);
+    fclose(fp);
+    
+    string sline(line);
+    int p10 = sline.find("<");
+    int p20 = sline.find(">");
+    string strjob = sline.substr(p10+1,p20-p10-1);
+
+    JobId id(this, strjob);
+    return id;
+  }
+
+  // Methode pour le controle des jobs : retire un job du gestionnaire
+  void BatchManager_eLSF::deleteJob(const JobId & jobid)
+  {
+    int status;
+    int ref;
+    istringstream iss(jobid.getReference());
+    iss >> ref;
+    
+    // define command to submit batch
+    string command;
+    command = _protocol;
+    command += " ";
+
+    if (_username != ""){
+      command += _username;
+      command += "@";
+    }
+
+    command += _hostname;
+    command += " \"bkill " ;
+    command += iss.str();
+    command += "\"";
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");
+
+    cerr << "jobId = " << ref << "killed" << endl;
+  }
+   
+  // Methode pour le controle des jobs : suspend un job en file d'attente
+  void BatchManager_eLSF::holdJob(const JobId & jobid)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+  // Methode pour le controle des jobs : relache un job suspendu
+  void BatchManager_eLSF::releaseJob(const JobId & jobid)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_eLSF::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_eLSF::alterJob(const JobId & jobid, const Parametre & param)
+  {
+    alterJob(jobid, param, Environnement());
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_eLSF::alterJob(const JobId & jobid, const Environnement & env)
+  {
+    alterJob(jobid, Parametre(), env);
+  }
+
+  // Methode pour le controle des jobs : renvoie l'etat du job
+  JobInfo BatchManager_eLSF::queryJob(const JobId & jobid)
+  {
+    int id;
+    istringstream iss(jobid.getReference());
+    iss >> id;
+
+    // define name of log file
+    string logFile="/tmp/logs/";
+    logFile += getenv("USER");
+    logFile += "/batchSalome_";
+
+    srand ( time(NULL) );
+    int ir = rand();
+    ostringstream oss;
+    oss << ir;
+    logFile += oss.str();
+    logFile += ".log";
+
+    string command;
+    int status;
+
+    // define command to submit batch
+    command = _protocol;
+    command += " ";
+
+    if (_username != ""){
+      command += _username;
+      command += "@";
+    }
+
+    command += _hostname;
+    command += " \"bjobs " ;
+    command += iss.str();
+    command += "\" > ";
+    command += logFile;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");
+
+    JobInfo_eLSF ji = JobInfo_eLSF(id,logFile);
+    return ji;
+  }
+
+
+
+  // Methode pour le controle des jobs : teste si un job est present en machine
+  bool BatchManager_eLSF::isRunning(const JobId & jobid)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+  void BatchManager_eLSF::buildBatchScript(const Job & job) throw(EmulationException)
+  {
+    int status;
+    Parametre params = job.getParametre();
+    const int nbproc = params[NBPROC];
+    const long edt = params[MAXWALLTIME];
+    const long mem = params[MAXRAMSIZE];
+    const string workDir = params[WORKDIR];
+    const std::string dirForTmpFiles = params[TMPDIR];
+    const string fileToExecute = params[EXECUTABLE];
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    std::string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+    std::string fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(fileToExecute.c_str()));
+
+    int idx = dirForTmpFiles.find("Batch/");
+    std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+
+    std::string TmpFileName = BuildTemporaryFileName();
+    ofstream tempOutputFile;
+    tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+
+    tempOutputFile << "#! /bin/sh -f" << endl ;
+    if( edt > 0 )
+      tempOutputFile << "#BSUB -W " << getWallTime(edt) << endl ;
+    if( mem > 0 )
+      tempOutputFile << "#BSUB -M " << mem*1024 << endl ;
+    tempOutputFile << "#BSUB -n " << nbproc << endl ;
+    tempOutputFile << "#BSUB -o runSalome.output.log." << filelogtemp << endl ;
+    tempOutputFile << "#BSUB -e runSalome.error.log." << filelogtemp << endl ;
+    if( workDir.size() > 0 )
+      tempOutputFile << "cd " << workDir << endl ;
+    tempOutputFile << _mpiImpl->boot("",nbproc);
+    tempOutputFile << _mpiImpl->run("",nbproc,fileNameToExecute);
+    tempOutputFile << _mpiImpl->halt();
+    tempOutputFile.flush();
+    tempOutputFile.close();
+    chmod(TmpFileName.c_str(), 0x1ED);
+    cerr << TmpFileName.c_str() << endl;
+
+    string command;
+    if( _protocol == "rsh" )
+      command = "rcp ";
+    else if( _protocol == "ssh" )
+      command = "scp ";
+    else
+      throw EmulationException("Unknown protocol");
+    command += TmpFileName;
+    command += " ";
+    if(_username != ""){
+      command +=  _username;
+      command += "@";
+    }
+    command += _hostname;
+    command += ":";
+    command += dirForTmpFiles ;
+    command += "/" ;
+    command += rootNameToExecute ;
+    command += "_Batch.sh" ;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");    
+
+    RmTmpFile(TmpFileName);
+    
+  }
+
+  std::string BatchManager_eLSF::getWallTime(const long edt)
+  {
+    long h, m;
+    h = edt / 60;
+    m = edt - h*60;
+    ostringstream oss;
+    if( m >= 10 )
+      oss << h << ":" << m;
+    else
+      oss << h << ":0" << m;
+    return oss.str();
+  }
+
+}
diff --git a/src/Batch/Batch_BatchManager_eLSF.hxx b/src/Batch/Batch_BatchManager_eLSF.hxx
new file mode 100644 (file)
index 0000000..00d79a4
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.hxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#ifndef _BATCHMANAGER_eLSF_H_
+#define _BATCHMANAGER_eLSF_H_
+
+
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_JobInfo_eLSF.hxx"
+#include "Batch_InvalidArgumentException.hxx"
+#include "Batch_ConnexionFailureException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_NotYetImplementedException.hxx"
+#include "Batch_BatchManager.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+
+namespace Batch {
+
+  class Job;
+  class JobId;
+  class JobInfo;
+  class FactBatchManager;
+
+  class BatchManager_eLSF : public BatchManager_eClient
+  {
+  public:
+    // Constructeur et destructeur
+    BatchManager_eLSF(const FactBatchManager * parent, const char * host="localhost", const char * protocol="ssh", const char * mpiImpl="indif") throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host
+    virtual ~BatchManager_eLSF();
+
+    // Recupere le nom du serveur par defaut
+    // static string BatchManager_LSF::getDefaultServer();
+
+    // Methodes pour le controle des jobs
+    virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire
+    virtual void deleteJob(const JobId & jobid); // retire un job du gestionnaire
+    virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente
+    virtual void releaseJob(const JobId & jobid); // relache un job suspendu
+    virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente
+    virtual JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job
+    virtual bool isRunning(const JobId & jobid); // teste si un job est present en machine
+
+    virtual void setParametre(const JobId & jobid, const Parametre & param) { return alterJob(jobid, param); } // modifie un job en file d'attente
+    virtual void setEnvironnement(const JobId & jobid, const Environnement & env) { return alterJob(jobid, env); } // modifie un job en file d'attente
+
+
+  protected:
+    void buildBatchScript(const Job & job) throw(EmulationException);
+    std::string getWallTime(const long edt);
+
+  private:
+
+#ifdef SWIG
+  public:
+    // Recupere le l'identifiant d'un job deja soumis au BatchManager
+    //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); }
+    virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); }
+#endif
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_BatchManager_ePBS.cxx b/src/Batch/Batch_BatchManager_ePBS.cxx
new file mode 100644 (file)
index 0000000..999025c
--- /dev/null
@@ -0,0 +1,296 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_ePBS.cxx : emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+#include "Batch_BatchManager_ePBS.hxx"
+
+namespace Batch {
+
+  BatchManager_ePBS::BatchManager_ePBS(const FactBatchManager * parent, const char * host, const char * protocol, const char * mpiImpl) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager_eClient(parent,host,protocol,mpiImpl)
+  {
+    // Nothing to do
+  }
+
+  // Destructeur
+  BatchManager_ePBS::~BatchManager_ePBS()
+  {
+    // Nothing to do
+  }
+
+  // Methode pour le controle des jobs : soumet un job au gestionnaire
+  const JobId BatchManager_ePBS::submitJob(const Job & job)
+  {
+    int status;
+    Parametre params = job.getParametre();
+    const std::string dirForTmpFiles = params[TMPDIR];
+    const string fileToExecute = params[EXECUTABLE];
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+    // export input files on cluster
+    exportInputFiles(job);
+
+    // build batch script for job
+    buildBatchScript(job);
+
+    // define name of log file
+    string logFile="/tmp/logs/";
+    logFile += getenv("USER");
+    logFile += "/batchSalome_";
+    srand ( time(NULL) );
+    int ir = rand();
+    ostringstream oss;
+    oss << ir;
+    logFile += oss.str();
+    logFile += ".log";
+
+    string command;
+
+    // define command to submit batch
+    command = _protocol;
+    command += " ";
+
+    if(_username != ""){
+      command += _username;
+      command += "@";
+    }
+
+    command += _hostname;
+    command += " \"cd " ;
+    command += dirForTmpFiles ;
+    command += "; qsub " ;
+    command += fileNameToExecute ;
+    command += "_Batch.sh\" > ";
+    command += logFile;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");
+
+    // read id of submitted job in log file
+    char line[128];
+    FILE *fp = fopen(logFile.c_str(),"r");
+    fgets( line, 128, fp);
+    fclose(fp);
+    
+    string sline(line);
+    int pos = sline.find(".");
+    string strjob;
+    if(pos == string::npos)
+      strjob = sline;
+    else
+      strjob = sline.substr(0,pos);
+
+    JobId id(this, strjob);
+    return id;
+  }
+
+  // Methode pour le controle des jobs : retire un job du gestionnaire
+  void BatchManager_ePBS::deleteJob(const JobId & jobid)
+  {
+    int status;
+    int ref;
+    istringstream iss(jobid.getReference());
+    iss >> ref;
+    
+    // define command to submit batch
+    string command;
+    command = _protocol;
+    command += " ";
+
+    if (_username != ""){
+      command += _username;
+      command += "@";
+    }
+
+    command += _hostname;
+    command += " \"qdel " ;
+    command += iss.str();
+    command += "\"";
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");
+
+    cerr << "jobId = " << ref << "killed" << endl;
+  }
+   
+  // Methode pour le controle des jobs : suspend un job en file d'attente
+  void BatchManager_ePBS::holdJob(const JobId & jobid)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+  // Methode pour le controle des jobs : relache un job suspendu
+  void BatchManager_ePBS::releaseJob(const JobId & jobid)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_ePBS::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_ePBS::alterJob(const JobId & jobid, const Parametre & param)
+  {
+    alterJob(jobid, param, Environnement());
+  }
+
+  // Methode pour le controle des jobs : modifie un job en file d'attente
+  void BatchManager_ePBS::alterJob(const JobId & jobid, const Environnement & env)
+  {
+    alterJob(jobid, Parametre(), env);
+  }
+
+  // Methode pour le controle des jobs : renvoie l'etat du job
+  JobInfo BatchManager_ePBS::queryJob(const JobId & jobid)
+  {
+    int id;
+    istringstream iss(jobid.getReference());
+    iss >> id;
+
+    // define name of log file
+    string logFile="/tmp/logs/";
+    logFile += getenv("USER");
+    logFile += "/batchSalome_";
+
+    ostringstream oss;
+    oss << this << "_" << id;
+    logFile += oss.str();
+    logFile += ".log";
+
+    string command;
+    int status;
+
+    // define command to submit batch
+    command = _protocol;
+    command += " ";
+
+    if (_username != ""){
+      command += _username;
+      command += "@";
+    }
+
+    command += _hostname;
+    command += " \"qstat -f " ;
+    command += iss.str();
+    command += "\" > ";
+    command += logFile;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status && status != 153 && status != 256*153)
+      throw EmulationException("Error of connection on remote host");
+
+    JobInfo_ePBS ji = JobInfo_ePBS(id,logFile);
+    return ji;
+  }
+
+  // Methode pour le controle des jobs : teste si un job est present en machine
+  bool BatchManager_ePBS::isRunning(const JobId & jobid)
+  {
+    throw EmulationException("Not yet implemented");
+  }
+
+  void BatchManager_ePBS::buildBatchScript(const Job & job) throw(EmulationException)
+  {
+    int status;
+    Parametre params = job.getParametre();
+    const long nbproc = params[NBPROC];
+    const long edt = params[MAXWALLTIME];
+    const long mem = params[MAXRAMSIZE];
+    const string workDir = params[WORKDIR];
+    const std::string dirForTmpFiles = params[TMPDIR];
+    const string fileToExecute = params[EXECUTABLE];
+    const string home = params[HOMEDIR];
+    string::size_type p1 = fileToExecute.find_last_of("/");
+    string::size_type p2 = fileToExecute.find_last_of(".");
+    std::string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+    std::string fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(fileToExecute.c_str()));
+
+    int idx = dirForTmpFiles.find("Batch/");
+    std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+
+    std::string TmpFileName = BuildTemporaryFileName();
+    ofstream tempOutputFile;
+    tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+
+    tempOutputFile << "#! /bin/sh -f" << endl;
+    if( edt > 0 )
+      tempOutputFile << "#PBS -l walltime=" << edt*60 << endl ;
+    if( mem > 0 )
+      tempOutputFile << "#PBS -l mem=" << mem << "mb" << endl ;
+    tempOutputFile << "#PBS -o " << home << "/" << dirForTmpFiles << "/runSalome.output.log." << filelogtemp << endl ;
+    tempOutputFile << "#PBS -e " << home << "/" << dirForTmpFiles << "/runSalome.error.log." << filelogtemp << endl ;
+    if( workDir.size() > 0 )
+      tempOutputFile << "cd " << workDir << endl ;
+    tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbproc);
+    tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,fileNameToExecute);
+    tempOutputFile << _mpiImpl->halt();
+    tempOutputFile.flush();
+    tempOutputFile.close();
+    chmod(TmpFileName.c_str(), 0x1ED);
+    cerr << TmpFileName.c_str() << endl;
+
+    string command;
+    if( _protocol == "rsh" )
+      command = "rcp ";
+    else if( _protocol == "ssh" )
+      command = "scp ";
+    else
+      throw EmulationException("Unknown protocol");
+    command += TmpFileName;
+    command += " ";
+    if(_username != ""){
+      command +=  _username;
+      command += "@";
+    }
+    command += _hostname;
+    command += ":";
+    command += dirForTmpFiles ;
+    command += "/" ;
+    command += rootNameToExecute ;
+    command += "_Batch.sh" ;
+    cerr << command.c_str() << endl;
+    status = system(command.c_str());
+    if(status)
+      throw EmulationException("Error of connection on remote host");    
+
+    RmTmpFile(TmpFileName);
+    
+  }
+
+}
diff --git a/src/Batch/Batch_BatchManager_ePBS.hxx b/src/Batch/Batch_BatchManager_ePBS.hxx
new file mode 100644 (file)
index 0000000..42f4b1b
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_ePBS.hxx : emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#ifndef _BATCHMANAGER_eLSF_H_
+#define _BATCHMANAGER_eLSF_H_
+
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_JobInfo_ePBS.hxx"
+#include "Batch_InvalidArgumentException.hxx"
+#include "Batch_ConnexionFailureException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_NotYetImplementedException.hxx"
+#include "Batch_BatchManager.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+
+namespace Batch {
+
+  class Job;
+  class JobId;
+  class JobInfo;
+  class FactBatchManager;
+
+  class BatchManager_ePBS : public BatchManager_eClient
+  {
+  public:
+    // Constructeur et destructeur
+    BatchManager_ePBS(const FactBatchManager * parent, const char * host="localhost", const char * protocol="ssh", const char * mpiImpl="indif") throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host
+    virtual ~BatchManager_ePBS();
+
+    // Recupere le nom du serveur par defaut
+    // static string BatchManager_LSF::getDefaultServer();
+
+    // Methodes pour le controle des jobs
+    virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire
+    virtual void deleteJob(const JobId & jobid); // retire un job du gestionnaire
+    virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente
+    virtual void releaseJob(const JobId & jobid); // relache un job suspendu
+    virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente
+    virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente
+    virtual JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job
+    virtual bool isRunning(const JobId & jobid); // teste si un job est present en machine
+
+    virtual void setParametre(const JobId & jobid, const Parametre & param) { return alterJob(jobid, param); } // modifie un job en file d'attente
+    virtual void setEnvironnement(const JobId & jobid, const Environnement & env) { return alterJob(jobid, env); } // modifie un job en file d'attente
+
+
+  protected:
+    void buildBatchScript(const Job & job) throw(EmulationException);
+
+  private:
+
+#ifdef SWIG
+  public:
+    // Recupere le l'identifiant d'un job deja soumis au BatchManager
+    //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); }
+    virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); }
+#endif
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_FactBatchManager_eClient.cxx b/src/Batch/Batch_FactBatchManager_eClient.cxx
new file mode 100644 (file)
index 0000000..6673879
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eClient.cxx : emulation of client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#include <string>
+#include <sstream>
+#include "Batch_FactBatchManager_eClient.hxx"
+using namespace std;
+
+namespace Batch {
+
+  // Constructeur
+  FactBatchManager_eClient::FactBatchManager_eClient(const string & _t) : FactBatchManager(_t)
+  {
+  }
+
+  // Destructeur
+  FactBatchManager_eClient::~FactBatchManager_eClient()
+  {
+    // Nothing to do
+  }
+
+}
diff --git a/src/Batch/Batch_FactBatchManager_eClient.hxx b/src/Batch/Batch_FactBatchManager_eClient.hxx
new file mode 100644 (file)
index 0000000..616a662
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eClient.hxx : emulation of client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_eClient_H_
+#define _FACTBATCHMANAGER_eClient_H_
+
+#include <string>
+#include <map>
+#include "Batch_FactBatchManager.hxx"
+
+namespace Batch {
+  
+  class BatchManager_eClient;
+
+  class FactBatchManager_eClient : public FactBatchManager
+  {
+  public:
+    // Constructeur et destructeur
+    FactBatchManager_eClient(const std::string & type);
+    virtual ~FactBatchManager_eClient();
+
+    virtual Batch::BatchManager_eClient * operator() (const char * hostname,const char * protocol, const char * mpi) const = 0;
+
+  protected:
+
+  private:
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_FactBatchManager_eLSF.cxx b/src/Batch/Batch_FactBatchManager_eLSF.cxx
new file mode 100644 (file)
index 0000000..227bffa
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eLSF.cxx : 
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Date   : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <string>
+#include "Batch_BatchManager_eLSF.hxx"
+#include "Batch_FactBatchManager_eLSF.hxx"
+//#include "utilities.h"
+
+namespace Batch {
+
+  static FactBatchManager_eLSF sFBM_eLSF;
+
+  // Constructeur
+  FactBatchManager_eLSF::FactBatchManager_eLSF() : FactBatchManager_eClient("eLSF")
+  {
+    // Nothing to do
+  }
+
+  // Destructeur
+  FactBatchManager_eLSF::~FactBatchManager_eLSF()
+  {
+    // Nothing to do
+  }
+
+  // Functor
+  BatchManager * FactBatchManager_eLSF::operator() (const char * hostname) const
+  {
+    // MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
+    return new BatchManager_eLSF(this, hostname);
+  }
+
+  BatchManager_eClient * FactBatchManager_eLSF::operator() (const char * hostname, const char * protocol, const char * mpiImpl) const
+  {
+    // MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
+    return new BatchManager_eLSF(this, hostname, protocol, mpiImpl);
+  }
+
+}
diff --git a/src/Batch/Batch_FactBatchManager_eLSF.hxx b/src/Batch/Batch_FactBatchManager_eLSF.hxx
new file mode 100644 (file)
index 0000000..e1660aa
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eLSF.hxx : 
+ *
+ * Auteur : Bernard SECHER : CEA DEN
+ * Date   : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_eLSF_H_
+#define _FACTBATCHMANAGER_eLSF_H_
+
+using namespace std;
+#include <string>
+#include <map>
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_FactBatchManager_eClient.hxx"
+
+namespace Batch {
+  
+  class BatchManager_eLSF;
+
+  class FactBatchManager_eLSF : public FactBatchManager_eClient
+  {
+  public:
+    // Constructeur et destructeur
+    FactBatchManager_eLSF();
+    virtual ~FactBatchManager_eLSF();
+
+    virtual BatchManager * operator() (const char * hostname) const;
+    virtual BatchManager_eClient * operator() (const char * hostname, const char * protocol, const char * mpiImpl) const;
+
+  protected:
+
+  private:
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_FactBatchManager_ePBS.cxx b/src/Batch/Batch_FactBatchManager_ePBS.cxx
new file mode 100644 (file)
index 0000000..3bcbda5
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_ePBS.cxx : 
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Date   : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <string>
+#include "Batch_BatchManager_ePBS.hxx"
+#include "Batch_FactBatchManager_ePBS.hxx"
+//#include "utilities.h"
+
+namespace Batch {
+
+  static FactBatchManager_ePBS sFBM_ePBS;
+
+  // Constructeur
+  FactBatchManager_ePBS::FactBatchManager_ePBS() : FactBatchManager_eClient("ePBS")
+  {
+    // Nothing to do
+  }
+
+  // Destructeur
+  FactBatchManager_ePBS::~FactBatchManager_ePBS()
+  {
+    // Nothing to do
+  }
+
+  // Functor
+  BatchManager * FactBatchManager_ePBS::operator() (const char * hostname) const
+  {
+    // MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'");
+    return new BatchManager_ePBS(this, hostname);
+  }
+
+  BatchManager_eClient * FactBatchManager_ePBS::operator() (const char * hostname, const char * protocol, const char * mpiImpl) const
+  {
+    // MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'");
+    return new BatchManager_ePBS(this, hostname, protocol, mpiImpl);
+  }
+
+
+}
diff --git a/src/Batch/Batch_FactBatchManager_ePBS.hxx b/src/Batch/Batch_FactBatchManager_ePBS.hxx
new file mode 100644 (file)
index 0000000..69fdf32
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_ePBS.hxx : 
+ *
+ * Auteur : Bernard SECHER : CEA DEN
+ * Date   : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_ePBS_H_
+#define _FACTBATCHMANAGER_ePBS_H_
+
+using namespace std;
+#include <string>
+#include <map>
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_FactBatchManager_eClient.hxx"
+
+namespace Batch {
+  
+  class BatchManager_ePBS;
+
+  class FactBatchManager_ePBS : public FactBatchManager_eClient
+  {
+  public:
+    // Constructeur et destructeur
+    FactBatchManager_ePBS();
+    virtual ~FactBatchManager_ePBS();
+
+    virtual BatchManager * operator() (const char * hostname) const;
+    virtual BatchManager_eClient * operator() (const char * hostname, const char * protocol, const char * mpiImpl) const;
+
+  protected:
+
+  private:
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_JobInfo_eLSF.cxx b/src/Batch/Batch_JobInfo_eLSF.cxx
new file mode 100644 (file)
index 0000000..177f2eb
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_eLSF.cxx :  emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_eLSF.hxx"
+
+namespace Batch {
+
+
+
+  // Constructeurs
+  JobInfo_eLSF::JobInfo_eLSF(int id, string logFile) : JobInfo()
+  {
+    // On remplit les membres _param et _env
+    ostringstream oss;
+    oss << id;
+    _param[ID] = oss.str();
+
+    // read status of job in log file
+    char line[128];
+    ifstream fp(logFile.c_str(),ios::in);
+    fp.getline(line,80,'\n');
+    
+    string sjobid, username, status;
+    fp >> sjobid;
+    fp >> username;
+    fp >> status;
+
+    _param[STATE] = status;
+
+    if( status.find("RUN") != string::npos)
+      _running = true;
+
+  }
+
+  // Teste si un job est present en machine
+  bool JobInfo_eLSF::isRunning() const
+  {
+    return _running;
+  }
+
+
+  // Destructeur
+  JobInfo_eLSF::~JobInfo_eLSF()
+  {
+    // Nothing to do
+  }
+
+  // Convertit une date HH:MM:SS en secondes
+  long JobInfo_eLSF::HMStoLong(const string & s)
+  {
+    long hour, min, sec;
+
+    sscanf( s.c_str(), "%ld:%ld:%ld", &hour, &min, &sec);
+    return ( ( ( hour * 60L ) + min ) * 60L ) + sec;
+  }
+
+  // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+  string JobInfo_eLSF::__str__() const
+  {
+    ostringstream sst;
+    sst << "<JobInfo_eLSF (" << this << ") :" << endl;
+    sst << " ID = " <<_param[ID] << endl;
+    sst << " STATE = " <<_param[STATE] << endl;
+
+    return sst.str();
+  }
+
+
+}
diff --git a/src/Batch/Batch_JobInfo_eLSF.hxx b/src/Batch/Batch_JobInfo_eLSF.hxx
new file mode 100644 (file)
index 0000000..51d3f6f
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_eLSF.hxx :  emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#ifndef _JOBINFO_LSF_H_
+#define _JOBINFO_LSF_H_
+
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+  class JobInfo_eLSF : public JobInfo
+  {
+  public:
+    // Constructeurs et destructeur
+    JobInfo_eLSF() : _running(false) {};
+    JobInfo_eLSF(int id,std::string logFile);
+    virtual ~JobInfo_eLSF();
+
+    // Constructeur par recopie
+    JobInfo_eLSF(const JobInfo_eLSF & jinfo) : JobInfo(jinfo) {};
+
+    // Teste si un job est present en machine
+    virtual bool isRunning() const;
+
+    // Methodes pour l'interfacage avec Python (SWIG)
+    // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+    string  __str__() const; // SWIG : affichage en Python
+    string  __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+  protected:
+    bool _running; // etat du job en machine
+
+  private:
+    // Convertit une date HH:MM:SS en secondes
+    long HMStoLong(const string &);
+
+  };
+
+}
+
+#endif
diff --git a/src/Batch/Batch_JobInfo_ePBS.cxx b/src/Batch/Batch_JobInfo_ePBS.cxx
new file mode 100644 (file)
index 0000000..6d9807a
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_ePBS.cxx :  emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_ePBS.hxx"
+
+namespace Batch {
+
+
+
+  // Constructeurs
+  JobInfo_ePBS::JobInfo_ePBS(int id, string logFile) : JobInfo()
+  {
+    // On remplit les membres _param et _env
+    ostringstream oss;
+    oss << id;
+    _param[ID] = oss.str();
+
+    // read of log file
+    char line[128];
+    ifstream fp(logFile.c_str(),ios::in);
+      
+    string status;
+    string sline;
+    int pos = string::npos;
+    while( (pos == string::npos) && fp.getline(line,80,'\n') ){
+      sline = string(line);
+      pos = sline.find("job_state");
+    };
+      
+    if(pos!=string::npos){
+      istringstream iss(sline);
+      iss >> status;
+      iss >> status;
+      iss >> status;
+    }
+    else
+      status = "U";
+
+    _param[STATE] = status;
+
+    if( status.find("R") != string::npos)
+      _running = true;
+
+  }
+
+  // Teste si un job est present en machine
+  bool JobInfo_ePBS::isRunning() const
+  {
+    return _running;
+  }
+
+
+  // Destructeur
+  JobInfo_ePBS::~JobInfo_ePBS()
+  {
+    // Nothing to do
+  }
+
+  // Convertit une date HH:MM:SS en secondes
+  long JobInfo_ePBS::HMStoLong(const string & s)
+  {
+    long hour, min, sec;
+
+    sscanf( s.c_str(), "%ld:%ld:%ld", &hour, &min, &sec);
+    return ( ( ( hour * 60L ) + min ) * 60L ) + sec;
+  }
+
+  // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+  string JobInfo_ePBS::__str__() const
+  {
+    ostringstream sst;
+    sst << "<JobInfo_ePBS (" << this << ") :" << endl;
+    sst << " ID = " <<_param[ID] << endl;
+    sst << " STATE = " <<_param[STATE] << endl;
+
+    return sst.str();
+  }
+
+
+}
diff --git a/src/Batch/Batch_JobInfo_ePBS.hxx b/src/Batch/Batch_JobInfo_ePBS.hxx
new file mode 100644 (file)
index 0000000..79fb0b7
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_ePBS.hxx :  emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail   : mailto:bernard.secher@cea.fr
+ * Date   : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome 
+ *
+ */
+
+#ifndef _JOBINFO_PBS_H_
+#define _JOBINFO_PBS_H_
+
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+  class JobInfo_ePBS : public JobInfo
+  {
+  public:
+    // Constructeurs et destructeur
+    JobInfo_ePBS() : _running(false) {};
+    JobInfo_ePBS(int id,std::string logFile);
+    virtual ~JobInfo_ePBS();
+
+    // Constructeur par recopie
+    JobInfo_ePBS(const JobInfo_ePBS & jinfo) : JobInfo(jinfo) {};
+
+    // Teste si un job est present en machine
+    virtual bool isRunning() const;
+
+    // Methodes pour l'interfacage avec Python (SWIG)
+    // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+    string  __str__() const; // SWIG : affichage en Python
+    string  __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+  protected:
+    bool _running; // etat du job en machine
+
+  private:
+    // Convertit une date HH:MM:SS en secondes
+    long HMStoLong(const string &);
+
+  };
+
+}
+
+#endif
diff --git a/src/DSC/DSC.dox b/src/DSC/DSC.dox
new file mode 100644 (file)
index 0000000..f80a7cc
--- /dev/null
@@ -0,0 +1,49 @@
+/*!
+
+\page dsc_page DSC
+
+DSC means Dynamic Software Component. It's an extension of the %SALOME programming model.
+It provides a new paradigm to design %SALOME components. It also provides new ports for %SALOME services.
+These ports are : interface ports and datastream ports.
+
+\section S1_DSC Datastream ports
+
+We list in this section the datastream ports that are provided by %SALOME.
+
+<ol>
+
+<li>
+<b>BASIC datastream ports</b>
+<table>
+<tr><td> <b> Port name </b> </td><td> <b> Data type </b> </td><td> <b> Idl Name </b> </td><td> <b> Idl File </b> </td></tr>
+<tr><td> BASIC_short </td><td> short </td><td> Data_Short_Port </td><td> SALOME_Ports.idl </td></tr>
+</table>
+</li>
+
+<li>
+<b>CALCIUM datastream ports</b>
+<table>
+<tr><td> <b> Port name </b> </td><td> <b> Data type </b> </td><td> <b> Idl Name </b> </td><td> <b> Idl File </b> </td></tr>
+<tr><td> CALCIUM_integer </td><td> sequence of long </td><td> Calcium_Integer_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_real </td><td> sequence of float </td><td> Calcium_Real_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_double </td><td> sequence of double </td><td> Calcium_Double_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_string </td><td> sequence of %string </td><td> Calcium_String_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_logical </td><td> sequence of boolean </td><td> Calcium_Logical_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_complex </td><td> sequence of float </td><td> Calcium_Complex_Port </td><td> Calcium_Ports.idl </td></tr>
+</table>
+</li>
+
+<li>
+<b>PALM datastream ports</b>
+<table>
+<tr><td> <b> Port name </b> </td><td> <b> Data type </b> </td><td> <b> Idl Name </b> </td><td> <b> Idl File </b> </td></tr>
+<tr><td> PALM_short </td><td> short </td><td> Palm_Data_Short_Port </td><td> Palm_Ports.idl </td></tr>
+<tr><td> PALM_seq_short </td><td> sequence of short </td><td> Palm_Data_Seq_Short_Port </td><td> Palm_Ports.idl </td></tr>
+</table>
+</li>
+
+</ol>
+
+*/
+
+
diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx
new file mode 100644 (file)
index 0000000..969b510
--- /dev/null
@@ -0,0 +1,532 @@
+//  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library 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 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+//  File   : CalciumCxxInterface.hxx
+//  Author : Eric Fayolle (EDF)
+//  Module : KERNEL
+// Modified by : $LastChangedBy$
+// Date        : $LastChangedDate: 2007-03-01 13:27:58 +0100 (jeu, 01 mar 2007) $
+// Id          : $Id$
+
+#ifndef _CALCIUM_CXXINTERFACE_HXX_
+#define _CALCIUM_CXXINTERFACE_HXX_
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include "Superv_Component_i.hxx"
+#include "CalciumException.hxx"
+#include "CalciumTypes.hxx"
+#include "CalciumGenericUsesPort.hxx"
+#include "Copy2UserSpace.hxx"
+#include "Copy2CorbaSpace.hxx"
+#include "CalciumPortTraits.hxx"
+
+#include <stdio.h>
+
+//#define _DEBUG_
+
+template <typename T1, typename T2>
+struct IsSameType {
+  static const bool value = false;
+};
+template <typename T1>
+struct IsSameType<T1,T1> {
+  static const bool value = true;
+};
+
+
+#include <boost/type_traits/remove_all_extents.hpp>
+
+namespace CalciumInterface {
+  
+  /********************* INTERFACE DE DECONNEXION *****************/
+
+  static inline void
+  ecp_cd (Superv_Component_i & component, std::string & instanceName)
+  { 
+    /* TODO : Trouver le nom de l'instance SALOME*/
+    if (instanceName.empty()) instanceName="UNDEFINED";
+
+  }
+
+  static void
+  ecp_fin (Superv_Component_i & component, bool provideLastGivenValue)
+  { 
+    std::vector<std::string> usesPortNames;
+    std::vector<std::string>::const_iterator it;
+    component.get_uses_port_names(usesPortNames);    
+    
+    //Récupérer le type de réel du port est un peu difficile
+    //car l'interface ne donne aucune indication
+
+    //     uses_port *myUsesPort;
+    calcium_uses_port* myCalciumUsesPort;
+      
+    for (it=usesPortNames.begin(); it != usesPortNames.end(); ++it) {
+      try {
+
+       myCalciumUsesPort= 
+         component.Superv_Component_i::get_port< calcium_uses_port >((*it).c_str());
+
+//     component.Superv_Component_i::get_port(myUsesPort,(*it).c_str());
+//     calcium_uses_port* myCalciumUsesPort=
+//       dynamic_cast<calcium_uses_port*>(myUsesPort);
+
+#ifdef _DEBUG_
+       std::cerr << "-------- CalciumInterface(ecp_fin) MARK 1 -|"<< *it <<"|----"<< 
+         //      typeid(myUsesPort).name() <<"-------------" <<
+         typeid(myCalciumUsesPort).name() <<"-------------" << std::endl;
+#endif
+       
+//     if ( !myCalciumUsesPort )
+//       throw Superv_Component_i::BadCast(LOC(OSS()<<"Impossible de convertir le port "
+//                                             << *it << " en port de type calcium_uses_port." ));
+
+       myCalciumUsesPort->disconnect(provideLastGivenValue);
+
+      } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+       std::cerr << ex.what() << std::endl;
+#endif
+       throw (CalciumException(CalciumTypes::CPTPVR,ex));
+      } catch ( const DSC_Exception & ex) {
+#ifdef _DEBUG_
+       std::cerr << ex.what() << std::endl;
+#endif
+       // Exception venant de SupervComponent :
+       //   PortNotDefined(CPNMVR), PortNotConnected(CPLIEN)  
+       // ou du port uses : Dsc_Exception
+       // On continue à traiter la deconnexion des autres ports uses
+      } catch (...) {
+       throw (CalciumException(CalciumTypes::CPATAL,"Exception innatendue"));
+       // En fonction du mode de gestion des erreurs throw;
+      }
+    }
+  }
+
+
+  /********************* INTERFACES DE DESALLOCATION  *****************/
+
+  // Uniquement appelé par l'utilisateur s'il utilise la 0 copie
+  //   ( pointeur de données data==NULL à l'appel de ecp_lecture )
+  // Une désallocation aura lieu uniquement si un buffer intermédiaire
+  // était necessaire (type utilisateur et corba diffférent)
+  // La propriété du buffer est rendue à CORBA sinon  
+  template <typename T1, typename T2> static void
+  ecp_free ( T1 * dataPtr )
+  {
+    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
+    typedef typename PortType::DataManipulator            DataManipulator;
+    typedef typename DataManipulator::Type                DataType; // Attention != T1
+    typedef typename DataManipulator::InnerType           InnerType;
+
+    DeleteTraits<IsSameType<T1,InnerType>::value, DataManipulator >::apply(dataPtr);
+  }
+
+  template <typename T1> static void
+  ecp_free ( T1 * dataPtr )
+  {
+    ecp_free<T1,T1> ( dataPtr );
+  }
+
+
+  /********************* INTERFACES DE LECTURE *****************/
+
+
+  // T1 est le type de données
+  // T2 est un <nom> de type Calcium permettant de sélectionner le port CORBA correspondant 
+  // T1 et T2 sont dissociés pour discriminer le cas des nombres complexes
+  //  -> Les données des nombres complexes sont de type float mais
+  //     le port à utiliser est le port cplx
+  template <typename T1, typename T2 > static void
+  ecp_lecture ( Superv_Component_i & component,
+              int    const  & dependencyType,
+              double        & ti,
+              double const  & tf,
+              long          & i,
+              const string  & nomVar, 
+              size_t          bufferLength,
+              size_t        & nRead, 
+              T1            * &data )
+  {
+
+    assert(&component);
+
+    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
+    typedef typename PortType::DataManipulator            DataManipulator;
+    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T1
+    typedef typename DataManipulator::InnerType           InnerType;
+    CalciumTypes::DependencyType _dependencyType=              
+      static_cast<CalciumTypes::DependencyType>(dependencyType);
+    
+    CorbaDataType     corbaData;
+
+#ifdef _DEBUG_
+    std::cerr << "-------- CalciumInterface(ecp_lecture) MARK 1 ------------------" << std::endl;
+#endif
+
+    if (nomVar.empty())
+      throw CalciumException(CalciumTypes::CPNMVR,
+                               LOC("Le nom de la variable est <nul>"));
+    PortType * port;
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 2 ------------------" << std::endl;
+#endif
+
+    try {
+      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 3 ------------------" << std::endl;
+#endif
+    } catch ( const Superv_Component_i::PortNotDefined & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPNMVR,ex));
+    } catch ( const Superv_Component_i::PortNotConnected & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;;
+#endif
+      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
+      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
+    } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPTPVR,ex));
+    }
+  
+    // mode == mode du port 
+    CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
+
+    if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
+      throw CalciumException(CalciumTypes::CPIT,
+                            LOC(OSS()<<"Le mode de dépendance de la variable " 
+                                << nomVar << " est indéfini."));
+
+    if ( ( portDependencyType != _dependencyType ) && 
+        ( _dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) ) 
+      throw CalciumException(CalciumTypes::CPITVR,
+                            LOC(OSS()<<"Le mode de dépendance de la variable " 
+                                << nomVar << ": " << portDependencyType 
+                                << " ne correspond pas au mode demandé."));
+
+  
+    if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
+      corbaData = port->get(ti,tf, 0);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 5 ------------------" << std::endl;
+#endif
+    } 
+    else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
+      corbaData = port->get(0, i);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl;
+#endif
+    } else {
+      // Lecture en séquence
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 7 ------------------" << std::endl;
+#endif
+      corbaData = port->next(ti,i);
+    }
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 8 ------------------" << std::endl;
+#endif
+    size_t corbaDataSize = DataManipulator::size(corbaData);
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture) corbaDataSize : " << corbaDataSize << std::endl;
+#endif
+   
+    // Vérifie si l'utilisateur demande du 0 copie
+    if ( data == NULL ) {
+      if ( bufferLength != 0 ) {
+       MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)");
+      }
+      nRead = corbaDataSize;
+      // Si les types T1 et InnerType sont différents, il faudra effectuer tout de même une recopie
+      if (!IsSameType<T1,InnerType>::value) data = new T1[nRead];
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl;
+#endif
+      // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes.
+      // Copy2UserSpace : 
+      // La raison d'être du foncteur Copy2UserSpace est que le compilateur n'acceptera
+      // pas une expresion d'affectation sur des types incompatibles même 
+      // si cette expression se trouve dans une branche non exécuté d'un test
+      // sur la compatibilité des types.
+      // En utilisant le foncteur Copy2UserSpace, seul la spécialisation en adéquation
+      // avec la compatibilité des types sera compilée 
+      Copy2UserSpace< IsSameType<T1,InnerType>::value, DataManipulator >::apply(data,corbaData,nRead);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl;
+#endif
+      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
+      // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+      // DataManipulator::delete_data(corbaData); 
+      // ni DataManipulator::getPointer(corbaData,true); qui détruit la sequence lorsque l'on
+      // prend la propriété du buffer
+      //  old : Dans les deux cas la structure CORBA n'est plus utile 
+      //  old : Si !IsSameType<T1,InnerType>::value l'objet CORBA est détruit avec son contenu
+      //  old : Dans l'autre cas seul la coquille CORBA est détruite 
+      //  L'utilisateur devra appeler ecp_free qui déterminera s'il est necessaire
+      //  de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété
+   } else {
+      nRead = std::min < size_t > (corbaDataSize,bufferLength);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl;
+#endif
+      Copy2UserSpace<false, DataManipulator >::apply(data,corbaData,nRead);
+      DataManipulator::copy(corbaData,data,nRead);
+    
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
+#endif
+      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
+      // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+      // DataManipulator::delete_data(corbaData);
+   }
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture), Valeur de data : " << std::endl;
+    std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
+    std::cout << "Ptr :" << data << std::endl;
+
+    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl;
+#endif
+  
+    return;
+  }
+
+  // T1 est le type de données
+  template <typename T1 > static void
+  ecp_lecture ( Superv_Component_i & component,
+              int    const  & dependencyType,
+              double        & ti,
+              double const  & tf,
+              long          & i,
+              const string  & nomVar, 
+              size_t          bufferLength,
+              size_t        & nRead, 
+              T1            * &data )
+  {
+    ecp_lecture<T1,T1> (component,dependencyType,ti,tf,
+                       i,nomVar,bufferLength,nRead,data);
+  
+  }
+
+  /********************* INTERFACES D'ECRITURE *****************/
+
+  // T1 : DataType
+  // T2 : PortType
+  template <typename T1, typename T2> static void
+  ecp_ecriture ( Superv_Component_i & component,
+                int    const  & dependencyType,
+                double const  & t,
+                long   const  & i,
+                const string  & nomVar, 
+                size_t bufferLength,
+                T1     const  & data ) 
+  {
+    
+    assert(&component);
+
+    //typedef typename StarTrait<TT>::NonStarType                    T;
+    typedef typename boost::remove_all_extents< T2 >::type           T2_without_extent;
+    typedef typename boost::remove_all_extents< T1 >::type           T1_without_extent;
+
+    typedef typename UsesPortTraits    <T2_without_extent>::PortType UsesPortType;
+    typedef typename ProvidesPortTraits<T2_without_extent>::PortType ProvidesPortType;// pour obtenir un manipulateur de données
+    typedef typename ProvidesPortType::DataManipulator               DataManipulator;
+    // Verifier que l'on peut définir UsesPortType::DataManipulator
+    //    typedef typename PortType::DataManipulator            DataManipulator;
+    typedef typename DataManipulator::Type                           CorbaDataType; // Attention != T1
+    typedef typename DataManipulator::InnerType                      InnerType;
+    
+    T1_without_extent const & _data = data;
+
+    CalciumTypes::DependencyType _dependencyType=              
+      static_cast<CalciumTypes::DependencyType>(dependencyType);
+
+#ifdef _DEBUG_
+    std::cerr << "-------- CalciumInterface(ecriture) MARK 1 ------------------" << std::endl;
+#endif
+    if ( nomVar.empty() ) throw CalciumException(CalciumTypes::CPNMVR,
+                                                   LOC("Le nom de la variable est <nul>"));
+    UsesPortType * port;
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture) MARK 2 ------------------" << std::endl;
+#endif
+
+    try {
+      port  = component.Superv_Component_i::get_port< UsesPortType > (nomVar.c_str());
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl;
+#endif
+    } catch ( const Superv_Component_i::PortNotDefined & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPNMVR,ex));
+    } catch ( const Superv_Component_i::PortNotConnected & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;;
+#endif
+      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
+      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
+    } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPTPVR,ex));
+    }
+    // mode == mode du port 
+    // On pourrait créer la méthode CORBA dans le mode de Couplage CALCIUM.
+    // et donc ajouter cette cette méthode uniquement dans l'IDL calcium !
+
+//     CalciumTypes::DependencyType portDependencyType;
+//     try {
+//       portDependencyType = port->getDependencyType();
+//       std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
+//     } catch ( const DSC_Exception & ex ) {
+//       std::cerr << ex.what() << std::endl;;
+//       throw (CalciumException(CalciumTypes::CPIT,ex));
+//     }
+
+    if ( _dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
+      throw CalciumException(CalciumTypes::CPIT,
+                               LOC(OSS()<<"Le mode de dépendance demandé pour la variable " 
+                                   << nomVar << " est indéfini."));
+
+    if ( _dependencyType == CalciumTypes::SEQUENCE_DEPENDENCY )
+      throw CalciumException(CalciumTypes::CPIT,
+                               LOC(OSS()<<"Le mode de dépendance SEQUENCE_DEPENDENCY pour la variable " 
+                                   << nomVar << " est impossible en écriture."));
+
+    // Il faudrait que le port provides génère une exception si le mode donnée n'est pas
+    // le bon. La seule façon de le faire est d'envoyer -1 en temps si on n'est en itération
+    // et vice-versa pour informer les provides port du mode dans lequel on est. Sinon il faut
+    // modifier l'interface IDL pour y ajouter un mode de dépendance !
+    // ---->
+//     if ( portDependencyType != _dependencyType ) 
+//       throw CalciumException(CalciumTypes::CPITVR,
+//                             LOC(OSS()<<"Le mode de dépendance de la variable " 
+//                                 << nomVar << " ne correspond pas au mode demandé."));
+
+  
+    if ( bufferLength < 1 )
+      throw CalciumException(CalciumTypes::CPNTNULL,
+                               LOC(OSS()<<"Le buffer a envoyer est de taille nulle "));
+
+
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
+#endif
+    CorbaDataType corbaData;
+
+    
+    // Si les types Utilisateurs et CORBA sont différents
+    // il faut effectuer une recopie sinon on utilise directement le
+    // buffer data pour constituer la séquence
+    // TODO : 
+    // - Attention en mode asynchrone il faudra eventuellement
+    //   faire une copie des données même si elles sont de même type.
+    // - OLD : En cas de collocalisation (du port provide et du port uses)
+    //   OLD : il est necessaire d'effectuer une recopie du buffer car la
+    //   OLD : séquence est envoyée au port provide par une référence sur 
+    //   OLD : la séquence locale. Or la méthode put récupère le buffer directement
+    //   OLD : qui est alors le buffer utilisateur. Il pourrait alors arriver que :
+    //   OLD :   * Le recepteur efface le buffer emetteur
+    //   OLD :   * Le port lui-même efface le buffer de l'utilisateur !
+    //   OLD : Cette copie est effectuée dans GenericPortUses::put 
+    //   OLD : en fonction de la collocalisation ou non.
+    // - OLD :En cas de connection multiples d'un port uses distant vers plusieurs port provides
+    //   OLD : collocalisés les ports provides partagent la même copie de la donnée ! 
+    //   OLD : Il faut effectuer une copie dans le port provides.
+    //   OLD : Cette copie est effectuée dans GenericPortUses::put 
+    //   OLD : en fonction de la collocalisation ou non.
+    Copy2CorbaSpace<IsSameType<T1_without_extent,InnerType>::value, DataManipulator >::apply(corbaData,_data,bufferLength);
+    //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté
+    if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
+      try
+      {
+        port->put(*corbaData,t, -1); 
+      }
+      catch ( const DSC_Exception & ex) 
+      {
+        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
+      }
+      //Le -1 peut être traité par le cst DataIdContainer et transformé en 0 
+      //Etre obligé de mettre une étoile ds (*corbadata) va poser des pb pour les types <> seq
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl;
+#endif
+    } 
+    else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
+      try
+      {
+        port->put(*corbaData,-1, i);
+      }
+      catch ( const DSC_Exception & ex) 
+      {
+        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
+      }
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecriture) MARK 6 ------------------" << std::endl;
+#endif
+    } 
+
+    
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture), Valeur de corbaData : " << std::endl;
+    for (int i = 0; i < corbaData->length(); ++i)
+      cout << "-------- CalciumInterface(ecriture), corbaData[" << i << "] = " << (*corbaData)[i] << endl;
+#endif
+    
+    //    if ( !IsSameType<T1,InnerType>::value ) delete corbaData;
+    // Supprime l'objet CORBA avec eventuellement les données qu'il contient (cas de la recopie)
+    delete corbaData;
+
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture) MARK 7 ------------------" << std::endl;
+#endif
+   
+    return;
+  };
+  
+  template <typename T1> static void
+  ecp_ecriture ( Superv_Component_i & component,
+                int    const  & dependencyType,
+                double const  & t,
+                long   const  & i,
+                const string  & nomVar, 
+                size_t bufferLength,
+                T1 const & data ) {
+    ecp_ecriture<T1,T1> (component,dependencyType,t,i,nomVar,bufferLength,data); 
+  };
+
+};
+
+#endif
diff --git a/src/DSC/DSC_User/Datastream/Calcium/calciumE.h b/src/DSC/DSC_User/Datastream/Calcium/calciumE.h
new file mode 100644 (file)
index 0000000..49c9e57
--- /dev/null
@@ -0,0 +1,401 @@
+/*  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+ *  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+ * 
+ *  This library is free software; you can redistribute it and/or 
+ *  modify it under the terms of the GNU Lesser General Public 
+ *  License as published by the Free Software Foundation; either 
+ *  version 2.1 of the License. 
+ * 
+ *  This library 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 
+ *  Lesser General Public License for more details. 
+ * 
+ *  You should have received a copy of the GNU Lesser General Public 
+ *  License along with this library; if not, write to the Free Software 
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+ * 
+ * See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+ *
+ *
+ *
+ *  File   : calcium.h
+ *  Author : Eric Fayolle (EDF)
+ *  Module : KERNEL
+ */
+
+/* Outils d'Aide au Couplage de Code de Calcul : $Id$ */
+
+#ifndef __CALCIUM_E_H
+#define __CALCIUM_E_H
+
+#include <calciumP.h>
+
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define CPNeedPrototype        1
+#else
+#define CPNeedPrototype        0
+#endif
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*                                             */
+/*                                             */
+/* Fonctions de connexion                      */
+/*                                             */
+/*                                             */
+extern int     ecp_cd(
+/*             -----                           */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+        char  * /* S   Nom de l instance appelante*/
+#endif
+);
+
+
+/*                                             */
+/*                                             */
+/* Fonction de deconnexion                     */
+/*                                             */
+/*                                             */
+extern int     ecp_fin(
+/*             ------                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E Directive de continuation  */
+               /* CP_CONT ou CP_ARRET          */
+#endif
+);
+
+/*                                             */
+/*                                             */
+/* Fonctions de libération du buffer 0 copy    */
+/*                                             */
+
+  extern void ecp_len_free(
+#if CPNeedPrototype
+                          int *
+#endif
+                          );
+  extern void ecp_lre_free(
+#if CPNeedPrototype
+                          float *
+#endif
+                          );
+  extern void ecp_ldb_free(
+#if CPNeedPrototype
+                          double *
+#endif
+                          );
+  extern void ecp_llo_free(
+#if CPNeedPrototype
+                          int *
+#endif
+                          );
+  extern void ecp_lcp_free(
+#if CPNeedPrototype
+                          float *
+#endif
+                          );
+  extern void ecp_lch_free(
+#if CPNeedPrototype
+                          char **
+#endif
+                          );
+
+
+
+/*                                             */
+/*                                             */
+/* Fonctions de lecture bloquante 0 copy       */
+/*                                             */
+/*                                             */
+extern int     ecp_len(
+/*             ------                                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       int   ** /* E/S   Tableau d'entiers pour stocker les    */
+               /*     valeurs lues                             */
+#endif
+);
+
+extern int     ecp_lre(
+/*             ------                                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       float **/* E/S   Tableau de flottants pour stocker les  */
+               /*     valeurs lues                             */
+#endif
+);
+
+extern int     ecp_ldb(
+/*             ------                                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       double* /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       double* /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       double**/* E/S   Tableau de doubles pour stocker les    */
+               /*     valeurs lues                             */
+#endif
+);
+
+extern int     ecp_lcp(
+/*             ------                                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration lire                     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       float **/* E/S   Tableau de flottants pour stocker les  */
+               /*     valeurs lues (dimension = 2 * le nombre  */
+               /*     de valeurs lues)                         */
+#endif
+);
+
+extern int     ecp_llo(
+/*             ------                                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       int  ** /* E/S   Tableau d 'entier pour stocker les     */
+               /*     valeurs lues (remplace le logiques)      */
+#endif
+);
+
+extern int     ecp_lch(
+/*             ------                                          */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       char **[]/*E/S   Tableau de chaines pour stocker les    */
+               /*     valeurs lues (remplace le logiques)      */,
+       int     /* E   Taille des chaines du tablaeu            */
+#endif
+);
+
+
+
+/*                                             */
+/*                                             */
+/* Fonctions de lecture non bloquantes         */
+/*                                             */
+/*                                             */
+extern int     ecp_nlen(
+/*             -------                                         */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       int  ** /* E/S   Tableau d'entiers pour stocker les     */
+               /*     valeurs lues                             */
+#endif
+);
+
+extern int     ecp_nlre(
+/*             -------                                         */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       float **/* E/S   Tableau de flottants pour stocker les  */
+               /*     valeurs lues                             */
+#endif
+);
+
+extern int     ecp_nldb(
+/*             -------                                         */
+
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       double */* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       double */* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       double**/* E/S   Tableau de doubles pour stocker les    */
+               /*     valeurs lues                             */
+#endif
+);
+
+extern int     ecp_nlcp(
+/*             -------                                         */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration lire                     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       float **/* E/S   Tableau de flottants pour stocker les  */
+               /*     valeurs lues (dimension = 2 * le nombre  */
+               /*     de valeurs lues)                         */
+#endif
+);
+
+extern int     ecp_nllo(
+/*             -------                                         */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       int   **/* E/S   Tableau d 'entier pour stocker les     */
+               /*     valeurs lues (remplace le logiques)      */
+#endif
+);
+
+extern int     ecp_nlch(
+/*             -------                                         */
+#if CPNeedPrototype
+       void * component /* Pointeur de type Superv_Component_i* sur le */
+                        /* composant SALOME Supervisable  */,
+       int     /* E   Type de dependance ou de lecture         */
+               /*     CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL    */,
+       float * /* E/S Borne inf de l'intervalle de lecture     */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       float * /* E   Borne Sup de l'intervalle de lecture     */,
+       int   * /* E/S Pas d'iteration a lire                   */
+               /*     Retourne le pas lu dans le cas de        */
+               /*     lecture sequentielle                     */,
+       char  * /* E   Nom de la variable a lire                */,
+       int     /* E   Nombre max de valeurs a lire             */,
+       int   * /* S   Nombre de valeurs rellement lues         */,
+       char **[]/* E/S   Tableau de chaines pour stocker les   */
+               /*     valeurs lues (remplace le logiques)      */,
+       int     /* E   Taille des chaines du tablaeu            */
+#endif
+);
+
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif
diff --git a/src/Launcher/BatchTest.cxx b/src/Launcher/BatchTest.cxx
new file mode 100644 (file)
index 0000000..bb44166
--- /dev/null
@@ -0,0 +1,689 @@
+#include "BatchTest.hxx"
+
+BatchTest::BatchTest(const Engines::MachineParameters& batch_descr) 
+{
+  _batch_descr = batch_descr;
+
+  // Getting date
+  Batch::Date date = Batch::Date(time(0));
+  _date = date.str();
+  int lend = _date.size() ;
+  int i = 0 ;
+  while (i < lend) 
+  {
+    if (_date[i] == '/' || _date[i] == '-' || _date[i] == ':' ) 
+    {
+      _date[i] = '_' ;
+    }
+    i++ ;
+  }
+
+  // Creating test temporary file
+  _test_filename =  "/tmp/";
+  _test_filename +=  _date + "_test_cluster_file_";
+  _test_filename += _batch_descr.alias.in();
+  _base_filename = _date + "_test_cluster_file_" + _batch_descr.alias.in();
+}
+
+BatchTest::~BatchTest() {}
+
+bool
+BatchTest::test()
+{
+  bool rtn = false;
+  INFOS(std::endl 
+       << "--- Testing batch Machine :" << std::endl
+       << "--- Name       : " << _batch_descr.hostname << std::endl
+       << "--- Alias      : " << _batch_descr.alias << std::endl
+       << "--- Protocol   : " << _batch_descr.protocol << std::endl
+       << "--- User Name  : " << _batch_descr.username << std::endl
+       << "--- Batch Type : " << _batch_descr.batch << std::endl
+       << "--- MPI Impl   : " << _batch_descr.mpiImpl << std::endl
+       << "--- Appli Path : " << _batch_descr.applipath << std::endl
+       );
+
+  std::string result_connection("Not Tested");
+  std::string result_filecopy("Not Tested");
+  std::string result_getresult("Not Tested");
+  std::string result_jobsubmit_simple("Not Tested");
+  std::string result_jobsubmit_mpi("Not Tested");
+  std::string result_appli("Not Tested");
+
+  result_connection = test_connection();
+  result_filecopy = test_filecopy();
+  result_getresult = test_getresult();
+  result_jobsubmit_simple = test_jobsubmit_simple();
+  result_jobsubmit_mpi = test_jobsubmit_mpi();
+  result_appli = test_appli();
+
+  INFOS(std::endl
+       << "--- Test results" << std::endl
+       << "--- Connection          : " << result_connection << std::endl
+       << "--- File copy           : " << result_filecopy << std::endl
+       << "--- Get results         : " << result_getresult << std::endl
+       << "--- Submit simple job   : " << result_jobsubmit_simple << std::endl
+       << "--- Submit mpi job      : " << result_jobsubmit_mpi << std::endl
+       << "--- Application         : " << result_appli << std::endl
+       );
+  
+  if (result_connection == "OK"       and 
+      result_filecopy == "OK"         and 
+      result_getresult == "OK"        and
+      result_jobsubmit_simple == "OK" and 
+      result_jobsubmit_mpi == "OK"    and 
+      result_appli == "OK")
+    rtn = true;
+      
+  return rtn;
+}
+
+// For this test we use : alias, protocol, username
+std::string
+BatchTest::test_connection()
+{
+  int status;
+  std::string command;
+  std::string result("Failed : ");
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+
+  // Basic tests
+  if(alias == "")
+  {
+    result += "alias is empty !";
+    return result;
+  }
+  if(username == "")
+  {
+    result += "username is empty !";
+    return result;
+  }
+  if( protocol != "rsh" and protocol != "ssh")
+  {
+    result += "protocol unknown ! (" + protocol + ")";
+    return result;
+  }
+
+  // Build command
+  command += protocol
+         + " "
+         + username + "@" + alias;
+
+  // Test
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error of connection on remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  result = "OK";
+  return result;
+}
+
+// For this test we use : alias, protocol, username
+std::string
+BatchTest::test_filecopy()
+{
+  int status;
+  std::string home;
+  std::string command;
+  std::string result("Failed : ");
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+
+  // Getting home directory
+  std::string rst = get_home(&home);
+  if(rst != "") {
+    result += rst;
+    return result;
+  }
+
+  // Writing into the tempory file
+  command = "echo Hello > " +  _test_filename;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in creating tempory file ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  // Build command
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " + _test_filename + " "
+         + username + "@" + alias + ":" + home;
+
+  // Test
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in copy file on remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  result = "OK";
+  return result;
+}
+
+// For this test we use : alias, protocol, username
+std::string
+BatchTest::test_getresult()
+{
+  int status;
+  std::string home;
+  std::string command;
+  std::string result("Failed : ");
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+
+  // Getting home directory
+  std::string rst = get_home(&home);
+  if(rst != "") {
+    result += rst;
+    return result;
+  }
+
+  // Build command
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " + username + "@" + alias + ":" + home 
+         + "/" + _base_filename + " " + _test_filename + "_copy";
+
+  // Test
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in copy file from remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+  
+  // Compare files
+  std::ifstream src_file(_test_filename.c_str());
+  if (!src_file)
+  {
+    result += "Error in reading temporary file ! filename = " + _test_filename;
+    return result;
+  }
+  std::string cp_filename = _test_filename + "_copy";
+  std::ifstream cp_file(cp_filename.c_str());
+  if (!cp_file)
+  {
+    result += "Error in reading temporary copy file ! filename = " + cp_filename;
+    return result;
+  }
+  std::string src_firstline;
+  std::string cp_firstline;
+  std::getline(src_file, src_firstline);
+  std::getline(cp_file, cp_firstline);
+  src_file.close();
+  cp_file.close();
+  if (src_firstline != cp_firstline)
+  {
+    result += "Error source file and copy file are not equa ! source = " + src_firstline + " copy = " + cp_firstline;
+    return result;
+  }
+
+  result = "OK";
+  return result;
+}
+
+std::string 
+BatchTest::test_jobsubmit_simple() 
+{
+  int status;
+  std::string home;
+  std::string command;
+  std::string result("Failed : ");
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+  std::string batch_type = _batch_descr.batch.in();
+
+  // Basic test
+  if (batch_type == "slurm")
+  {
+    INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK");
+    result = "OK";
+    return result;
+  }
+  if (batch_type != "pbs")
+  {
+    result += "Batch type unknown ! : " + batch_type;
+    return result;
+  }
+
+  // Getting home directory
+  std::string rst = get_home(&home);
+  if(rst != "") {
+    result += rst;
+    return result;
+  }
+
+  // PBS test
+  std::string _test_file_simple = _test_filename + "_simple";
+  std::ofstream file;
+  file.open(_test_file_simple.c_str(), std::ofstream::out);
+  file << "#!/bin/bash\n"
+       << "#PBS -l nodes=1\n"
+       << "#PBS -l walltime=00:01:00\n"
+       << "#PBS -o " + home + "/" + _date + "_simple_output.log\n"
+       << "#PBS -e " + home + "/" + _date + "_simple_error.log\n"
+       << "echo Bonjour\n"
+       << "echo Error >&2\n";
+  file.flush();
+  file.close();
+
+
+  // Build command for copy
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " + _test_file_simple + " "
+         + username + "@" + alias + ":" + home;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in copy job file to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  // Build command for submit job
+  std::string file_job_name = _test_filename + "_jobid";
+  command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_simple > " + file_job_name;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in sending qsub to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+  std::string jobid;
+  std::ifstream file_job(file_job_name.c_str());
+  if (!file_job)
+  {
+    result += "Error in reading temporary file ! filename = " + file_job_name;
+    return result;
+  }
+  std::getline(file_job, jobid);
+  file_job.close();
+  // Wait the end of the job
+  command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name;
+  bool stop = false;
+  while (!stop) 
+  {
+    status = system(command.c_str());
+    if(status && status != 153 && status != 256*153)
+    {
+      std::ostringstream oss;
+      oss << status;
+      result += "Error in sending qstat to remote host ! status = ";
+      result += oss.str();
+      return result;
+    }
+
+    if(status == 153 || status == 256*153 )
+      stop = true;
+    sleep(1);
+  }
+
+  // Build command for getting results
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " 
+         + username + "@" + alias + ":" + home + "/" + _date + "_simple* /tmp";
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "error in getting file result of qsub simple to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+  
+  // Test results
+  std::string normal_input;
+  std::string file_normal_name = "/tmp/" + _date + "_simple_output.log";
+  std::ifstream file_normal(file_normal_name.c_str());
+  if (!file_normal)
+  {
+    result += "Error in reading temporary file ! filename = " + file_normal_name;
+    return result;
+  }
+  std::getline(file_normal, normal_input);
+  file_normal.close();
+  if (normal_input != "Bonjour")
+  {
+    result += "error from simple ouput file ! waiting for Bonjour and get : " + normal_input;
+    return result;
+  }
+  std::string error_input;
+  std::string file_error_name = "/tmp/" + _date + "_simple_error.log";
+  std::ifstream file_error(file_error_name.c_str());
+  if (!file_error)
+  {
+    result += "Error in reading temporary file ! filename = " + file_error_name;
+    return result;
+  }
+  std::getline(file_error, error_input);
+  file_error.close();
+  if (error_input != "Error")
+  {
+    result += "error from simple error file ! waiting for Error and get : " + error_input;
+    return result;
+  }
+  result = "OK";
+  return result;
+}
+
+std::string 
+BatchTest::test_jobsubmit_mpi() 
+{
+  int status;
+  std::string home;
+  std::string command;
+  MpiImpl * mpiImpl;
+  std::string result("Failed : ");
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+  std::string batch_type = _batch_descr.batch.in();
+  std::string mpi_type = _batch_descr.mpiImpl.in();
+
+  // Basic test
+  if(mpi_type == "lam")
+    mpiImpl = new MpiImpl_LAM();
+  else if(mpi_type == "mpich1")
+    mpiImpl = new MpiImpl_MPICH1();
+  else if(mpi_type == "mpich2")
+    mpiImpl = new MpiImpl_MPICH2();
+  else if(mpi_type == "openmpi")
+    mpiImpl = new MpiImpl_OPENMPI();
+  else
+  {
+    result += "Error MPI impl not supported : " + mpi_type;
+    return result;
+  }
+
+  // SLURM not yet implemented...
+  if (batch_type == "slurm")
+  {
+    INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK");
+    result = "OK";
+    return result;
+  }
+
+  // Getting home directory
+  std::string rst = get_home(&home);
+  if(rst != "") {
+    result += rst;
+    return result;
+  }
+
+  // MPI test
+  std::string _test_file_script = _test_filename + "_script";
+  std::ofstream file_script;
+  file_script.open(_test_file_script.c_str(), std::ofstream::out);
+  file_script << "#!/bin/bash\n"
+             << "echo HELLO MPI\n";
+  file_script.flush();
+  file_script.close();
+  chmod(_test_file_script.c_str(), 0x1ED);
+
+  std::string _test_file_mpi = _test_filename + "_mpi";
+  std::ofstream file_mpi;
+  file_mpi.open(_test_file_mpi.c_str(), std::ofstream::out);
+  file_mpi << "#!/bin/bash\n"
+          << "#PBS -l nodes=1\n"
+          << "#PBS -l walltime=00:01:00\n"
+          << "#PBS -o " << home << "/" << _date << "_mpi_output.log\n"
+          << "#PBS -e " << home << "/" << _date << "_mpi_error.log\n"
+          << mpiImpl->boot("${PBS_NODEFILE}", 1)
+          << mpiImpl->run("${PBS_NODEFILE}", 1, _base_filename + "_script")
+          << mpiImpl->halt();
+  file_mpi.flush();
+  file_mpi.close();
+
+
+  // Build command for copy
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " + _test_file_script + " "
+         + username + "@" + alias + ":" + home;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in copy job file to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " + _test_file_mpi + " "
+         + username + "@" + alias + ":" + home;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in copy job file to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  // Build command for submit job
+  std::string file_job_name = _test_filename + "_jobid";
+  command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_mpi > " + file_job_name;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in sending qsub to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+  std::string jobid;
+  std::ifstream file_job(file_job_name.c_str());
+  if (!file_job)
+  {
+    result += "Error in reading temporary file ! filename = " + file_job_name;
+    return result;
+  }
+  std::getline(file_job, jobid);
+  file_job.close();
+  // Wait the end of the job
+  command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name;
+  bool stop = false;
+  while (!stop) 
+  {
+    status = system(command.c_str());
+    if(status && status != 153 && status != 256*153)
+    {
+      std::ostringstream oss;
+      oss << status;
+      result += "Error in sending qstat to remote host ! status = ";
+      result += oss.str();
+      return result;
+    }
+
+    if(status == 153 || status == 256*153 )
+      stop = true;
+    sleep(1);
+  }
+
+  // Build command for getting results
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " 
+         + username + "@" + alias + ":" + home + "/" + _date + "_mpi* /tmp";
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "error in getting file result of qsub mpi from remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+  
+  // Test results
+  std::string normal_input;
+  std::string file_normal_name = "/tmp/" + _date + "_mpi_output.log";
+  std::ifstream file_normal(file_normal_name.c_str());
+  if (!file_normal)
+  {
+    result += "Error in reading temporary file ! filename = " + file_normal_name;
+    return result;
+  }
+  bool test_ok = false;
+  while (std::getline(file_normal, normal_input))
+  {
+    if (normal_input == "HELLO MPI")
+      test_ok = true;
+  }
+  file_normal.close();
+  if (!test_ok)
+  {
+    result += "error from mpi ouput file ! waiting for HELLO MPI please watch /tmp/" + _date + "_mpi_output.log file";
+    return result;
+  }
+  result = "OK";
+  return result;
+}
+
+std::string 
+BatchTest::test_appli()
+{
+  int status;
+  std::string home;
+  std::string command;
+  std::string result("Failed : ");
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+  std::string applipath = _batch_descr.applipath.in();
+  
+  // Getting home directory
+  std::string rst = get_home(&home);
+  if(rst != "") {
+    result += rst;
+    return result;
+  }
+
+  std::string _test_file_appli = _test_filename + "_appli_test";
+  std::ofstream file_appli;
+  file_appli.open(_test_file_appli.c_str(), std::ofstream::out);
+  file_appli << "#!/bin/bash\n"
+            << "if [ -f " << applipath << "/runAppli ]\n"
+            << "then\n"
+            << "  echo OK\n"
+            << "else\n"
+            << "  echo NOK\n"
+            << "fi\n";
+  file_appli.flush();
+  file_appli.close();
+
+  // Build command for copy
+  command = "scp";
+  if(protocol == "rsh")
+    command = "rcp";
+  command += " " + _test_file_appli + " "
+         + username + "@" + alias + ":" + home;
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in copy appli test file to remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  // Launch test
+  command = protocol + " " + username + "@" + alias 
+         + " sh " + home + "/" + _base_filename + "_appli_test > " 
+         + _test_filename + "_appli_test_result";
+
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in launching appli test on remote host ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  // Read test result
+  std::string rst_appli;
+  std::string file_appli_result_name = _test_filename + "_appli_test_result";
+  std::ifstream file_appli_result(file_appli_result_name.c_str());
+  if (!file_appli_result)
+  {
+    result += "Error in reading temporary file ! filename = " + file_appli_result_name;
+    return result;
+  }
+  std::getline(file_appli_result, rst_appli);
+  file_appli_result.close();
+  
+  if (rst_appli != "OK")
+  {
+    result += "Error checking application on remote host ! result = " + rst;
+    return result;
+  }
+
+  result = "OK";
+  return result;
+}
+
+// Useful methods
+std::string
+BatchTest::get_home(std::string * home)
+{
+  int status;
+  std::string result = "";
+  std::string command;
+  std::string alias = _batch_descr.alias.in();
+  std::string username = _batch_descr.username.in();
+  std::string protocol = _batch_descr.protocol.in();
+  std::string file_home_name = _test_filename + "_home";
+
+  command = protocol + " " + username + "@" + alias + " 'echo $HOME' > " + file_home_name; 
+  status = system(command.c_str());
+  if(status) {
+    std::ostringstream oss;
+    oss << status;
+    result += "Error in getting home directory ! status = ";
+    result += oss.str();
+    return result;
+  }
+
+  std::ifstream file_home(file_home_name.c_str());
+  if (!file_home)
+  {
+    result += "Error in reading temporary file ! filename = " + file_home_name;
+    return result;
+  }
+  std::getline(file_home, *home);
+  file_home.close();
+  return result;
+}
diff --git a/src/Launcher/BatchTest.hxx b/src/Launcher/BatchTest.hxx
new file mode 100644 (file)
index 0000000..600b71b
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __BatchTest_HXX__
+#define __BatchTest_HXX__
+
+#include <sys/stat.h>
+#include <iostream>
+#include <fstream>
+
+#include <SALOMEconfig.h>
+#include "utilities.h"
+#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
+
+#include "Batch_Date.hxx"
+#include "MpiImpl.hxx"
+
+class BatchTest 
+{
+  public:
+    BatchTest(const Engines::MachineParameters& batch_descr);
+    virtual ~BatchTest();
+
+    bool test();
+
+    std::string test_connection();
+    std::string test_filecopy();
+    std::string test_getresult();
+    std::string test_jobsubmit_simple();
+    std::string test_jobsubmit_mpi();
+    std::string test_appli();
+
+  protected:
+    std::string get_home(std::string * home);
+  
+  private:
+    Engines::MachineParameters _batch_descr;
+    std::string _test_filename;
+    std::string _base_filename;
+    std::string _date;
+};
+
+#endif
diff --git a/src/Launcher/Launcher.cxx b/src/Launcher/Launcher.cxx
new file mode 100644 (file)
index 0000000..8a92e1d
--- /dev/null
@@ -0,0 +1,628 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "Batch_Date.hxx"
+#include "Batch_FactBatchManager_eLSF.hxx"
+#include "Batch_FactBatchManager_ePBS.hxx"
+#include "Launcher.hxx"
+#include <iostream>
+#include <sstream>
+#include <sys/stat.h>
+
+using namespace std;
+
+//=============================================================================
+/*! 
+ *  Constructor
+ *  \param orb
+ *  Define a CORBA single thread policy for the server, which avoid to deal
+ *  with non thread-safe usage like Change_Directory in SALOME naming service
+ */
+//=============================================================================
+
+Launcher_cpp::Launcher_cpp()
+{
+  cerr << "Launcher_cpp constructor" << endl;
+}
+
+//=============================================================================
+/*! 
+ * destructor
+ */
+//=============================================================================
+
+Launcher_cpp::~Launcher_cpp()
+{
+  cerr << "Launcher_cpp destructor" << endl;
+  std::map < string, Batch::BatchManager_eClient * >::const_iterator it1;
+  for(it1=_batchmap.begin();it1!=_batchmap.end();it1++)
+    delete it1->second;
+  std::map < std::pair<std::string,long> , Batch::Job* >::const_iterator it2;
+  for(it2=_jobmap.begin();it2!=_jobmap.end();it2++)
+    delete it2->second;
+}
+
+//=============================================================================
+/*! CORBA Method:
+ *  Submit a batch job on a cluster and returns the JobId
+ *  \param fileToExecute      : .py/.exe/.sh/... to execute on the batch cluster
+ *  \param filesToExport      : to export on the batch cluster
+ *  \param NumberOfProcessors : Number of processors needed on the batch cluster
+ *  \param params             : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+long Launcher_cpp::submitSalomeJob( const string fileToExecute ,
+                                   const vector<string>& filesToExport ,
+                                   const vector<string>& filesToImport ,
+                                   const batchParams& batch_params,
+                                   const machineParams& params) throw(LauncherException)
+{
+  cerr << "BEGIN OF Launcher_cpp::submitSalomeJob" << endl;
+  long jobId;
+  vector<string> aMachineList;
+
+  // check batch params
+  if ( !check(batch_params) )
+    throw LauncherException("Batch parameters are bad (see informations above)");
+
+  // find a cluster matching the structure params
+  vector<string> aCompoList ;
+  try{
+    aMachineList = _ResManager->GetFittingResources(params, aCompoList);
+  }
+  catch(const ResourcesException &ex){
+    throw LauncherException(ex.msg.c_str());
+  }
+  if (aMachineList.size() == 0)
+    throw LauncherException("No resources have been found with your parameters");
+
+  ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+  string clustername(p.Alias);
+  cerr << "Choose cluster: " <<  clustername << endl;
+  
+  // search batch manager for that cluster in map or instanciate one
+  map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+  if(it == _batchmap.end())
+    {
+      _batchmap[clustername] = FactoryBatchManager(p);
+      // TODO: Add a test for the cluster !
+    }
+    
+  try{
+    // tmp directory on cluster to put files to execute
+    string tmpdir = getTmpDirForBatchFiles();
+
+    // create and submit job on cluster
+    Batch::Parametre param;
+    param[USER] = p.UserName;
+    param[EXECUTABLE] = buildSalomeCouplingScript(fileToExecute,tmpdir,p);
+    param[INFILE] = Batch::Couple( fileToExecute, getRemoteFile(tmpdir,fileToExecute) );
+    for(int i=0;i<filesToExport.size();i++)
+      param[INFILE] += Batch::Couple( filesToExport[i], getRemoteFile(tmpdir,filesToExport[i]) );
+
+
+    ostringstream file_name_output;
+    file_name_output << "~/" << tmpdir << "/" << "runSalome.output.log*";
+    ostringstream file_name_error;
+    file_name_error << "~/" << tmpdir << "/" << "runSalome.error.log*";
+    ostringstream file_container_log;
+    file_container_log << "~/" << tmpdir << "/" << "YACS_Server*";
+    param[OUTFILE] = Batch::Couple( "", file_name_output.str());
+    param[OUTFILE] += Batch::Couple( "", file_name_error.str());
+    param[OUTFILE] += Batch::Couple( "", file_container_log.str());
+
+    for(int i=0;i<filesToImport.size();i++)
+      param[OUTFILE] += Batch::Couple( "", filesToImport[i] );
+
+    param[NBPROC] = batch_params.nb_proc;
+    param[WORKDIR] = batch_params.batch_directory;
+    param[TMPDIR] = tmpdir;
+    param[MAXWALLTIME] = getWallTime(batch_params.expected_during_time);
+    param[MAXRAMSIZE] = getRamSize(batch_params.mem);
+    param[HOMEDIR] = getHomeDir(p, tmpdir);
+
+    Batch::Environnement env;
+
+    Batch::Job* job = new Batch::Job(param,env);
+
+    // submit job on cluster
+    Batch::JobId jid = _batchmap[clustername]->submitJob(*job);
+
+    // get job id in long
+    istringstream iss(jid.getReference());
+    iss >> jobId;
+
+    _jobmap[ pair<string,long>(clustername,jobId) ] = job;
+  }
+  catch(const Batch::EmulationException &ex){
+    throw LauncherException(ex.msg.c_str());
+  }
+
+  return jobId;
+}
+
+//=============================================================================
+/*! CORBA Method:
+ *  Query a batch job on a cluster and returns the status of job
+ *  \param jobId              : identification of Salome job
+ *  \param params             : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+string Launcher_cpp::querySalomeJob( long id, 
+                                    const machineParams& params) throw(LauncherException)
+{
+  // find a cluster matching params structure
+  vector<string> aCompoList ;
+  vector<string> aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+  ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+  string clustername(p.Alias);
+    
+  // search batch manager for that cluster in map
+  std::map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+  if(it == _batchmap.end())
+    throw LauncherException("no batchmanager for that cluster");
+    
+  ostringstream oss;
+  oss << id;
+  Batch::JobId jobId( _batchmap[clustername], oss.str() );
+
+  Batch::JobInfo jinfo = jobId.queryJob();
+  Batch::Parametre par = jinfo.getParametre();
+  return par[STATE];
+}
+
+//=============================================================================
+/*! CORBA Method:
+ *  Delete a batch job on a cluster 
+ *  \param jobId              : identification of Salome job
+ *  \param params             : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+void Launcher_cpp::deleteSalomeJob( const long id, 
+                                   const machineParams& params) throw(LauncherException)
+{
+  // find a cluster matching params structure
+  vector<string> aCompoList ;
+  vector<string> aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+  ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+  string clustername(p.Alias);
+    
+  // search batch manager for that cluster in map
+  map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+  if(it == _batchmap.end())
+    throw LauncherException("no batchmanager for that cluster");
+  
+  ostringstream oss;
+  oss << id;
+  Batch::JobId jobId( _batchmap[clustername], oss.str() );
+
+  jobId.deleteJob();
+}
+
+//=============================================================================
+/*! CORBA Method:
+ *  Get result files of job on a cluster
+ *  \param jobId              : identification of Salome job
+ *  \param params             : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+void Launcher_cpp::getResultSalomeJob( const string directory,
+                                      const long id, 
+                                      const machineParams& params) throw(LauncherException)
+{
+  vector<string> aCompoList ;
+  vector<string> aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+  ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+  string clustername(p.Alias);
+    
+  // search batch manager for that cluster in map
+  map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+  if(it == _batchmap.end())
+    throw LauncherException("no batchmanager for that cluster");
+    
+  Batch::Job* job = _jobmap[ pair<string,long>(clustername,id) ];
+
+  _batchmap[clustername]->importOutputFiles( *job, directory );
+}
+
+//=============================================================================
+/*!
+ *  Factory to instanciate the good batch manager for choosen cluster.
+ */ 
+//=============================================================================
+
+Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager( const ParserResourcesType& params ) throw(LauncherException)
+{
+
+  std::string hostname, protocol, mpi;
+  Batch::FactBatchManager_eClient* fact;
+
+  hostname = params.Alias;
+  switch(params.Protocol){
+  case rsh:
+    protocol = "rsh";
+    break;
+  case ssh:
+    protocol = "ssh";
+    break;
+  default:
+    throw LauncherException("unknown protocol");
+    break;
+  }
+  switch(params.mpi){
+  case lam:
+    mpi = "lam";
+    break;
+  case mpich1:
+    mpi = "mpich1";
+    break;
+  case mpich2:
+    mpi = "mpich2";
+    break;
+  case openmpi:
+    mpi = "openmpi";
+    break;
+  case slurm:
+    mpi = "slurm";
+    break;
+  default:
+    mpi = "indif";
+    break;
+  }    
+  cerr << "Instanciation of batch manager" << endl;
+  switch( params.Batch ){
+  case pbs:
+    cerr << "Instantiation of PBS batch manager" << endl;
+    fact = new Batch::FactBatchManager_ePBS;
+    break;
+  case lsf:
+    cerr << "Instantiation of LSF batch manager" << endl;
+    fact = new Batch::FactBatchManager_eLSF;
+    break;
+  default:
+    cerr << "BATCH = " << params.Batch << endl;
+    throw LauncherException("no batchmanager for that cluster");
+  }
+  return (*fact)(hostname.c_str(),protocol.c_str(),mpi.c_str());
+}
+
+string Launcher_cpp::buildSalomeCouplingScript(const string fileToExecute, const string dirForTmpFiles, const ParserResourcesType& params)
+{
+  int idx = dirForTmpFiles.find("Batch/");
+  std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+
+  string::size_type p1 = fileToExecute.find_last_of("/");
+  string::size_type p2 = fileToExecute.find_last_of(".");
+  std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+  std::string TmpFileName = "/tmp/runSalome_" + fileNameToExecute + ".sh";
+
+  MpiImpl* mpiImpl = FactoryMpiImpl(params.mpi);
+
+  ofstream tempOutputFile;
+  tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+
+  // Begin
+  tempOutputFile << "#! /bin/sh -f" << endl ;
+  tempOutputFile << "cd " ;
+  tempOutputFile << params.AppliPath << endl ;
+  tempOutputFile << "export SALOME_BATCH=1\n";
+  tempOutputFile << "export PYTHONPATH=~/" ;
+  tempOutputFile << dirForTmpFiles ;
+  tempOutputFile << ":$PYTHONPATH" << endl ;
+
+  // Test node rank
+  tempOutputFile << "if test " ;
+  tempOutputFile << mpiImpl->rank() ;
+  tempOutputFile << " = 0; then" << endl ;
+
+  // -----------------------------------------------
+  // Code for rank 0 : launch runAppli and a container
+  // RunAppli
+  if(params.ModulesList.size()>0)
+    tempOutputFile << "  ./runAppli --terminal --modules=" ;
+  else
+    tempOutputFile << "  ./runAppli --terminal ";
+  for ( int i = 0 ; i < params.ModulesList.size() ; i++ ) {
+    tempOutputFile << params.ModulesList[i] ;
+    if ( i != params.ModulesList.size()-1 )
+      tempOutputFile << "," ;
+  }
+  tempOutputFile << " --standalone=registry,study,moduleCatalog --ns-port-log="
+                << filelogtemp 
+                << " &\n";
+
+  // Wait NamingService
+  tempOutputFile << "  current=0\n"
+                << "  stop=20\n" 
+                << "  while ! test -f " << filelogtemp << "\n"
+                << "  do\n"
+                << "    sleep 2\n"
+                << "    let current=current+1\n"
+                << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
+                << "      echo Error Naming Service failed ! >&2"
+                << "      exit\n"
+                << "    fi\n"
+                << "  done\n"
+                << "  port=`cat " << filelogtemp << "`\n";
+    
+  // Wait other containers
+  tempOutputFile << "  for ((ip=1; ip < ";
+  tempOutputFile << mpiImpl->size();
+  tempOutputFile << " ; ip++))" << endl;
+  tempOutputFile << "  do" << endl ;
+  tempOutputFile << "    arglist=\"$arglist YACS_Server_\"$ip" << endl ;
+  tempOutputFile << "  done" << endl ;
+  tempOutputFile << "  sleep 5" << endl ;
+  tempOutputFile << "  ./runSession waitContainers.py $arglist" << endl ;
+  
+  // Launch user script
+  tempOutputFile << "  ./runSession python ~/" << dirForTmpFiles << "/" << fileNameToExecute << ".py" << endl;
+
+  // Stop application
+  tempOutputFile << "  rm " << filelogtemp << "\n"
+                << "  ./runSession shutdownSalome.py" << endl;
+
+  // -------------------------------------
+  // Other nodes launch a container
+  tempOutputFile << "else" << endl ;
+
+  // Wait NamingService
+  tempOutputFile << "  current=0\n"
+                << "  stop=20\n" 
+                << "  while ! test -f " << filelogtemp << "\n"
+                << "  do\n"
+                << "    sleep 2\n"
+                << "    let current=current+1\n"
+                << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
+                << "      echo Error Naming Service failed ! >&2"
+                << "      exit\n"
+                << "    fi\n"
+                << "  done\n"
+                << "  port=`cat " << filelogtemp << "`\n";
+
+  // Launching container
+  tempOutputFile << "  ./runSession SALOME_Container YACS_Server_";
+  tempOutputFile << mpiImpl->rank()
+                << " > ~/" << dirForTmpFiles << "/YACS_Server_" 
+                << mpiImpl->rank() << "_container_log." << filelogtemp
+                << " 2>&1\n";
+  tempOutputFile << "fi" << endl ;
+  tempOutputFile.flush();
+  tempOutputFile.close();
+  chmod(TmpFileName.c_str(), 0x1ED);
+  cerr << TmpFileName.c_str() << endl;
+
+  delete mpiImpl;
+
+  return TmpFileName;
+    
+}
+
+MpiImpl *Launcher_cpp::FactoryMpiImpl(MpiImplType mpi) throw(LauncherException)
+{
+  switch(mpi){
+  case lam:
+    return new MpiImpl_LAM();
+  case mpich1:
+    return new MpiImpl_MPICH1();
+  case mpich2:
+    return new MpiImpl_MPICH2();
+  case openmpi:
+    return new MpiImpl_OPENMPI();
+  case slurm:
+    return new MpiImpl_SLURM();
+  case indif:
+    throw LauncherException("you must specify a mpi implementation in CatalogResources.xml file");
+  default:
+    ostringstream oss;
+    oss << mpi << " : not yet implemented";
+    throw LauncherException(oss.str().c_str());
+  }
+
+}
+
+string Launcher_cpp::getTmpDirForBatchFiles()
+{
+  string ret;
+  string thedate;
+
+  // Adding date to the directory name
+  Batch::Date date = Batch::Date(time(0));
+  thedate = date.str();
+  int lend = thedate.size() ;
+  int i = 0 ;
+  while ( i < lend ) {
+    if ( thedate[i] == '/' || thedate[i] == '-' || thedate[i] == ':' ) {
+      thedate[i] = '_' ;
+    }
+    i++ ;
+  }
+
+  ret = string("Batch/");
+  ret += thedate;
+  return ret;
+}
+
+string Launcher_cpp::getRemoteFile( std::string remoteDir, std::string localFile )
+{
+  string::size_type pos = localFile.find_last_of("/") + 1;
+  int ln = localFile.length() - pos;
+  string remoteFile = remoteDir + "/" + localFile.substr(pos,ln);
+  return remoteFile;
+}
+
+bool Launcher_cpp::check(const batchParams& batch_params)
+{
+  bool rtn = true;
+  cerr << "Job parameters are :" << endl;
+  cerr << "Directory : $HOME/Batch/$date" << endl;
+
+  // check expected_during_time (check the format)
+  std::string edt_info = batch_params.expected_during_time;
+  std::string edt_value = batch_params.expected_during_time;
+  if (edt_value != "") {
+    std::string begin_edt_value = edt_value.substr(0, 2);
+    std::string mid_edt_value = edt_value.substr(2, 1);
+    std::string end_edt_value = edt_value.substr(3);
+  
+    long value;
+    std::istringstream iss(begin_edt_value);
+    if (!(iss >> value)) {
+      edt_info = "Error on definition ! : " + edt_value;
+      rtn = false;
+    }
+    else if (value < 0) {
+      edt_info = "Error on definition time is negative ! : " + value;
+      rtn = false;
+    }
+    std::istringstream iss_2(end_edt_value);
+    if (!(iss_2 >> value)) {
+      edt_info = "Error on definition ! : " + edt_value;
+      rtn = false;
+    }
+    else if (value < 0) {
+      edt_info = "Error on definition time is negative ! : " + value;
+      rtn = false;
+    }
+    if (mid_edt_value != ":") {
+      edt_info = "Error on definition ! :" + edt_value;
+      rtn = false;
+    }
+  }
+  else {
+    edt_info = "No value given";
+  }
+  cerr << "Expected during time : " << edt_info << endl;;
+
+  // check memory (check the format)
+  std::string mem_info;
+  std::string mem_value = batch_params.mem;
+  if (mem_value != "") {
+    std::string begin_mem_value = mem_value.substr(0, mem_value.length()-2);
+    long re_mem_value;
+    std::istringstream iss(begin_mem_value);
+    if (!(iss >> re_mem_value)) {
+      mem_info = "Error on definition ! : " + mem_value;
+      rtn = false;
+    }
+    else if (re_mem_value <= 0) {
+      mem_info = "Error on definition memory is negative ! : " + mem_value;
+      rtn = false;
+    }
+    std::string end_mem_value = mem_value.substr(mem_value.length()-2);
+    if (end_mem_value != "gb" and end_mem_value != "mb") {
+      mem_info = "Error on definition, type is bad ! " + mem_value;
+      rtn = false;
+    }
+  }
+  else {
+    mem_info = "No value given";
+  }
+  cerr << "Memory : " << mem_info << endl;
+
+  // check nb_proc
+  std::string nb_proc_info;
+  ostringstream nb_proc_value;
+  nb_proc_value << batch_params.nb_proc;
+  if(batch_params.nb_proc <= 0) {
+    nb_proc_info = "Bad value ! nb_proc = ";
+    nb_proc_info += nb_proc_value.str();
+    rtn = false;
+  }
+  else {
+    nb_proc_info = nb_proc_value.str();
+  }
+  cerr << "Nb of processors : " << nb_proc_info << endl;
+
+  return rtn;
+}
+
+long Launcher_cpp::getWallTime(std::string edt)
+{
+  long hh, mm, ret;
+
+  if( edt.size() == 0 )
+    return 0;
+
+  string::size_type pos = edt.find(":");
+  string h = edt.substr(0,pos);
+  string m = edt.substr(pos+1,edt.size()-pos+1);
+  istringstream issh(h);
+  issh >> hh;
+  istringstream issm(m);
+  issm >> mm;
+  ret = hh*60 + mm;
+  return  ret;
+}
+
+long Launcher_cpp::getRamSize(std::string mem)
+{
+  long mv;
+
+  if( mem.size() == 0 )
+    return 0;
+
+  string ram = mem.substr(0,mem.size()-2);
+  istringstream iss(ram);
+  iss >> mv;
+  string unity = mem.substr(mem.size()-2,2);
+  if( (unity.find("gb") != string::npos) || (unity.find("GB") != string::npos) )
+    return mv*1024;
+  else if( (unity.find("mb") != string::npos) || (unity.find("MB") != string::npos) )
+    return mv;
+  else if( (unity.find("kb") != string::npos) || (unity.find("KB") != string::npos) )
+    return mv/1024;
+  else if( (unity.find("b") != string::npos) || (unity.find("B") != string::npos) )
+    return mv/(1024*1024);
+  else
+    return 0;
+}
+
+std::string
+Launcher_cpp::getHomeDir(const ParserResourcesType& p, const std::string& tmpdir)
+{
+    std::string home;
+    std::string command;
+    int idx = tmpdir.find("Batch/");
+    std::string filelogtemp = tmpdir.substr(idx+6, tmpdir.length());
+    filelogtemp = "/tmp/logs" + filelogtemp + "_home";
+
+    if( p.Protocol == rsh )
+      command = "rsh ";
+    else if( p.Protocol == ssh )
+      command = "ssh ";
+    else
+      throw LauncherException("Unknown protocol");
+    if (p.UserName != ""){
+      command += p.UserName;
+      command += "@";
+    }
+    command += p.Alias;
+    command += " 'echo $HOME' > ";
+    command += filelogtemp;
+    std::cerr << command.c_str() << std::endl;
+    int status = system(command.c_str());
+    if(status)
+      throw LauncherException("Error of launching home command on remote host");
+
+    std::ifstream file_home(filelogtemp.c_str());
+    std::getline(file_home, home);
+    file_home.close();
+    return home;
+}
diff --git a/src/Launcher/Launcher.hxx b/src/Launcher/Launcher.hxx
new file mode 100644 (file)
index 0000000..84dd59d
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __LAUNCHER_HXX__
+#define __LAUNCHER_HXX__
+
+#include "Batch_BatchManager_eClient.hxx"
+#include "ResourcesManager.hxx"
+
+#include <string>
+
+struct batchParams{
+  std::string batch_directory;
+  std::string expected_during_time;
+  std::string mem;
+  unsigned long nb_proc;
+};
+
+class LauncherException
+{
+public:
+  const std::string msg;
+
+  LauncherException(const std::string m) : msg(m) {}
+};
+
+class Launcher_cpp
+{
+
+public:
+  Launcher_cpp();
+  ~Launcher_cpp();
+
+  long submitSalomeJob(const std::string fileToExecute ,
+                      const std::vector<std::string>& filesToExport ,
+                      const std::vector<std::string>& filesToImport ,
+                      const batchParams& batch_params,
+                      const machineParams& params) throw(LauncherException);
+
+  std::string querySalomeJob( const long jobId, const machineParams& params) throw(LauncherException);
+  void deleteSalomeJob( const long jobId, const machineParams& params) throw(LauncherException);
+  void getResultSalomeJob( const std::string directory, const long jobId, const machineParams& params ) throw(LauncherException);
+
+  void SetResourcesManager( ResourcesManager_cpp* rm ) { _ResManager = rm; }
+
+protected:
+
+  std::string buildSalomeCouplingScript(const string fileToExecute, const string dirForTmpFiles, const ParserResourcesType& params);
+  MpiImpl *FactoryMpiImpl(MpiImplType mpiImpl) throw(LauncherException);
+  Batch::BatchManager_eClient *FactoryBatchManager( const ParserResourcesType& params ) throw(LauncherException);
+  std::string getTmpDirForBatchFiles();
+  std::string getRemoteFile( std::string remoteDir, std::string localFile );
+  std::string getHomeDir(const ParserResourcesType& p, const std::string & tmpdir);  
+
+  std::map <std::string,Batch::BatchManager_eClient*> _batchmap;
+  std::map < std::pair<std::string,long> , Batch::Job* > _jobmap;
+  ResourcesManager_cpp *_ResManager;
+  bool check(const batchParams& batch_params);
+  long getWallTime(std::string edt);
+  long getRamSize(std::string mem);
+};
+
+#endif
diff --git a/src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx b/src/ParallelContainer/SALOME_ParallelContainerProxy_i.cxx
new file mode 100644 (file)
index 0000000..c88588c
--- /dev/null
@@ -0,0 +1,43 @@
+//  SALOME_ParallelContainerProxy : implementation of container and engine for Parallel Kernel
+//
+//  Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library 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 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//  File   : SALOME_ParallelContainerProxy_i.cxx
+//  Author : André RIBES, EDF
+
+#include "SALOME_ParallelContainerProxy_i.hxx"
+
+Container_proxy_impl_final::Container_proxy_impl_final(CORBA::ORB_ptr orb, 
+                                                      paco_fabrique_thread * fab_thread, 
+                                                      bool is_a_return_proxy) :
+  Engines::Container_proxy_impl(orb, fab_thread, is_a_return_proxy),
+  InterfaceManager_impl(orb, fab_thread, is_a_return_proxy)
+{}
+
+Container_proxy_impl_final:: ~Container_proxy_impl_final() {}
+
+void
+Container_proxy_impl_final::Shutdown()
+{
+  INFOS("Shutdown Parallel Proxy");
+  if(!CORBA::is_nil(_orb))
+    _orb->shutdown(0);
+}
+
diff --git a/src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx b/src/ParallelContainer/SALOME_ParallelContainerProxy_i.hxx
new file mode 100644 (file)
index 0000000..77d5914
--- /dev/null
@@ -0,0 +1,44 @@
+//  SALOME_ParallelContainerProxy : implementation of container and engine for Parallel Kernel
+//
+//  Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library 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 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//  File   : SALOME_ParallelContainerProxy_i.hxx
+//  Author : André RIBES, EDF
+
+#ifndef _SALOME_PARALLEL_CONTAINER_PROXY_I_HXX_
+#define _SALOME_PARALLEL_CONTAINER_PROXY_I_HXX_
+
+#include "utilities.h"
+#include "SALOME_ComponentPaCO_Engines_Container_server.h"
+
+class Container_proxy_impl_final :
+  public Engines::Container_proxy_impl
+{
+  public:
+    Container_proxy_impl_final(CORBA::ORB_ptr orb, 
+                              paco_fabrique_thread * fab_thread, 
+                              bool is_a_return_proxy = false);
+
+    virtual ~Container_proxy_impl_final();
+
+    virtual void Shutdown();
+};
+
+#endif
diff --git a/src/ResourcesManager/ResourcesManager.cxx b/src/ResourcesManager/ResourcesManager.cxx
new file mode 100644 (file)
index 0000000..ddf3712
--- /dev/null
@@ -0,0 +1,488 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "ResourcesManager.hxx" 
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string.h>
+#include <map>
+#include <list>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libxml/parser.h>
+
+#include "utilities.h"
+
+#define MAX_SIZE_FOR_HOSTNAME 256;
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * just for test
+ */ 
+//=============================================================================
+
+ResourcesManager_cpp::
+ResourcesManager_cpp(const char *xmlFilePath) :
+    _path_resources(xmlFilePath)
+{
+  MESSAGE ( "ResourcesManager_cpp constructor" );
+}
+
+//=============================================================================
+/*!
+ *  Standard constructor, parse resource file.
+ *  - if ${APPLI} exists in environment,
+ *    look for ${HOME}/${APPLI}/CatalogResources.xml
+ *  - else look for default:
+ *    ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
+ *  - parse XML resource file.
+ */ 
+//=============================================================================
+
+ResourcesManager_cpp::ResourcesManager_cpp()
+{
+  MESSAGE ( "ResourcesManager_cpp constructor" );
+  _isAppliSalomeDefined = (getenv("APPLI") != 0);
+
+  if (_isAppliSalomeDefined)
+    {
+      _path_resources = getenv("HOME");
+      _path_resources += "/";
+      _path_resources += getenv("APPLI");
+      _path_resources += "/CatalogResources.xml";
+    }
+
+  else
+    {
+      _path_resources = getenv("KERNEL_ROOT_DIR");
+      _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
+    }
+
+  ParseXmlFile();
+  MESSAGE ( "ResourcesManager_cpp constructor end" );
+}
+
+//=============================================================================
+/*!
+ *  Standard Destructor
+ */ 
+//=============================================================================
+
+ResourcesManager_cpp::~ResourcesManager_cpp()
+{
+  MESSAGE ( "ResourcesManager_cpp destructor" );
+}
+
+//=============================================================================
+/*!
+ *  get the list of name of ressources fitting for the specified module.
+ *  If hostname specified, check it is local or known in resources catalog.
+ *
+ *  Else
+ *  - select first machines with corresponding OS (all machines if
+ *    parameter OS empty),
+ *  - then select the sublist of machines on witch the module is known
+ *    (if the result is empty, that probably means that the inventory of
+ *    modules is probably not done, so give complete list from previous step)
+ */ 
+//=============================================================================
+
+std::vector<std::string> 
+ResourcesManager_cpp::GetFittingResources(const machineParams& params,
+                                     const std::vector<std::string>& componentList) throw(ResourcesException)
+{
+//   cerr << "ResourcesManager_cpp::GetFittingResources" << endl;
+  vector <std::string> vec;
+
+  ParseXmlFile();
+
+  const char *hostname = params.hostname.c_str();
+  INFOS ( "GetFittingResources " << hostname << " " << GetHostname().c_str() );
+
+  if (hostname[0] != '\0'){
+    //       cerr << "ResourcesManager_cpp::GetFittingResources : hostname specified" << endl;
+
+    if ( strcmp(hostname, "localhost") == 0 ||
+        strcmp(hostname, GetHostname().c_str()) == 0 )
+      {
+       //           cerr << "ResourcesManager_cpp::GetFittingResources : localhost" << endl;
+       vec.push_back(GetHostname().c_str());
+       //        cerr << "ResourcesManager_cpp::GetFittingResources : " << vec.size() << endl;
+      }
+       
+    else if (_resourcesList.find(hostname) != _resourcesList.end())
+      {
+       // --- params.hostname is in the list of resources so return it.
+       vec.push_back(hostname);
+      }
+    else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end())
+    {
+      // --- params.hostname is in the list of resources so return it.
+      vec.push_back(hostname);
+    }
+    else
+      {
+       // Cas d'un cluster: nombre de noeuds > 1
+       int cpt=0;
+       for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
+         if( (*iter).second.DataForSort._nbOfNodes > 1 ){
+           if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
+             vec.push_back((*iter).first.c_str());
+             //cerr << "SALOME_ResourcesManager_cpp::GetFittingResources vector["
+             //     << cpt << "] = " << (*iter).first.c_str() << endl ;
+             cpt++;
+           }
+         }
+       }
+       if(cpt==0){
+         // --- user specified an unknown hostame so notify him.
+         MESSAGE ( "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" );
+         throw ResourcesException("unknown host");
+       }
+      }
+  }
+    
+  else{
+    // --- Search for available resources sorted by priority
+    SelectOnlyResourcesWithOS(vec, params.OS.c_str());
+      
+    KeepOnlyResourcesWithModule(vec, componentList);
+       
+    if (vec.size() == 0)
+      SelectOnlyResourcesWithOS(vec, params.OS.c_str());
+    
+    // --- set wanted parameters
+    ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
+      
+    ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
+       
+    ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
+       
+    ResourceDataToSort::_memInMBWanted = params.mem_mb;
+       
+    // --- end of set
+       
+    list<ResourceDataToSort> li;
+       
+    for (vector<string>::iterator iter = vec.begin();
+        iter != vec.end();
+        iter++)
+      li.push_back(_resourcesList[(*iter)].DataForSort);
+       
+    li.sort();
+       
+    unsigned int i = 0;
+       
+    for (list<ResourceDataToSort>::iterator iter2 = li.begin();
+        iter2 != li.end();
+        iter2++)
+      vec[i++] = (*iter2)._hostName;
+  }
+    
+  return vec;
+
+}
+
+//=============================================================================
+/*!
+ *  add an entry in the ressources catalog  xml file.
+ *  Return 0 if OK (KERNEL found in new resources modules) else throw exception
+ */ 
+//=============================================================================
+
+int
+ResourcesManager_cpp::
+AddResourceInCatalog(const machineParams& paramsOfNewResources,
+                     const vector<string>& modulesOnNewResources,
+                     const char *alias,
+                     const char *userName,
+                     AccessModeType mode,
+                     AccessProtocolType prot)
+throw(ResourcesException)
+{
+  vector<string>::const_iterator iter = find(modulesOnNewResources.begin(),
+                                            modulesOnNewResources.end(),
+                                            "KERNEL");
+
+  if (iter != modulesOnNewResources.end())
+    {
+      ParserResourcesType newElt;
+      newElt.DataForSort._hostName = paramsOfNewResources.hostname;
+      newElt.Alias = alias;
+      newElt.Protocol = prot;
+      newElt.Mode = mode;
+      newElt.UserName = userName;
+      newElt.ModulesList = modulesOnNewResources;
+      newElt.OS = paramsOfNewResources.OS;
+      newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
+      newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
+      newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
+      newElt.DataForSort._nbOfProcPerNode =
+        paramsOfNewResources.nb_proc_per_node;
+      _resourcesList[newElt.DataForSort._hostName] = newElt;
+      return 0;
+    }
+
+  else
+    throw ResourcesException("KERNEL is not present in this resource");
+}
+
+//=============================================================================
+/*!
+ *  Deletes a resource from the catalog
+ */ 
+//=============================================================================
+
+void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
+{
+  _resourcesList.erase(hostname);
+}
+
+//=============================================================================
+/*!
+ *  write the current data in memory in file.
+ */ 
+//=============================================================================
+
+void ResourcesManager_cpp::WriteInXmlFile()
+{
+  const char* aFilePath = _path_resources.c_str();
+  
+  FILE* aFile = fopen(aFilePath, "w");
+
+  if (aFile == NULL)
+    {
+      INFOS ( "Error opening file !" );
+      return;
+    }
+  
+  xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
+  xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
+
+  SALOME_ResourcesCatalog_Handler* handler =
+    new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
+  handler->PrepareDocToXmlFile(aDoc);
+  delete handler;
+
+  int isOk = xmlSaveFile(aFilePath, aDoc);
+  
+  if (!isOk)
+    INFOS ( "Error while XML file saving." );
+  
+  // Free the document
+  xmlFreeDoc(aDoc);
+
+  fclose(aFile);
+  
+  INFOS ( "WRITING DONE!" );
+}
+
+//=============================================================================
+/*!
+ *  parse the data type catalog
+ */ 
+//=============================================================================
+
+const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
+{
+  SALOME_ResourcesCatalog_Handler* handler =
+    new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
+
+  const char* aFilePath = _path_resources.c_str();
+  FILE* aFile = fopen(aFilePath, "r");
+  
+  if (aFile != NULL)
+    {
+      xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
+      
+      if (aDoc != NULL)
+       handler->ProcessXmlDocument(aDoc);
+      else
+       INFOS ( "ResourcesManager_cpp: could not parse file "<< aFilePath );
+      
+      // Free the document
+      xmlFreeDoc(aDoc);
+
+      fclose(aFile);
+    }
+  else
+    INFOS ( "ResourcesManager_cpp: file "<<aFilePath<<" is not readable." );
+  
+  delete handler;
+
+  return _resourcesList;
+}
+
+//=============================================================================
+/*!
+ *   consult the content of the list
+ */ 
+//=============================================================================
+
+const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
+  {
+    return _resourcesList;
+  }
+
+
+//=============================================================================
+/*!
+ *  dynamically obtains the first machines
+ */ 
+//=============================================================================
+
+string ResourcesManager_cpp::FindFirst(const std::vector<std::string>& listOfMachines)
+{
+  return _dynamicResourcesSelecter.FindFirst(listOfMachines);
+}
+
+//=============================================================================
+/*!
+ *  dynamically obtains the best machines
+ */ 
+//=============================================================================
+
+string ResourcesManager_cpp::FindNext(const std::vector<std::string>& listOfMachines)
+{
+  return _dynamicResourcesSelecter.FindNext(listOfMachines,_resourcesList);
+}
+//=============================================================================
+/*!
+ *  dynamically obtains the best machines
+ */ 
+//=============================================================================
+
+string ResourcesManager_cpp::FindBest(const std::vector<std::string>& listOfMachines)
+{
+  return _dynamicResourcesSelecter.FindBest(listOfMachines);
+}
+
+//=============================================================================
+/*!
+ *  Gives a sublist of machines with matching OS.
+ *  If parameter OS is empty, gives the complete list of machines
+ */ 
+//=============================================================================
+
+// Warning need an updated parsed list : _resourcesList
+void ResourcesManager_cpp::SelectOnlyResourcesWithOS( vector<string>& hosts,  const char *OS) const
+throw(ResourcesException)
+{
+  string base(OS);
+
+  for (map<string, ParserResourcesType>::const_iterator iter =
+         _resourcesList.begin();
+       iter != _resourcesList.end();
+       iter++)
+    {
+      if ( (*iter).second.OS == base || base.size() == 0)
+        hosts.push_back((*iter).first);
+    }
+}
+
+
+//=============================================================================
+/*!
+ *  Gives a sublist of machines on which the module is known.
+ */ 
+//=============================================================================
+
+//Warning need an updated parsed list : _resourcesList
+void ResourcesManager_cpp::KeepOnlyResourcesWithModule( vector<string>& hosts, const vector<string>& componentList) const
+throw(ResourcesException)
+{
+  for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
+    {
+      MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
+      const vector<string>& mapOfModulesOfCurrentHost = (((*it).second).ModulesList);
+
+      bool erasedHost = false;
+      if( mapOfModulesOfCurrentHost.size() > 0 ){
+       for(int i=0;i<componentList.size();i++){
+          const char* compoi = componentList[i].c_str();
+         vector<string>::const_iterator itt = find(mapOfModulesOfCurrentHost.begin(),
+                                             mapOfModulesOfCurrentHost.end(),
+                                             compoi);
+//                                           componentList[i]);
+         if (itt == mapOfModulesOfCurrentHost.end()){
+           erasedHost = true;
+           break;
+         }
+       }
+      }
+      if(erasedHost)
+        hosts.erase(iter);
+      else
+        iter++;
+    }
+}
+
+
+ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine)
+{
+  if (_resourcesList.find(machine) != _resourcesList.end())
+    return _resourcesList[machine];
+  else
+    return _resourcesBatchList[machine];
+}
+
+std::string ResourcesManager_cpp::GetHostname()
+{
+  int ls = 100, r = 1;
+  char *s;
+
+  while (ls < 10000 && r) {
+    ls *= 2;
+    s = new char[ls];
+    r = gethostname(s, ls-1);
+    switch (r) 
+      {
+      case 0:
+         break;
+      default:
+#ifdef EINVAL
+      case EINVAL:
+#endif
+#ifdef ENAMETOOLONG
+      case ENAMETOOLONG:
+#endif
+        delete [] s;
+       continue;
+      }
+  }
+
+  if (r != 0) {
+    s = new char[50];
+    strcpy(s, "localhost");
+  }
+
+  // remove all after '.'
+  char *aDot = (strchr(s,'.'));
+  if (aDot) aDot[0] = '\0';
+
+  string p = s;
+  delete [] s;
+  return p;
+}
+
diff --git a/src/ResourcesManager/ResourcesManager.hxx b/src/ResourcesManager/ResourcesManager.hxx
new file mode 100644 (file)
index 0000000..951aba5
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library 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 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __RESOURCESMANAGER_HXX__
+#define __RESOURCESMANAGER_HXX__
+
+#include <string>
+#include <fstream>
+#include <vector>
+#include "SALOME_ResourcesCatalog_Parser.hxx"
+#include "SALOME_ResourcesCatalog_Handler.hxx"
+#include "SALOME_LoadRateManager.hxx"
+
+// --- WARNING ---
+// The call of BuildTempFileToLaunchRemoteContainer and RmTmpFile must be done
+// in a critical section to be sure to be clean.
+// Only one thread should use the SALOME_ResourcesManager class in a SALOME
+// session.
+
+struct machineParams{
+  std::string hostname;
+  std::string OS;
+  unsigned int nb_node;
+  unsigned int nb_proc_per_node;
+  unsigned int cpu_clock;
+  unsigned int mem_mb;
+};
+
+class ResourcesException
+{
+public:
+  const std::string msg;
+
+  ResourcesException(const std::string m) : msg(m) {}
+};
+
+class ResourcesManager_cpp
+  {
+
+  public:
+
+    ResourcesManager_cpp(const char *xmlFilePath);
+    ResourcesManager_cpp();
+
+    ~ResourcesManager_cpp();
+
+    std::vector<std::string> 
+    GetFittingResources(const machineParams& params,
+                        const std::vector<std::string>& componentList) throw(ResourcesException);
+
+    std::string FindFirst(const std::vector<std::string>& listOfMachines);
+    std::string FindNext(const std::vector<std::string>& listOfMachines);
+    std::string FindBest(const std::vector<std::string>& listOfMachines);
+
+    int AddResourceInCatalog
+    (const machineParams& paramsOfNewResources,
+     const std::vector<std::string>& modulesOnNewResources,
+     const char *alias,
+     const char *userName,
+     AccessModeType mode,
+     AccessProtocolType prot) throw(ResourcesException);
+
+    void DeleteResourceInCatalog(const char *hostname);
+
+    void WriteInXmlFile();
+
+    const MapOfParserResourcesType& ParseXmlFile();
+
+    const MapOfParserResourcesType& GetList() const;
+
+    ParserResourcesType GetResourcesList(const std::string& machine);
+
+  protected:
+    
+    void SelectOnlyResourcesWithOS(std::vector<std::string>& hosts,
+                                  const char *OS) const
+      throw(ResourcesException);
+
+    void KeepOnlyResourcesWithModule(std::vector<std::string>& hosts,
+                                    const std::vector<std::string>& componentList) const
+      throw(ResourcesException);
+
+    //! will contain the path to the ressources catalog
+    std::string _path_resources;
+
+    //! will contain the informations on the data type catalog(after parsing)
+    MapOfParserResourcesType _resourcesList;
+
+    //! will contain the informations on the data type catalog(after parsing)
+    MapOfParserResourcesType _resourcesBatchList;
+
+    SALOME_LoadRateManager _dynamicResourcesSelecter;
+
+    //! different behaviour if $APPLI exists (SALOME Application) 
+    bool _isAppliSalomeDefined;
+
+    std::string GetHostname();
+  };
+
+#endif // __RESOURCESMANAGER_HXX__