//******************************************************************************
//
// Restricted Rights
// WARNING: This is a restricted distribution Zeligsoft file.
//
//******************************************************************************
//
// Copyright (C) 2006 Zeligsoft Inc. - All Rights Reserved
//

//******************************************************************************
//
//     FILE: zcePushPorts_OctetSeqConsumerUsesPort.cpp
//
//******************************************************************************


#include "zcePushPorts_OctetSeqConsumerUsesPort.h"


zcePushPorts_OctetSeqConsumerUsesPort::zcePushPorts_OctetSeqConsumerUsesPort( std::string name ZCE_EXC_ENV_ARG ) : 
	port_(::PushPorts::OctetSeqConsumer::_nil()), name_(name), connectionId_(""), consCount_(0), cardinality_(ZCEPUSHPORTS_OCTETSEQCONSUMERUSESPORT_CARDINALITY_DEFAULT )
{

	ZCE_ASSERT_EXCEPTION_VOID;
	
}

zcePushPorts_OctetSeqConsumerUsesPort::~zcePushPorts_OctetSeqConsumerUsesPort()
{

	//ZCE_ASSERT_EXCEPTION_VOID;
	
}

/*!
 * \brief Applications require the connectPort operation to establish associations
 * between Ports. Ports provide channels through which data and/or control pass.
 * The connectPort operation provides half of a two-way association; therefore two
 * calls are required to create a two-way association.
 *
 * Specification reference:  3.1.3.1.1.5.1
 *
 * The connectPort operation shall make a connection to the component identified
 * by its input parameters. A port may support several connections. The input
 * connectionId is a unique identifier to be used by disconnectPort when breaking
 * this specific connection.
 *
 * \return This operation does not return a value.
 *
 * \throw InvalidPort The connectPort operation shall raise the InvalidPort
 * exception when the input connection parameter is an invalid connection for this
 * Port.
 *
 * \throw OccupiedPort The connectPort operation shall raise the OccupiedPort
 * exception when unable to accept the connections because the Port is already
 * fully occupied.
 *
 */
void zcePushPorts_OctetSeqConsumerUsesPort::connectPort ( CORBA::Object_ptr connection,  const char * connectionId ZCE_EXC_ENV_ARG )
			throw ( CORBA::SystemException, CF::Port::InvalidPort, CF::Port::OccupiedPort )
{

	ZCE_ASSERT_EXCEPTION_VOID;
	
	// The cardinality for uses ports defaults to '1' if you want the posibility of
	// higher cardinality ports, then port_ must be changed to map that maintains the
	// connected ports

	if(consCount_ > cardinality_)
	{
		// 3.1.3.1.1.5.1.5 : unable to accept the connection because the Port is already
		// fully occupied

		ZCE_EXC_THROW ( CF::Port::OccupiedPort, () );
	}

	if(!CORBA::is_nil(connection))
	{
		ZCE_EXC_TRY
		{
			port_ = PushPorts::OctetSeqConsumer::_narrow(connection);
		}
		ZCE_EXC_CATCHTYPE(CORBA::UserException)
		{
			// 3.1.3.1.1.5.1.5 : the input connection parameter is an invalid connection for
			// this Port
			// 3.1.3.1.1.3.1 : errorCode 1 means the Port component is invalid (unable to
			// narrow object reference) or illegal object reference
			ZCE_EXC_THROW ( CF::Port::InvalidPort, (1, name_.c_str()) );
		}
		ZCE_EXC_CATCHTYPE(CORBA::SystemException)
		{
			// 3.1.3.1.1.5.1.5 : the input connection parameter is an invalid connection for
			// this Port
			// 3.1.3.1.1.3.1 : errorCode 1 means the Port component is invalid (unable to
			// narrow object reference) or illegal object reference
			ZCE_EXC_THROW ( CF::Port::InvalidPort, (1, name_.c_str()) );
		}
		ZCE_EXC_CATCHTYPE(CORBA::Exception)
		{
			// 3.1.3.1.1.5.1.5 : the input connection parameter is an invalid connection for
			// this Port
			// 3.1.3.1.1.3.1 : errorCode 1 means the Port component is invalid (unable to
			// narrow object reference) or illegal object reference
			ZCE_EXC_THROW ( CF::Port::InvalidPort, (1, name_.c_str()) );
		}
		ZCE_EXC_ENDTRY_VOID;
		if(CORBA::is_nil(port_))
		{
			// 3.1.3.1.1.5.1.5 : the input connection parameter is an invalid connection for
			// this Port
			// 3.1.3.1.1.3.1 : errorCode 1 means the Port component is invalid (unable to
			// narrow object reference) or illegal object reference
			ZCE_EXC_THROW ( CF::Port::InvalidPort, (1, name_.c_str()) );
		}

		consCount_++; // increase the consumer count since a connection was made

		connectionId_ = connectionId;
	}
	else
	{
		// 3.1.3.1.1.5.1.5 : the input connection parameter is an invalid connection for
		// this Port
		// 3.1.3.1.1.3.1 : errorCode 1 means the Port component is invalid (unable to
		// narrow object reference) or illegal object reference
		ZCE_EXC_THROW ( CF::Port::InvalidPort, (1, name_.c_str()) );
	}

}

/*!
 * \brief Applications require the disconnectPort operation in order to allow
 * consumer/producer data components to disassociate themselves from their
 * counterparts (consumer/producer).
 *
 * Specification reference:  3.1.3.1.1.5.2
 *
 * The disconnectPort operation shall break the connection to the component
 * identified by the input parameter.
 *
 * \return This operation does not return a value.
 *
 * \throw InvalidPort The disconnectPort operation shall raise the InvalidPort
 * exception when the name passed to disconnectPort is not connected with the Port
 * component.
 *
 */
void zcePushPorts_OctetSeqConsumerUsesPort::disconnectPort ( const char * connectionId ZCE_EXC_ENV_ARG )
			throw ( CORBA::SystemException , CF::Port::InvalidPort )
{

	ZCE_ASSERT_EXCEPTION_VOID;
	if(connectionId_ != connectionId)
	{
		// 3.1.3.1.1.5.1.5 : the input connection parameter is an invalid connection for
		// this Port
		// 3.1.3.1.1.3.1 : errorCode 2 means the Port name is not found (not used by this
		// Port)
		ZCE_EXC_THROW ( CF::Port::InvalidPort, (2, connectionId) );
	}

	port_ = PushPorts::OctetSeqConsumer::_nil();

	connectionId_ = "";
	consCount_--;

}



bool zcePushPorts_OctetSeqConsumerUsesPort::is_connected( ZCE_EXC_ENV_SINGLE_ARG )
{
	bool _bRetVal = false;
	ZCE_ASSERT_EXCEPTION(_bRetVal);
	
	return ((!CORBA::is_nil(port_)) && (consCount_ > 0)); 
}




/*!	\brief
 *
 *	 Describe operation here.
 * 
 *	\param msg ( ::CF::OctetSequence ) 
 * 
 *	\param options ( ::CF::Properties ) 
 * 
 */
void zcePushPorts_OctetSeqConsumerUsesPort::processOctetMsg( const CF::OctetSequence& msg, const CF::Properties& options ZCE_EXC_ENV_ARG )
{
	ZCE_ASSERT_EXCEPTION_VOID;
	if (! is_connected(ZCE_EXC_ENV_SINGLE_PARAM) )
	{
		ZCE_EXC_THROW ( CORBA::OBJECT_NOT_EXIST, (0,CORBA::COMPLETED_NO) );
	}

	port_->processOctetMsg(msg, options);

}


// End-Of-File
//------------------------------------------------------------------------------
