rendered paste body/****************************************************************************
Copyright 2004, Virginia Polytechnic Institute and State University
This file is part of the OSSIE Core Framework.
OSSIE Core Framework is free software; you can redistribute it and/or modify
it under the terms of the Lesser GNU General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
OSSIE Core Framework 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
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with OSSIE Core Framework; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
****************************************************************************/
#include <iostream>
#ifdef MS_dotNET
#include <process.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "ossie/ApplicationFactory_impl.h"
using namespace std;
ApplicationFactory_impl::ComponentInfo::ComponentInfo ()
{
implId = NULL;
localFileName = NULL;
entryPoint = NULL;
name = NULL;
}
ApplicationFactory_impl::ComponentInfo::
ComponentInfo ( const ComponentInfo & ComponentInfoCopy )
{
// populate object with the component information
this->name = new char[ strlen ( ComponentInfoCopy.name ) + 1 ];
strcpy ( this->name, ComponentInfoCopy.name );
this->implId = new char[ strlen ( ComponentInfoCopy.implId ) + 1 ];
strcpy ( this->implId, ComponentInfoCopy.implId );
this->codeType = ComponentInfoCopy.codeType;
this->localFileName =
new char[ strlen ( ComponentInfoCopy.localFileName ) + 1 ];
strcpy ( this->localFileName, ComponentInfoCopy.localFileName );
this->entryPoint = new char[ strlen ( ComponentInfoCopy.entryPoint ) + 1 ];
strcpy ( this->entryPoint, ComponentInfoCopy.entryPoint );
for ( unsigned int i = 0; i < ComponentInfoCopy.usesDevices->size (); i++ )
this->usesDevices->push_back ( ( *ComponentInfoCopy.usesDevices ) [ i ] );
this->allocationCapacities = ComponentInfoCopy.allocationCapacities;
this->execParameters = ComponentInfoCopy.execParameters;
this->factoryParameters = ComponentInfoCopy.factoryParameters;
this->configureProperties = ComponentInfoCopy.configureProperties;
this->options = ComponentInfoCopy.options;
}
ApplicationFactory_impl::ApplicationFactory_impl ( const char *_softProfile )
{
// population application factory with the appropriate information
this->_softwareProfile = new char[ strlen ( _softProfile ) + 1 ];
strcpy ( this->_softwareProfile, _softProfile );
this->_sadParser = new SADParser ( _softwareProfile );
this->_name = new char[ strlen ( _sadParser->getName () ) + 1 ];
strcpy ( this->_name, _sadParser->getName () );
this->_identifier = new char[ strlen ( _sadParser->getID () ) + 1 ];
strcpy ( this->_identifier, _sadParser->getID () );
//Get reference to DomainManager (to register w/event channel)
CORBAOBJ obj = _orb.lookup ( "/DomainName1/DomainManager" );
dmnMgr = CF::DomainManager::_narrow ( obj );
ApplicationFactoryEventHandler *_evtHandler =
new ApplicationFactoryEventHandler ( this );
dmnMgr->registerWithEventChannel ( _evtHandler->_this (),
CORBA::string_dup ( _identifier ),
CORBA::string_dup ( "ODM_Channel" ) );
};
CF::Application_ptr ApplicationFactory_impl::create ( const char *name,
const CF::Properties & initConfiguration,
const CF::DeviceAssignmentSequence & deviceAssignments )
throw ( CORBA::SystemException, CF::ApplicationFactory::CreateApplicationError,
CF::ApplicationFactory::CreateApplicationRequestError,
CF::ApplicationFactory::InvalidInitConfiguration )
{
cout << "entering appFactory->create" << endl;
std::vector <SADComponentPlacement*>* ComponentsVector = _sadParser->getComponents();
//Get SPD file names from SAD:
//Makes list of SPD files.
std::vector <char*> SPDList;
{ // this is here because Microsoft does not believe in following standards
for ( unsigned int i = 0; i < ComponentsVector->size(); i++ ) {
SPDList.push_back( ( *ComponentsVector ) [ i ] ->getSPDFile() );
}
}
// initialize DeviceLoadInfoVector
while ( DeviceLoadInfoVector.size() != 0 ) {
DeviceLoadInfoVector.pop_back();
}
verifyDeviceAssignments( SPDList, deviceAssignments );
// allocate space for device assignment
// (assume maximum length of 10 - will make dynamic in later version)
CF::DeviceAssignmentSequence* _availableDevs =
new CF::DeviceAssignmentSequence( deviceAssignments );
//_availableDevs->length (0);
PROC_ID_SEQ* _pidSeq = new PROC_ID_SEQ ( 30 );
_pidSeq->length ( 0 );
//get a sequence of registeredDeviceManagers
CF::DomainManager::DeviceManagerSequence * devMgrs;
devMgrs = dmnMgr->deviceManagers ();
bool requestedDeviceFound = false;
CF::DeviceSequence * rgstdDevices;
for ( unsigned int componentIndex = 0;
componentIndex < DeviceLoadInfoVector.size ();
componentIndex++ ) {
//get the intended assignedDeviceId from deviceAssignments
int assignmentIndex = 0;
while ( strcmp( DeviceLoadInfoVector[ componentIndex ] ->name,
deviceAssignments[ assignmentIndex ].componentId ) != 0 ) {
assignmentIndex++;
}
//search in all deviceManagers for intended device
for ( unsigned int devMgrIndex = 0;
devMgrIndex < devMgrs->length ();
devMgrIndex++ ) {
//get all devices registered in this device Manager
rgstdDevices = ( *devMgrs ) [ devMgrIndex ] ->registeredDevices ();
for ( unsigned int deviceIndex = 0;
deviceIndex < rgstdDevices->length (); deviceIndex++ ) {
//find a match for the intended device
if ( strcmp( ( *rgstdDevices ) [ deviceIndex ] ->label (),
deviceAssignments[ assignmentIndex ].assignedDeviceId ) == 0 ) {
requestedDeviceFound = true;
cout << "the host is " << ( *rgstdDevices ) [ deviceIndex ] ->label () << endl;
//printf("the host is: %s\n", (*rgstdDevices)[deviceIndex]->label ());
//now we have a pointer to the required device
//Get allocation properties
//allocate
( *rgstdDevices ) [ deviceIndex ] ->
allocateCapacity ( DeviceLoadInfoVector[ componentIndex ] ->
allocationCapacities );
//Get file name
//load if it is not empty
if ( strcmp ( DeviceLoadInfoVector[ componentIndex ] ->localFileName, "" ) != 0 ) {
//load it
//TODO: Validate that the intended device supports the
// LoadableDevice interface
cout << "loading " << DeviceLoadInfoVector[ componentIndex ] ->localFileName << endl;
//printf("loading -> %s\n",DeviceLoadInfoVector[componentIndex]->localFileName);
CF::LoadableDevice_var loadDev =
CF::LoadableDevice::_narrow ( ( *rgstdDevices ) [ deviceIndex ] );
loadDev->load ( ( *devMgrs ) [ devMgrIndex ] ->fileSys (),
DeviceLoadInfoVector[ componentIndex ] ->localFileName,
DeviceLoadInfoVector[ componentIndex ] ->codeType );
//execute when necesary
// if(DeviceLoadInfoVector[componentIndex]->codeType == CF::LoadableDevice::LoadType::EXECUTABLE ||
if ( DeviceLoadInfoVector[ componentIndex ] ->codeType ==
CF::LoadableDevice::EXECUTABLE
|| DeviceLoadInfoVector[ componentIndex ] ->codeType ==
CF::LoadableDevice::SHARED_LIBRARY
&& strcmp ( DeviceLoadInfoVector[ componentIndex ] ->
entryPoint, "" ) != 0 ) {
//execute
//TODO: Validate that the intended device supports
// the LoadableDevice interface
cout << "executing-> " << DeviceLoadInfoVector[ componentIndex ] ->localFileName << endl;
//printf("executing-> %s\n",DeviceLoadInfoVector[componentIndex]->localFileName);
CF::ExecutableDevice_var execDev =
CF::ExecutableDevice::
_narrow ( ( *rgstdDevices ) [ deviceIndex ] );
CF::ExecutableDevice:: ProcessID_Type tempPid = execDev->
execute ( DeviceLoadInfoVector[ componentIndex ] ->
localFileName,
DeviceLoadInfoVector[ componentIndex ] ->options,
DeviceLoadInfoVector[ componentIndex ] ->
execParameters );
if ( tempPid < 0 ) {
//throw exception here
} else {
_pidSeq->length ( _pidSeq->length() + 1 );
( * _pidSeq ) [ _pidSeq->length() - 1 ].processId = tempPid;
( * _pidSeq ) [ _pidSeq->length() - 1 ].componentId =
strdup( deviceAssignments[ assignmentIndex ].componentId );
}
//execDev->execute( LoadInfoVector[componentIndex]->entryPoint, LoadInfoVector[componentIndex]->options, LoadInfoVector[componentIndex]->parameters );
//NOTE: The PID returned by execute is not handled
//An exception shall be thrown when PID = -1
}
}
}
}
}
}
CF::Resource_ptr _assemblyController;
ELEM_SEQ* _namingCtxSeq = new ELEM_SEQ ();
_namingCtxSeq->length ( ComponentsVector->size () );
ELEM_SEQ* _implSeq = new ELEM_SEQ ();
_implSeq->length ( ComponentsVector->size () );
std::vector <CF::Resource_ptr>_resourceVector;
SADComponentInstantiation* _assemblyControllerProfile =
_sadParser->getAssemblyController ();
int vector_access = 0;
{ // this is here because Microsoft does not believe in following standards
// install the different components in the system
for ( unsigned int i = 0; i < ComponentsVector->size (); i++ ) {
std::vector <SADComponentInstantiation*>* ComponentInstantiationVector =
( *ComponentsVector ) [ i ] ->getSADInstantiations ();
// dbl chk for mem leaks
SPDParser _spdParser ( SPDList[ i ] );
// dbl chk for mem leaks, also
SCDParser _scdParser ( _spdParser.getSCDFile () );
if ( !_scdParser.isResource () ) {
// this makes sure that the resource factory
// is not handled like a resource
continue;
}
( *_namingCtxSeq ) [ i ].componentId =
CORBA::string_dup ( ( *ComponentInstantiationVector ) [ 0 ] ->getID () );
( *_implSeq ) [ i ].componentId =
CORBA::string_dup ( ( *ComponentInstantiationVector ) [ 0 ] ->getID () );
// assuming 1 instantiation for each componentplacement
if ( ( *ComponentInstantiationVector ) [ 0 ] ->isNamingService () ) {
// this is for the naming-service based configuration
// it assumes that the component already exists (like a device)
char * _lookupName = ( *ComponentInstantiationVector ) [ 0 ] ->
getFindByNamingServiceName ();
( *_namingCtxSeq ) [ i ].elementId = CORBA::string_dup ( _lookupName );
CORBAOBJ _obj;
do {
#ifdef HAVE_UNISTD_H
// todo Must be a better way
sleep( 1 );
#else
Sleep( 1000 );
#endif
_obj = _orb.lookup ( _lookupName );
}
/*
* What does this do? -TT
*/
while ( CORBA::is_nil ( _obj ) );
// check to see if the resource is the assembly controller
// either way, the resource is initialized and configured
if ( _assemblyControllerProfile == ( *ComponentInstantiationVector ) [ 0 ] ) {
_assemblyController = CF::Resource::_narrow ( _obj );
_assemblyController->initialize ();
_assemblyController->configure ( initConfiguration );
_assemblyController->configure ( DeviceLoadInfoVector[ i ] ->
configureProperties );
} else {
if ( _scdParser.isResource () && _scdParser.isConfigurable () ) {
CF::Resource_ptr _rsc = CF::Resource::_narrow ( _obj );
_rsc->initialize ();
_rsc->configure ( DeviceLoadInfoVector[ i ] ->configureProperties );
_resourceVector.push_back ( CF::Resource::_duplicate ( _rsc ) );
}
}
} else if ( ( *ComponentInstantiationVector ) [ 0 ] ->isResourceFactoryRef () ) {
// resource-factory based component instantiation
SADComponentInstantiation * _resourceFacInstantiation = NULL;
int tmpCnt = 0;
// figure out which resource factory is used
while ( _resourceFacInstantiation == NULL ) {
_resourceFacInstantiation =
( *ComponentsVector ) [ tmpCnt ] ->
getSADInstantiationById ( ( *ComponentInstantiationVector )
[ 0 ] ->getResourceFactoryRefId () );
tmpCnt++;
}
( *_namingCtxSeq ) [ i ].elementId =
CORBA::string_dup ( _resourceFacInstantiation->
getFindByNamingServiceName () );
CORBAOBJ _obj =
_orb.lookup ( _resourceFacInstantiation->
getFindByNamingServiceName () );
CF::ResourceFactory_ptr _resourceFactory =
CF::ResourceFactory::_narrow ( _obj );
// configure factory
/*std::vector < InstantiationProperty * >*_factoryInstantiationProps
= (*ComponentInstantiationVector)[0]->getFactoryProperties ();
CF::Properties _factoryProperties (_factoryInstantiationProps->
size ());
for (unsigned int j = 0; j < _factoryInstantiationProps->size ();
j++)
{
_factoryProperties[j].id
=
CORBA::string_dup ((*_factoryInstantiationProps)[j]->
getID ());
_factoryProperties[j].
value <<= CORBA::
string_dup ((*_factoryInstantiationProps)[j]->getValue ());
}*/
// unused PJB char *value = LoadInfoVector[vector_access]->name;
// instantiate resource
// (mechanism for this is left up to the factory's implementation)
CF::Resource_ptr _resourceCreated =
_resourceFactory->
createResource ( LoadInfoVector[ vector_access ] ->name,
LoadInfoVector[ vector_access ] ->factoryParameters );
if ( CORBA::is_nil ( _resourceCreated ) )
throw CF::ApplicationFactory::CreateApplicationError ();
// check to see if the resource is the assembly controller
// either way, the resource is initialized and configured
if ( strcmp ( _assemblyControllerProfile->getID (),
( *ComponentInstantiationVector ) [ 0 ] ->getID () ) == 0 ) {
_assemblyController = _resourceCreated;
_assemblyController->initialize ();
_assemblyController->configure ( initConfiguration );
_assemblyController->
configure ( LoadInfoVector[ vector_access ] ->configureProperties );
} else {
_resourceCreated->initialize ();
_resourceCreated->
configure ( LoadInfoVector[ vector_access ] ->configureProperties );
_resourceVector.push_back ( _resourceCreated );
}
vector_access++;
} else {
char* _id, *_usagename;
_id = LoadInfoVector[ i ] ->implId;
_usagename = LoadInfoVector[ i ] ->name;
char* _lookup = new char[ strlen ( _usagename ) + strlen ( _id ) + 1 ];
strcpy ( _lookup, _usagename );
strcat ( _lookup, "_" );
strcat ( _lookup, _id );
( *_namingCtxSeq ) [ i ].elementId = CORBA::string_dup ( _lookup );
CORBAOBJ _obj = _orb.lookup ( _lookup );
if ( _assemblyControllerProfile == ( *ComponentInstantiationVector ) [ 0 ] ) {
_assemblyController = CF::Resource::_narrow ( _obj );
_assemblyController->initialize ();
_assemblyController->configure ( initConfiguration );
_assemblyController->configure ( LoadInfoVector[ i ] ->
configureProperties );
} else {
CF::Resource_ptr _rsc = CF::Resource::_narrow ( _obj );
_rsc->initialize ();
_rsc->configure ( LoadInfoVector[ i ] ->configureProperties );
_resourceVector.push_back ( _rsc );
}
delete _lookup;
_lookup = NULL;
}
} // end for()
}
std::vector < Connection * >*_connection = _sadParser->getConnections ();
// create all resource connections
for ( int _numConnections = _connection->size () - 1;
_numConnections >= 0;
_numConnections-- ) {
UsesPort* _usesPortParser = ( *_connection ) [ _numConnections ] ->getUsesPort ();
FindBy* _findUsesPortBy = _usesPortParser->getFindBy ();
ProvidesPort* _providesPortParser = NULL;
FindBy* _findProvidesPortBy = NULL;
if ( ( *_connection ) [ _numConnections ] ->isProvidesPort () )
_providesPortParser =
( *_connection ) [ _numConnections ] ->getProvidesPort ();
else if ( ( *_connection ) [ _numConnections ] ->isFindBy () )
_findProvidesPortBy = ( *_connection ) [ _numConnections ] ->getFindBy ();
else {
//throw an exception?
}
CORBAOBJ _usesObj;
CORBAOBJ _providesObj;
if ( _providesPortParser != NULL ) {
_findProvidesPortBy = _providesPortParser->getFindBy ();
}
if ( _findUsesPortBy->isFindByNamingService () ) {
while ( CORBA::is_nil ( _usesObj ) )
_usesObj = _orb.lookup ( _findUsesPortBy->getFindByNamingServiceName () );
}
if ( _findProvidesPortBy->isFindByNamingService () ) {
while ( CORBA::is_nil ( _providesObj ) )
_providesObj = _orb.lookup ( _findProvidesPortBy->
getFindByNamingServiceName () );
}
CF::PortSupplier_ptr _usesPort = CF::PortSupplier::_narrow ( _usesObj );
CF::Port_ptr _port = CF::Port::_narrow ( _usesPort->getPort ( _usesPortParser->getID () ) );
_port->connectPort ( _providesObj,
CORBA::string_dup ( ( *_connection ) [ _numConnections ] ->getID () ) );
}
// We are assuming that all components and their resources are collocated.
// This means that we assume the SAD <partitioning> element contains the
// <hostcollocation> element.
Application_impl* _application = new Application_impl ( _identifier,
name,
_softwareProfile,
_availableDevs, // need to provide support for device searching
_implSeq,
_namingCtxSeq,
_pidSeq, // need to provide support for PID SEQ
CF::Resource::_duplicate ( _assemblyController ) );
///\todo Figure out what this commented out code is supposed to do
// StandardEvent::DomainManagementObjectAddedEventType _objAddedEvent;
//_objAddedEvent.producerId = CORBA::string_dup (_identifier);
//_objAddedEvent.sourceId = CORBA::string_dup (_application->identifier ());
//_objAddedEvent.sourceName = CORBA::string_dup (_application->name ());
//_objAddedEvent.sourceIOR = _application->_this ();
//_objAddedEvent.sourceCategory = StandardEvent::APPLICATION;
//CORBA::Any _anyObjAddedEvent;
//_anyObjAddedEvent <<= _objAddedEvent;
// sendEventToOutgoingChannel( _anyObjAddedEvent );
// _assemblyController=CF::Resource::_nil();
return CF::Application::_duplicate ( _application->_this () );
}
; /* END ApplicationFactory_impl::create() */
/*Creates a vector of components and their pertinent info listed
in the order they must be loaded and executed (deepest dependancies first).
Need to add getImplementations() for allocation loop???*/
void
ApplicationFactory_impl::ComponentDependencies ( SPDParser * SPDFile,
bool assignmentMatch )
{
// unused PJB int TBD_Length = 2; //Need to figure out how to find number of dependancy files.
vector <SPDImplementation*>* SPDImpl = SPDFile->getImplementations ();
// unused PJB char** DependantFiles = (*SPDImpl)[0]->getSoftwareDependencies(); //Assuming only one implementation.
//Open property file and get properties:
char *PRFFileName = SPDFile->getPRFFile ();
PRFParser PRFFile ( PRFFileName );
PRFProperty *prfSimpleProp = PRFFile.getFactoryParamProperties ();
ComponentInfo *CurrentComponentInfo = new ComponentInfo;
CurrentComponentInfo->factoryParameters.length ( prfSimpleProp->size () );
{ // this is here because Microsoft does not believe in following standards
for ( unsigned int i = 0; i < prfSimpleProp->size (); i++ ) {
CF::DataType * dt = ( *prfSimpleProp ) [ i ] ->getDataType ();
CurrentComponentInfo->factoryParameters[ i ].id = CORBA::string_dup ( dt->id );
CurrentComponentInfo->factoryParameters[ i ].value = dt->value;
}
}
prfSimpleProp = PRFFile.getExecParamProperties ();
CurrentComponentInfo->execParameters.length ( prfSimpleProp->size () );
{ // this is here because Microsoft does not believe in following standards
for ( unsigned int i = 0; i < prfSimpleProp->size (); i++ ) {
CF::DataType * dt = ( *prfSimpleProp ) [ i ] ->getDataType ();
CurrentComponentInfo->execParameters[ i ].id = CORBA::string_dup ( dt->id );
CurrentComponentInfo->execParameters[ i ].value = dt->value;
}
}
prfSimpleProp = PRFFile.getMatchingProperties ();
CurrentComponentInfo->allocationCapacities.length ( prfSimpleProp->size () );
{ // this is here because Microsoft does not believe in following standards
for ( unsigned int i = 0; i < prfSimpleProp->size (); i++ ) {
CF::DataType * dt = ( *prfSimpleProp ) [ i ] ->getDataType ();
CurrentComponentInfo->allocationCapacities[ i ].id = CORBA::string_dup ( dt->id );
CurrentComponentInfo->allocationCapacities[ i ].value = dt->value;
}
}
prfSimpleProp = PRFFile.getConfigureProperties ();
CurrentComponentInfo->configureProperties.length ( prfSimpleProp->size () );
{ // this is here because Microsoft does not believe in following standards
for ( unsigned int i = 0; i < prfSimpleProp->size (); i++ ) {
CF::DataType * dt = ( *prfSimpleProp ) [ i ] ->getDataType ();
CurrentComponentInfo->configureProperties[ i ].id = CORBA::string_dup ( dt->id );
CurrentComponentInfo->configureProperties[ i ].value = dt->value;
}
}
CurrentComponentInfo->implId = ( *SPDImpl ) [ 0 ] ->getID ();
CurrentComponentInfo->localFileName = ( *SPDImpl ) [ 0 ] ->getCodeFile ();
CurrentComponentInfo->codeType = ( *SPDImpl ) [ 0 ] ->getCodeType ();
CurrentComponentInfo->entryPoint = ( *SPDImpl ) [ 0 ] ->getEntryPoint ();
CurrentComponentInfo->usesDevices = ( *SPDImpl ) [ 0 ] ->getUsesDevices ();
CurrentComponentInfo->name = SPDFile->getSoftPkgName ();
if ( assignmentMatch )
DeviceLoadInfoVector.push_back ( CurrentComponentInfo );
else
LoadInfoVector.push_back ( CurrentComponentInfo );
}
void
/*char* _spdFileName, */
ApplicationFactory_impl::verifyDeviceAssignments ( std::vector < char *>&SPDList,
const CF::
DeviceAssignmentSequence &
_deviceAssignments )
{
bool assignmentMatch;
for ( unsigned int i = 0; i < SPDList.size (); i++ ) {
SPDParser SPDFile ( SPDList[ i ] );
assignmentMatch = false;
char *component = SPDFile.getSoftPkgName ();
//Verify that the component assigned to the device exists in the SAD
for ( unsigned int j = 0; j < _deviceAssignments.length (); j++ ) {
if ( strcmp ( _deviceAssignments[ j ].componentId, component ) == 0 ) {
assignmentMatch = true;
}
}
ComponentDependencies ( &SPDFile, assignmentMatch );
}
}
ApplicationFactoryEventHandler::
ApplicationFactoryEventHandler ( ApplicationFactory_impl * _appFac )
{
appFactory = _appFac;
}
void
ApplicationFactoryEventHandler::push ( const CORBA::Any & _any )
throw ( CORBA::SystemException, CosEventComm::Disconnected )
{}
void
ApplicationFactoryEventHandler::disconnect_push_consumer ()
throw ( CORBA::SystemException )
{}