Applying patch to activemq-cpp client for AMQ 818

git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@424272 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nathan Christopher Mittler 2006-07-21 11:36:09 +00:00
parent 8dd454ed08
commit a0e3831ab8
200 changed files with 8260 additions and 6619 deletions

View File

@ -0,0 +1,31 @@
Version 0.0.2
----------------------
New Features:
* Destinations now support the Destination Options shown here:
http://www.activemq.org/site/destination-options.html
Additional Changes
* Extensive code cleanup, including expanded Java DOC comments and more
consistant formatting.
* Memory leak checking with Rational Purify was done and several small
leaks were fixed.
* Added additional Unit tests for new functionality, and additional
tests for existing feature correctness
* Fixed a problem on Windows that was causing the socketinputstream
reads to break unexpectedly.
* Fixed the username, password, client-id processing so they get
out in the ConnectCommand Properly.
* Minor bug fixes
Known Issues
* Unchanged from version 0.0.1
Version 0.0.1
----------------------
* Initial Release

View File

@ -1,4 +1,5 @@
SRCDIR = src
OUTDIR = out
MAKESUPPORT_HOME = $(PWD)
OFILES = \
@ -31,6 +32,7 @@ OFILES = \
$(OUTDIR)/main/activemq/core/ActiveMQProducer.o \
$(OUTDIR)/main/activemq/core/ActiveMQConsumer.o \
$(OUTDIR)/main/activemq/core/ActiveMQTransaction.o \
$(OUTDIR)/main/activemq/core/ActiveMQConstants.o \
\
$(OUTDIR)/main/activemq/io/EndianReader.o \
$(OUTDIR)/main/activemq/io/EndianWriter.o \
@ -62,6 +64,7 @@ OFILES = \
OTESTFILES = \
$(OUTDIR)/test/main.o \
\
$(OUTDIR)/test/activemq/core/ActiveMQDestinationTest.o \
$(OUTDIR)/test/activemq/core/ActiveMQConnectionFactoryTest.o \
$(OUTDIR)/test/activemq/core/ActiveMQConnectionTest.o \
$(OUTDIR)/test/activemq/core/ActiveMQSessionTest.o \
@ -130,10 +133,16 @@ OINTEGRATIONFILES = \
$(OUTDIR)/test-integration/integration/simple/SimpleTester.o \
$(OUTDIR)/test-integration/integration/transactional/TransactionTester.o \
$(OUTDIR)/test-integration/integration/common/AbstractTester.o \
$(OUTDIR)/test-integration/integration/common/IntegrationCommon.o
$(OUTDIR)/test-integration/integration/common/IntegrationCommon.o \
$(OUTDIR)/test-integration/integration/various/SimpleRollbackTest.o
LIBFILE = $(OUTDIR)/activemq.a
TESTEXE = $(OUTDIR)/activemqTest
# Increment this to get a build specific library.
VERSION = 0_0_2
LIBRARY_NAME = activemq-cpp-$(VERSION)
LIBFILE = $(OUTDIR)/lib$(LIBRARY_NAME).a
TESTEXE = $(OUTDIR)/activemqTest
INTEGRATIONEXE = $(OUTDIR)/activemqIntegrationTests
DEFINES =

View File

@ -2,17 +2,13 @@
# Compiler specific configuration
#
OUTDIR = out
LIBRARY_NAME = activemq-cpp
LIBFILE = $(OUTDIR)/lib$(LIBRARY_NAME).a
#
# GCC/G++ debug for Linux
#
CC = g++ -frtti -g -pthread -DDEBUG -D_DEBUG -D_REENTRANT
LD = g++ -g -frtti -pthread
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -ldl -luuid
ARFLAGS =
CC = g++ -frtti -g -pthread -DDEBUG -D_DEBUG -D_REENTRANT
LD = g++ -g -frtti -pthread
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -ldl -luuid
ARFLAGS =

View File

@ -2,18 +2,13 @@
# Compiler specific configuration
#
OUTDIR = out
LIBRARY_NAME = activemq-cpp
LIBFILE = $(OUTDIR)/lib$(LIBRARY_NAME).a
#
# GCC/G++ release for Linux
#
CC = g++ -frtti -pthread -O3 -DNDEBUG -D_REENTRANT
LD = g++ -frtti -pthread
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -ldl -luuid
OUTDIR = out
ARFLAGS =
CC = g++ -frtti -pthread -O3 -DNDEBUG -D_REENTRANT
LD = g++ -frtti -pthread
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -ldl -luuid
ARFLAGS =

View File

@ -2,17 +2,12 @@
# Compiler specific configuration
#
OUTDIR = out
LIBRARY_NAME = activemq-cpp
LIBFILE = $(OUTDIR)/lib$(LIBRARY_NAME).a
#
# GCC/G++ debug for Linux
#
CC = g++ -fexceptions -frtti -O0 -g3 -DDEBUG -D_DEBUG -D_REENTRANT -D_WIN32 -DWINVER=0x0502 -DWIN32_LEAN_AND_MEAN
LD = g++ -g3 -frtti
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -lws2_32 -lrpcrt4
OUTDIR = out
ARFLAGS =
CC = g++ -fexceptions -frtti -O0 -g3 -DDEBUG -D_DEBUG -D_REENTRANT -D_WIN32 -DWINVER=0x0502 -DWIN32_LEAN_AND_MEAN
LD = g++ -g3 -frtti
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -lws2_32 -lrpcrt4
ARFLAGS =

View File

@ -2,18 +2,13 @@
# Compiler specific configuration
#
OUTDIR = out
LIBRARY_NAME = activemq-cpp
LIBFILE = $(OUTDIR)/lib$(LIBRARY_NAME).a
#
# GCC/G++ release for Linux
#
CC = g++ -fexceptions -frtti -O3 -DNDEBUG -D_REENTRANT -D__WIN32 -DWIN32_LEAN_AND_MEAN
LD = g++ -frtti
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -lws2_32 -lrpcrt4
OUTDIR = out
ARFLAGS =
CC = g++ -fexceptions -frtti -O3 -DNDEBUG -D_REENTRANT -D__WIN32 -DWIN32_LEAN_AND_MEAN
LD = g++ -frtti
CCFLAGS = -Wall
LDFLAGS = -L$(OUTDIR) -l$(LIBRARY_NAME) -lcppunit -lws2_32 -lrpcrt4
ARFLAGS =

View File

@ -84,19 +84,13 @@ default: all
$(LIBFILE): $(OFILES) $(DEPLIBS)
$(ECHO) " - Creating static library file "$@
$(ECHO) " - $(AR) $(ARFLAGS) $@ $(OFILES)"
$(AR) $(ARFLAGS) $@ $(OFILES)
$(ECHO) 'Finished building target: $@'
$(TESTEXE): $(OTESTFILES) $(LIBFILE)
$(ECHO) " - Creating executable "$@
$(ECHO) " - $(LD) -o $@ $(OTESTFILES) $(LDFLAGS)"
$(TESTEXE): $(OTESTFILES)
$(LD) -o $@ $(OTESTFILES) $(LDFLAGS)
$(ECHO) 'Finished building target: $@'
$(INTEGRATIONEXE): $(OINTEGRATIONFILES) $(LIBFILE)
$(ECHO) " - Creating executable "$@
$(ECHO) " - $(LD) -o $@ $(OINTEGRATIONFILES) $(LDFLAGS)"
$(INTEGRATIONEXE): $(OINTEGRATIONFILES)
$(LD) -o $@ $(OINTEGRATIONFILES) $(LDFLAGS)
$(ECHO) 'Finished building target: $@'
@ -171,6 +165,7 @@ prepare_integration:
$(MD) $(OUTDIR)/test-integration/integration/simple; \
$(MD) $(OUTDIR)/test-integration/integration/transactional; \
$(MD) $(OUTDIR)/test-integration/integration/durable; \
$(MD) $(OUTDIR)/test-integration/integration/various; \
fi
done:

View File

@ -91,6 +91,7 @@
<fileName>ActiveMQProducer.cpp</fileName>
<fileName>ActiveMQSession.cpp</fileName>
<fileName>ActiveMQTransaction.cpp</fileName>
<fileName>ActiveMQConstants.cpp</fileName>
</fileNames>
</source>
<source>

View File

@ -1,5 +1,5 @@
--------------------------------------------------------------------------
ActiveMQ CPP Library - Version 0.0.1
ActiveMQ CPP Library
--------------------------------------------------------------------------
This library provides a JMS like interface to an ActiveMQ broker in c++.

View File

@ -42,7 +42,7 @@ public:
virtual void run() {
try {
// Create a ConnectionFactory
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory("127.0.0.1:61613");
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61613");
// Create a Connection
connection = connectionFactory->createConnection();
@ -143,7 +143,7 @@ public:
try {
// Create a ConnectionFactory
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory("127.0.0.1:61613");
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61613");
// Create a Connection
connection = connectionFactory->createConnection();

View File

@ -51,11 +51,11 @@ namespace concurrent{
#define WAIT_INFINITE 0xFFFFFFFF
#define synchronized(W) \
if(false){} \
else \
for(activemq::concurrent::Lock lock_W(W); \
lock_W.isLocked(); lock_W.unlock())
#define synchronized(W) \
if(false){} \
else \
for(activemq::concurrent::Lock lock_W(W); \
lock_W.isLocked(); lock_W.unlock())
}}

View File

@ -18,106 +18,105 @@
#ifndef ACTIVEMQ_CONCURRENT_LOCK_H
#define ACTIVEMQ_CONCURRENT_LOCK_H
// Includes.
#include <activemq/concurrent/Synchronizable.h>
namespace activemq{
namespace concurrent{
/**
* A wrapper class around a given synchronization mechanism that
* provides automatic release upon destruction.
* @author Nathan Mittler
*/
class Lock
{
private: // Data
/**
* Flag to indicate whether or not this object has locked the
* sync object.
* A wrapper class around a given synchronization mechanism that
* provides automatic release upon destruction.
* @author Nathan Mittler
*/
bool locked;
class Lock
{
private: // Data
/**
* The synchronizable object to lock/unlock.
*/
Synchronizable* syncObject;
/**
* Flag to indicate whether or not this object has locked the
* sync object.
*/
bool locked;
/**
* The synchronizable object to lock/unlock.
*/
Synchronizable* syncObject;
public: // Interface
public: // Interface
/**
* Constructor - initializes the object member and locks
* the object if desired.
* @param object The sync object to control
* @param intiallyLocked If true, the object will automatically
* be locked.
*/
Lock( Synchronizable* object, const bool intiallyLocked = true )
{
try{
syncObject = object;
locked = false;
if( intiallyLocked )
{
lock();
}
/**
* Constructor - initializes the object member and locks
* the object if desired.
* @param object The sync object to control
* @param intiallyLocked If true, the object will automatically
* be locked.
*/
Lock( Synchronizable* object, const bool intiallyLocked = true )
{
try{
syncObject = object;
locked = false;
if( intiallyLocked )
{
lock();
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
/**
* Destructor - Unlocks the object if it is locked.
*/
virtual ~Lock()
{
try{
if( locked )
{
syncObject->unlock();
}
/**
* Destructor - Unlocks the object if it is locked.
*/
virtual ~Lock()
{
try{
if( locked )
{
syncObject->unlock();
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
/**
* Locks the object.
*/
void lock()
{
try{
syncObject->lock();
locked = true;
/**
* Locks the object.
*/
void lock()
{
try{
syncObject->lock();
locked = true;
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
/**
* Unlocks the object.
*/
void unlock()
{
try{
if(locked)
{
syncObject->unlock();
locked = false;
}
/**
* Unlocks the object.
*/
void unlock()
{
try{
if(locked)
{
syncObject->unlock();
locked = false;
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
/**
* Indicates whether or not the object is locked.
* @return true if the object is locked, otherwise false.
*/
bool isLocked() const{ return locked; }
};
/**
* Indicates whether or not the object is locked.
* @return true if the object is locked, otherwise false.
*/
bool isLocked() const{ return locked; }
};
}}

View File

@ -96,7 +96,7 @@ namespace concurrent{
lock_owner = 0;
lock_count = 0;
}
/**
* Destructor - destroys the mutex object.
*/

View File

@ -30,19 +30,19 @@ LOGCMS_INITIALIZE(logger, PooledThread, "com.activemq.concurrent.PooledThread");
////////////////////////////////////////////////////////////////////////////////
PooledThread::PooledThread(ThreadPool* pool)
{
if(pool == NULL)
{
throw exceptions::IllegalArgumentException( __FILE__, __LINE__,
"PooledThread::PooledThread");
}
if(pool == NULL)
{
throw exceptions::IllegalArgumentException( __FILE__, __LINE__,
"PooledThread::PooledThread");
}
busy = false;
done = false;
busy = false;
done = false;
listener = NULL;
listener = NULL;
// Store our Pool.
this->pool = pool;
// Store our Pool.
this->pool = pool;
}
////////////////////////////////////////////////////////////////////////////////
@ -53,109 +53,109 @@ PooledThread::~PooledThread()
////////////////////////////////////////////////////////////////////////////////
void PooledThread::run(void)
{
ThreadPool::Task task;
ThreadPool::Task task;
try
{
while(!done)
{
//LOGCMS_DEBUG(logger, "PooledThread::run - Entering deQ");
try
{
while(!done)
{
//LOGCMS_DEBUG(logger, "PooledThread::run - Entering deQ");
// Blocks until there something to be done
task = pool->deQueueTask();
// Blocks until there something to be done
task = pool->deQueueTask();
//LOGCMS_DEBUG(logger, "PooledThread::run - Exited deQ");
//LOGCMS_DEBUG(logger, "PooledThread::run - Exited deQ");
// Check if the Done Flag is set, in case it happened while we
// were waiting for a task
if(done)
{
break;
}
// Check if the Done Flag is set, in case it happened while we
// were waiting for a task
if(done)
{
break;
}
// If we got here and the runnable was null then something
// bad must have happened. Throw an Exception and bail.
if(!task.first)
{
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"PooledThread::run - Retrieive NULL task from Pool.");
}
// If we got here and the runnable was null then something
// bad must have happened. Throw an Exception and bail.
if(!task.first)
{
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"PooledThread::run - Retrieive NULL task from Pool.");
}
// Got some work to do, so set flag to busy
busy = true;
// Got some work to do, so set flag to busy
busy = true;
// Inform a listener that we are going to start
if(listener)
{
/*LOGCMS_DEBUG(logger,
"PooledThread::run - Inform Listener we are starting");*/
listener->onTaskStarted(this);
}
// Perform the work
task.first->run();
// Inform a listener that we are going to start
if(listener)
{
/*LOGCMS_DEBUG(logger,
"PooledThread::run - Inform Listener we are starting");*/
listener->onTaskStarted(this);
}
// Perform the work
task.first->run();
/*LOGCMS_DEBUG(logger,
"PooledThread::run - Inform Task Listener we are done");*/
"PooledThread::run - Inform Task Listener we are done");*/
// Notify the Task listener that we are done
task.second->onTaskComplete(task.first);
// Notify the Task listener that we are done
task.second->onTaskComplete(task.first);
// Inform a listener that we are going to stop and wait
// for a new task
if(listener)
{
/*LOGCMS_DEBUG(logger,
"PooledThread::run - Inform Listener we are done");*/
listener->onTaskCompleted(this);
}
// Inform a listener that we are going to stop and wait
// for a new task
if(listener)
{
/*LOGCMS_DEBUG(logger,
"PooledThread::run - Inform Listener we are done");*/
listener->onTaskCompleted(this);
}
// Set flag to inactive, we will wait for work
busy = false;
}
}
catch(exceptions::ActiveMQException& ex)
{
ex.setMark( __FILE__, __LINE__ );
// Set flag to inactive, we will wait for work
busy = false;
}
}
catch( exceptions::ActiveMQException& ex )
{
ex.setMark( __FILE__, __LINE__ );
// Notify the Task owner
if(task.first && task.second)
{
task.second->onTaskException(task.first, ex);
}
// Notify the Task owner
if(task.first && task.second)
{
task.second->onTaskException(task.first, ex);
}
busy = false;
busy = false;
// Notify the PooledThreadListener
if(listener)
{
listener->onTaskException(this, ex);
}
}
catch(...)
{
exceptions::ActiveMQException ex(
__FILE__, __LINE__,
"PooledThread::run - Caught Unknown Exception");
// Notify the PooledThreadListener
if(listener)
{
listener->onTaskException(this, ex);
}
}
catch(...)
{
exceptions::ActiveMQException ex(
__FILE__, __LINE__,
"PooledThread::run - Caught Unknown Exception");
// Notify the Task owner
if(task.first && task.second)
{
task.second->onTaskException(task.first, ex);
}
// Notify the Task owner
if(task.first && task.second)
{
task.second->onTaskException(task.first, ex);
}
busy = false;
busy = false;
// Notify the PooledThreadListener
if(listener)
{
listener->onTaskException(this, ex);
}
}
// Notify the PooledThreadListener
if(listener)
{
listener->onTaskException(this, ex);
}
}
}
////////////////////////////////////////////////////////////////////////////////
void PooledThread::stop(void) throw ( cms::CMSException )
{
done = true;
done = true;
}

View File

@ -28,77 +28,77 @@
namespace activemq{
namespace concurrent{
class ThreadPool;
class ThreadPool;
class PooledThread : public Thread, public cms::Stoppable
{
private:
class PooledThread : public Thread, public cms::Stoppable
{
private:
// Is this thread currently processing something
bool busy;
// Is this thread currently processing something
bool busy;
// Boolean flag indicating thread should stop
bool done;
// Boolean flag indicating thread should stop
bool done;
// Listener for Task related events
PooledThreadListener* listener;
// Listener for Task related events
PooledThreadListener* listener;
// The thread pool this Pooled Thread is Servicing
ThreadPool* pool;
// The thread pool this Pooled Thread is Servicing
ThreadPool* pool;
// Logger Init
LOGCMS_DECLARE(logger);
// Logger Init
LOGCMS_DECLARE(logger);
public:
public:
/**
* Constructor
*/
PooledThread(ThreadPool* pool);
/**
* Constructor
*/
PooledThread(ThreadPool* pool);
/**
* Destructor
*/
virtual ~PooledThread(void);
/**
* Destructor
*/
virtual ~PooledThread(void);
/**
* Run Method for this object waits for something to be
* enqueued on the ThreadPool and then grabs it and calls
* its run method.
*/
virtual void run(void);
/**
* Run Method for this object waits for something to be
* enqueued on the ThreadPool and then grabs it and calls
* its run method.
*/
virtual void run(void);
/**
* Stops the Thread, thread will complete its task if currently
* running one, and then die. Does not block.
*/
virtual void stop(void) throw ( cms::CMSException );
/**
* Stops the Thread, thread will complete its task if currently
* running one, and then die. Does not block.
*/
virtual void stop(void) throw ( cms::CMSException );
/**
* Checks to see if the thread is busy, if busy it means
* that this thread has taken a task from the ThreadPool's
* queue and is processing it.
*/
virtual bool isBusy(void) { return busy; }
/**
* Adds a listener to this <code>PooledThread</code> to be
* notified when this thread starts and completes a task.
*/
virtual void setPooledThreadListener(PooledThreadListener* listener)
{
this->listener = listener;
}
/**
* Checks to see if the thread is busy, if busy it means
* that this thread has taken a task from the ThreadPool's
* queue and is processing it.
*/
virtual bool isBusy(void) { return busy; }
/**
* Removes a listener for this <code>PooledThread</code> to be
* notified when this thread starts and completes a task.
*/
virtual PooledThreadListener* getPooledThreadListener(void)
{
return this->listener;
}
};
/**
* Adds a listener to this <code>PooledThread</code> to be
* notified when this thread starts and completes a task.
*/
virtual void setPooledThreadListener(PooledThreadListener* listener)
{
this->listener = listener;
}
/**
* Removes a listener for this <code>PooledThread</code> to be
* notified when this thread starts and completes a task.
*/
virtual PooledThreadListener* getPooledThreadListener(void)
{
return this->listener;
}
};
}}

View File

@ -22,44 +22,43 @@
namespace activemq{
namespace concurrent{
//forward declare
class PooledThread;
class PooledThread;
class PooledThreadListener
{
public:
class PooledThreadListener
{
public:
/**
* Destructor
*/
virtual ~PooledThreadListener(void) {}
/**
* Called by a pooled thread when it is about to begin
* executing a new task.
* @param Pointer to the Pooled Thread that is making this call
*/
virtual void onTaskStarted(PooledThread* thread) = 0;
/**
* Destructor
*/
virtual ~PooledThreadListener(void) {}
/**
* Called by a pooled thread when it is about to begin
* executing a new task.
* @param Pointer to the Pooled Thread that is making this call
*/
virtual void onTaskStarted(PooledThread* thread) = 0;
/**
* Called by a pooled thread when it has completed a task
* and is going back to waiting for another task to run
* @param Pointer the the Pooled Thread that is making this call.
*/
virtual void onTaskCompleted(PooledThread* thread) = 0;
/**
* Called by a pooled thread when it has completed a task
* and is going back to waiting for another task to run
* @param Pointer the the Pooled Thread that is making this call.
*/
virtual void onTaskCompleted(PooledThread* thread) = 0;
/**
* Called by a pooled thread when it has encountered an exception
* while running a user task, after receiving this notification
* the callee should assume that the PooledThread is now no longer
* running.
* @param Pointer to the Pooled Thread that is making this call
* @param The Exception that occured.
*/
virtual void onTaskException(PooledThread* thread,
exceptions::ActiveMQException& ex) = 0;
/**
* Called by a pooled thread when it has encountered an exception
* while running a user task, after receiving this notification
* the callee should assume that the PooledThread is now no longer
* running.
* @param Pointer to the Pooled Thread that is making this call
* @param The Exception that occured.
*/
virtual void onTaskException( PooledThread* thread,
exceptions::ActiveMQException& ex) = 0;
};
};
}}

View File

@ -19,23 +19,23 @@
namespace activemq{
namespace concurrent{
/**
* Interface for a runnable object - defines a task
* that can be run by a thread.
*/
class Runnable{
public:
virtual ~Runnable(){}
/**
* Run method - called by the Thread class in the context
* of the thread.
*/
virtual void run() = 0;
};
/**
* Interface for a runnable object - defines a task
* that can be run by a thread.
*/
class Runnable{
public:
virtual ~Runnable(){}
/**
* Run method - called by the Thread class in the context
* of the thread.
*/
virtual void run() = 0;
};
}}
#endif /*ACTIVEMQ_CONCURRENT_RUNNABLE_H_*/

View File

@ -23,64 +23,64 @@
namespace activemq{
namespace concurrent{
/**
* The interface for all synchronizable objects (that is, objects
* that can be locked and unlocked).
*/
class Synchronizable
{
public: // Abstract Interface
/**
* The interface for all synchronizable objects (that is, objects
* that can be locked and unlocked).
*/
class Synchronizable
{
public:
virtual ~Synchronizable(){}
/**
* Locks the object.
* @throws ActiveMQException
*/
virtual void lock() throw(exceptions::ActiveMQException) = 0;
/**
* Unlocks the object.
* @throws ActiveMQException
*/
virtual void unlock() throw(exceptions::ActiveMQException) = 0;
virtual ~Synchronizable(){}
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling.
* @throws ActiveMQException
*/
virtual void wait() throw(exceptions::ActiveMQException) = 0;
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling. This wait will timeout after the specified time
* interval.
* @param time in millisecsonds to wait, or WAIT_INIFINITE
* @throws ActiveMQException
*/
virtual void wait(unsigned long millisecs)
throw(exceptions::ActiveMQException) = 0;
/**
* Locks the object.
* @throws ActiveMQException
*/
virtual void lock() throw(exceptions::ActiveMQException) = 0;
/**
* Signals a waiter on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
* @throws ActiveMQException
*/
virtual void notify() throw(exceptions::ActiveMQException) = 0;
/**
* Unlocks the object.
* @throws ActiveMQException
*/
virtual void unlock() throw(exceptions::ActiveMQException) = 0;
/**
* Signals the waiters on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
* @throws ActiveMQException
*/
virtual void notifyAll() throw(exceptions::ActiveMQException) = 0;
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling.
* @throws ActiveMQException
*/
virtual void wait() throw(exceptions::ActiveMQException) = 0;
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling. This wait will timeout after the specified time
* interval.
* @param time in millisecsonds to wait, or WAIT_INIFINITE
* @throws ActiveMQException
*/
virtual void wait(unsigned long millisecs)
throw(exceptions::ActiveMQException) = 0;
};
/**
* Signals a waiter on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
* @throws ActiveMQException
*/
virtual void notify() throw( exceptions::ActiveMQException ) = 0;
/**
* Signals the waiters on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
* @throws ActiveMQException
*/
virtual void notifyAll() throw( exceptions::ActiveMQException ) = 0;
};
}}

View File

@ -23,33 +23,30 @@
namespace activemq{
namespace concurrent{
class TaskListener
{
public:
/**
* Destructor
*/
virtual ~TaskListener() {}
/**
* Called when a queued task has completed, the task that
* finished is passed along for user consumption
* @param Runnable Pointer to the task that finished
*/
virtual void onTaskComplete(Runnable* task) = 0;
/**
* Called when a queued task has thrown an exception while
* being run. The Callee should assume that this was an
* unrecoverable exeption and that this task is now defunct.
* @param Runnable Pointer to the task
* @param The ActiveMQException that was thrown.
*/
virtual void onTaskException(Runnable* task,
exceptions::ActiveMQException& ex) = 0;
};
class TaskListener
{
public:
virtual ~TaskListener() {}
/**
* Called when a queued task has completed, the task that
* finished is passed along for user consumption
* @param Runnable Pointer to the task that finished
*/
virtual void onTaskComplete(Runnable* task) = 0;
/**
* Called when a queued task has thrown an exception while
* being run. The Callee should assume that this was an
* unrecoverable exeption and that this task is now defunct.
* @param Runnable Pointer to the task
* @param The ActiveMQException that was thrown.
*/
virtual void onTaskException( Runnable* task,
exceptions::ActiveMQException& ex) = 0;
};
}}

View File

@ -19,10 +19,10 @@
#include <errno.h>
#ifdef unix
#include <errno.h> // EINTR
#include <errno.h> // EINTR
extern int errno;
#else
#include <process.h> // _endthreadex
#include <process.h> // _endthreadex
#endif
#include <activemq/exceptions/ActiveMQException.h>
@ -45,17 +45,17 @@ static struct ThreadStaticInitializer {
////////////////////////////////////////////////////////////////////////////////
Thread::Thread()
{
task = this;
started = false;
joined = false;
task = this;
started = false;
joined = false;
}
////////////////////////////////////////////////////////////////////////////////
Thread::Thread( Runnable* task )
{
this->task = task;
started = false;
joined = false;
this->task = task;
started = false;
joined = false;
}
////////////////////////////////////////////////////////////////////////////////
@ -72,8 +72,8 @@ void Thread::start() throw ( exceptions::ActiveMQException )
}
#ifdef unix
pthread_attr_init (&attributes);
pthread_attr_init (&attributes);
pthread_attr_setdetachstate (&attributes, PTHREAD_CREATE_JOINABLE);
int err = pthread_create (
&this->threadHandle,
@ -81,7 +81,7 @@ void Thread::start() throw ( exceptions::ActiveMQException )
runCallback,
this);
if (err != 0) {
throw exceptions::ActiveMQException( __FILE__, __LINE__,
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"Coud not start thread");
}
@ -91,13 +91,13 @@ void Thread::start() throw ( exceptions::ActiveMQException )
this->threadHandle =
(HANDLE)_beginthreadex(NULL, 0, runCallback, this, 0, &threadId);
if (this->threadHandle == NULL) {
throw exceptions::ActiveMQException( __FILE__, __LINE__,
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"Coud not start thread");
}
#endif
// Mark the thread as started.
// Mark the thread as started.
started = true;
}
@ -105,11 +105,11 @@ void Thread::start() throw ( exceptions::ActiveMQException )
void Thread::join() throw( exceptions::ActiveMQException )
{
if (!this->started) {
throw exceptions::ActiveMQException( __FILE__, __LINE__,
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"Thread::join() called without having called Thread::start()");
}
if (!this->joined) {
#ifdef unix
pthread_join(this->threadHandle, NULL);
#else
@ -121,16 +121,16 @@ void Thread::join() throw( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void Thread::sleep(int millisecs)
void Thread::sleep( int millisecs )
{
#ifdef unix
struct timespec rec, rem;
rec.tv_sec = millisecs / 1000;
rec.tv_nsec = (millisecs % 1000) * 1000000;
while( nanosleep( &rec, &rem ) == -1 ){
if( errno != EINTR ){
break;
}
if( errno != EINTR ){
break;
}
}
#else
@ -154,9 +154,9 @@ void*
#else
unsigned int WINAPI
#endif
Thread::runCallback (void* param)
Thread::runCallback( void* param )
{
// Get the instance.
// Get the instance.
Thread* thread = (Thread*)param;
// Invoke run on the task.

View File

@ -24,107 +24,108 @@
#if (defined(__unix__) || defined(unix) || defined(MACOSX) || defined(__APPLE__)) && !defined(USG)
#ifndef unix
#define unix
#endif
#ifndef unix
#define unix
#endif
#include <pthread.h>
#include <pthread.h>
#else
#include <windows.h>
#include <windows.h>
#endif
namespace activemq{
namespace concurrent{
/**
* Basic thread class - mimics the Java Thread. Derived classes may
* implement the run method, or this class can be used as is with
* a provided Runnable delegate.
*/
class Thread : public Runnable
{
private:
/**
* Basic thread class - mimics the Java Thread. Derived classes may
* implement the run method, or this class can be used as is with
* a provided Runnable delegate.
*/
class Thread : public Runnable
{
private:
/**
* The task to be run by this thread, defaults to
* this thread object.
*/
Runnable* task;
/**
* The task to be run by this thread, defaults to
* this thread object.
*/
Runnable* task;
#ifdef unix
pthread_attr_t attributes;
pthread_t threadHandle ;
#else
HANDLE threadHandle ;
#endif
#ifdef unix
pthread_attr_t attributes;
pthread_t threadHandle;
#else
HANDLE threadHandle;
#endif
/**
* Started state of this thread.
*/
bool started;
/**
* Started state of this thread.
*/
bool started;
/**
* Indicates whether the thread has already been
* joined.
*/
bool joined;
/**
* Indicates whether the thread has already been
* joined.
*/
bool joined;
public:
public:
Thread();
Thread( Runnable* task );
virtual ~Thread();
Thread();
Thread( Runnable* task );
virtual ~Thread();
/**
* Creates a system thread and starts it in a joinable mode.
* Upon creation, the
* run() method of either this object or the provided Runnable
* object will be invoked in the context of this thread.
* @exception runtime_error is thrown if the system could
* not start the thread.
*/
virtual void start() throw (exceptions::ActiveMQException);
/**
* Creates a system thread and starts it in a joinable mode.
* Upon creation, the
* run() method of either this object or the provided Runnable
* object will be invoked in the context of this thread.
* @exception runtime_error is thrown if the system could
* not start the thread.
*/
virtual void start() throw ( exceptions::ActiveMQException );
/**
* Wait til the thread exits. This is when the run()
* method has returned or has thrown an exception.
* If an exception was thrown in the run() method,
* join() will return the thrown exception. Otherwise
* (if run() returned normally), join() will
* return NULL.
*/
virtual void join() throw (exceptions::ActiveMQException);
/**
* Wait til the thread exits. This is when the run()
* method has returned or has thrown an exception.
* If an exception was thrown in the run() method,
* join() will return the thrown exception. Otherwise
* (if run() returned normally), join() will
* return NULL.
*/
virtual void join() throw ( exceptions::ActiveMQException );
/**
* Default implementation of the run method - does nothing.
*/
virtual void run(){};
/**
* Default implementation of the run method - does nothing.
*/
virtual void run(){};
public:
public:
/**
* Halts execution of the calling thread for a specified no of millisec.
*
* Note that this method is a static method that applies to the
* calling thread and not to the thread object.
*/
static void sleep(int millisecs);
/**
* Halts execution of the calling thread for a specified no of millisec.
*
* Note that this method is a static method that applies to the
* calling thread and not to the thread object.
*/
static void sleep( int millisecs );
/**
* Obtains the Thread Id of the current thread
* @return Thread Id
*/
static unsigned long getId(void);
/**
* Obtains the Thread Id of the current thread
* @return Thread Id
*/
static unsigned long getId(void);
private:
private:
// Internal thread handling
#ifdef unix
static void* runCallback (void* param);
#else
static unsigned int WINAPI runCallback (void* param);
#endif
} ;
// Internal thread handling
#ifdef unix
static void* runCallback (void* param);
#else
static unsigned int WINAPI runCallback (void* param);
#endif
};
}}

View File

@ -39,273 +39,279 @@ ThreadPool ThreadPool::instance;
////////////////////////////////////////////////////////////////////////////////
ThreadPool::ThreadPool(void)
{
maxThreads = DEFAULT_MAX_POOL_SIZE;
blockSize = DEFAULT_MAX_BLOCK_SIZE;
freeThreads = 0;
maxThreads = DEFAULT_MAX_POOL_SIZE;
blockSize = DEFAULT_MAX_BLOCK_SIZE;
freeThreads = 0;
shutdown = false;
shutdown = false;
}
////////////////////////////////////////////////////////////////////////////////
ThreadPool::~ThreadPool(void)
{
try
{
std::vector<PooledThread*>::iterator itr = pool.begin();
try
{
std::vector<PooledThread*>::iterator itr = pool.begin();
// Stop all the threads
for(; itr != pool.end(); ++itr)
{
(*itr)->stop();
}
// Stop all the threads
for(; itr != pool.end(); ++itr)
{
(*itr)->stop();
}
// Set the shutdown flag so that the DeQueue methods all quit
// when we interrupt them.
shutdown = true;
// Set the shutdown flag so that the DeQueue methods all quit
// when we interrupt them.
shutdown = true;
synchronized(&queue)
{
// Signal the Queue so that all waiters are notified
queue.notifyAll();
}
synchronized(&queue)
{
// Signal the Queue so that all waiters are notified
queue.notifyAll();
}
// Wait for everyone to die
for(itr = pool.begin(); itr != pool.end(); ++itr)
{
(*itr)->join();
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
// Wait for everyone to die
for(itr = pool.begin(); itr != pool.end(); ++itr)
{
(*itr)->join();
// Destroy the threads
delete *itr;
}
pool.clear();
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::queueTask(ThreadPool::Task task)
void ThreadPool::queueTask( ThreadPool::Task task )
throw ( exceptions::ActiveMQException )
{
try
{
if(!task.first || !task.second)
{
throw exceptions::IllegalArgumentException( __FILE__, __LINE__,
"ThreadPool::QueueTask - Invalid args for Task");
}
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - syncing on queue");
try
{
if(!task.first || !task.second)
{
throw exceptions::IllegalArgumentException( __FILE__, __LINE__,
"ThreadPool::QueueTask - Invalid args for Task");
}
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - syncing on queue");
synchronized(&queue)
{
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - sync'd, synching pool");
synchronized(&queue)
{
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - sync'd, synching pool");
// If there's nobody open to do work, then create some more
// threads to handle the work.
if(freeThreads == 0)
{
AllocateThreads(blockSize);
}
// If there's nobody open to do work, then create some more
// threads to handle the work.
if(freeThreads == 0)
{
AllocateThreads(blockSize);
}
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - pushing task");
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - pushing task");
// queue the new work.
queue.push(task);
// queue the new work.
queue.push(task);
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - calling notify");
//LOGCMS_DEBUG(logger, "ThreadPool::QueueTask - calling notify");
// Inform waiters that we put some work on the queue.
queue.notify();
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
// Inform waiters that we put some work on the queue.
queue.notify();
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
ThreadPool::Task ThreadPool::deQueueTask(void)
throw ( exceptions::ActiveMQException )
{
try
{
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - syncing on queue");
try
{
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - syncing on queue");
synchronized(&queue)
{
/*LOGCMS_DEBUG(logger,
"ThreadPool::DeQueueTask - sync'd checking queue empty");*/
synchronized(&queue)
{
/*LOGCMS_DEBUG(logger,
"ThreadPool::DeQueueTask - sync'd checking queue empty");*/
// Wait for work, wait in a while loop since another thread could
// be waiting for a lock and get the work before we get woken up
// from our wait.
while(queue.empty() && !shutdown)
{
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - Q empty, waiting");
// Wait for work, wait in a while loop since another thread could
// be waiting for a lock and get the work before we get woken up
// from our wait.
while(queue.empty() && !shutdown)
{
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - Q empty, waiting");
queue.wait();
queue.wait();
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - done waiting");
}
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - done waiting");
}
// Don't give more work if we are closing down
if(shutdown)
{
return Task();
}
// Don't give more work if we are closing down
if(shutdown)
{
return Task();
}
// check size again.
if(queue.empty())
{
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"ThreadPool::DeQueueUserWorkItem - Empty Taskn, not in shutdown.");
}
// check size again.
if(queue.empty())
{
throw exceptions::ActiveMQException( __FILE__, __LINE__,
"ThreadPool::DeQueueUserWorkItem - Empty Taskn, not in shutdown.");
}
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - popping task");
//LOGCMS_DEBUG(logger, "ThreadPool::DeQueueTask - popping task");
// not empty so get the new work to do
return queue.pop();
}
// not empty so get the new work to do
return queue.pop();
}
return Task();
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
return Task();
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::reserve(unsigned long size)
void ThreadPool::reserve( unsigned long size )
{
try{
synchronized(&poolLock)
{
if(size < pool.size() || pool.size() == maxThreads)
{
return;
}
try
{
synchronized(&poolLock)
{
if(size < pool.size() || pool.size() == maxThreads)
{
return;
}
// How many do we reserve
unsigned long allocCount = size - pool.size();
// How many do we reserve
unsigned long allocCount = size - pool.size();
// Allocate the new Threads
AllocateThreads(allocCount);
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
// Allocate the new Threads
AllocateThreads(allocCount);
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::setMaxThreads(unsigned long maxThreads)
void ThreadPool::setMaxThreads( unsigned long maxThreads )
{
try
{
synchronized(&poolLock)
{
if(maxThreads == 0)
{
// Caller tried to do something stupid, ignore them.
try
{
synchronized(&poolLock)
{
if(maxThreads == 0)
{
// Caller tried to do something stupid, ignore them.
return;
}
this->maxThreads = maxThreads;
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::setBlockSize( unsigned long blockSize )
{
try
{
if(blockSize <= 0)
{
// User tried something dumb, protect them from themselves
return;
}
this->maxThreads = maxThreads;
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
synchronized(&poolLock)
{
this->blockSize = blockSize;
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::setBlockSize(unsigned long blockSize)
void ThreadPool::AllocateThreads( unsigned long count )
{
try
{
if(blockSize <= 0)
{
// User tried something dumb, protect them from themselves
return;
}
try
{
if(pool.size() >= maxThreads)
{
return;
}
synchronized(&poolLock)
{
this->blockSize = blockSize;
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::AllocateThreads(unsigned long count)
{
try
{
if(pool.size() >= maxThreads)
{
return;
}
synchronized(&poolLock)
{
// Take the min of alloc size of maxThreads since we don't
// want anybody sneaking eaxtra threads in, greedy bastards.
count = std::min(count, maxThreads - pool.size());
synchronized(&poolLock)
{
// Take the min of alloc size of maxThreads since we don't
// want anybody sneaking eaxtra threads in, greedy bastards.
count = std::min(count, maxThreads - pool.size());
// Each time we create a thread we increment the free Threads
// counter, but before we call start so that the Thread doesn't
// get ahead of us.
for(unsigned long i = 0; i < count; ++i)
{
pool.push_back(new PooledThread(this));
pool.back()->setPooledThreadListener(this);
freeThreads++;
pool.back()->start();
}
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
// Each time we create a thread we increment the free Threads
// counter, but before we call start so that the Thread doesn't
// get ahead of us.
for(unsigned long i = 0; i < count; ++i)
{
pool.push_back(new PooledThread(this));
pool.back()->setPooledThreadListener(this);
freeThreads++;
pool.back()->start();
}
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::onTaskStarted(PooledThread* thread)
void ThreadPool::onTaskStarted( PooledThread* thread )
{
try
{
synchronized(&poolLock)
{
freeThreads--;
try
{
synchronized(&poolLock)
{
freeThreads--;
// Now that this callback has decremented the free threads coutner
// let check if there is any outstanding work to be done and no
// threads to handle it. This could happen if the QueueTask
// method was called successively without any of the PooledThreads
// having a chance to wake up and service the queue. This would
// cause the number of Task to exceed the number of free threads
// once the Threads got a chance to wake up and service the queue
if(freeThreads == 0 && !queue.empty())
{
// Allocate a new block of threads
AllocateThreads(blockSize);
}
}
// Now that this callback has decremented the free threads coutner
// let check if there is any outstanding work to be done and no
// threads to handle it. This could happen if the QueueTask
// method was called successively without any of the PooledThreads
// having a chance to wake up and service the queue. This would
// cause the number of Task to exceed the number of free threads
// once the Threads got a chance to wake up and service the queue
if(freeThreads == 0 && !queue.empty())
{
// Allocate a new block of threads
AllocateThreads(blockSize);
}
}
//LOGCMS_DEBUG(logger, "ThreadPool::onTaskStarted:");
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
//LOGCMS_DEBUG(logger, "ThreadPool::onTaskStarted:");
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ThreadPool::onTaskCompleted(PooledThread* thread)
void ThreadPool::onTaskCompleted( PooledThread* thread )
{
try
{
synchronized(&poolLock)
{
freeThreads++;
}
try
{
synchronized(&poolLock)
{
freeThreads++;
}
//LOGCMS_DEBUG(logger, "ThreadPool::onTaskCompleted: ");
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
//LOGCMS_DEBUG(logger, "ThreadPool::onTaskCompleted: ");
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
@ -313,32 +319,32 @@ void ThreadPool::onTaskException(
PooledThread* thread,
exceptions::ActiveMQException& ex)
{
//LOGCMS_DEBUG(logger, "ThreadPool::onTaskException: ");
//LOGCMS_DEBUG(logger, "ThreadPool::onTaskException: ");
try
{
synchronized(&poolLock)
{
// Delete the thread that had the exception and start a new
// one to take its place.
freeThreads--;
try
{
synchronized(&poolLock)
{
// Delete the thread that had the exception and start a new
// one to take its place.
freeThreads--;
std::vector<PooledThread*>::iterator itr =
std::find(pool.begin(), pool.end(), thread);
std::vector<PooledThread*>::iterator itr =
std::find(pool.begin(), pool.end(), thread);
if(itr != pool.end())
{
pool.erase(itr);
}
if(itr != pool.end())
{
pool.erase(itr);
}
// Bye-Bye Thread Object
delete thread;
// Bye-Bye Thread Object
delete thread;
// Now allocate a replacement
AllocateThreads(1);
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
// Now allocate a replacement
AllocateThreads(1);
}
}
AMQ_CATCH_RETHROW( exceptions::ActiveMQException )
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}

View File

@ -30,209 +30,202 @@
namespace activemq{
namespace concurrent{
/**
* Defines a Thread Pool object that implements the functionality
* of pooling threads to perform user tasks. The Thread Poll has
* max size that it will grow to. The thread pool allocates threads
* in blocks. When there are no waiting worker threads and a task
* is queued then a new batch is allocated. The user can specify
* the size of the blocks, otherwise a default value is used.
* <P>
* When the user queues a task they must also queue a listner to
* be notified when the task has completed, this provides the user
* with a mechanism to know when a task object can be freed.
* <P>
* To have the Thread Pool perform a task, the user enqueue's an
* object that implements the <code>Runnable</code> insterface and
* one of the worker threads will executing it in its thread context.
*/
class ThreadPool : public PooledThreadListener
{
public:
/**
* Defines a Thread Pool object that implements the functionality
* of pooling threads to perform user tasks. The Thread Poll has
* max size that it will grow to. The thread pool allocates threads
* in blocks. When there are no waiting worker threads and a task
* is queued then a new batch is allocated. The user can specify
* the size of the blocks, otherwise a default value is used.
* <P>
* When the user queues a task they must also queue a listner to
* be notified when the task has completed, this provides the user
* with a mechanism to know when a task object can be freed.
* <P>
* To have the Thread Pool perform a task, the user enqueue's an
* object that implements the <code>Runnable</code> insterface and
* one of the worker threads will executing it in its thread context.
*/
class ThreadPool : public PooledThreadListener
{
public:
// Constants
static const size_t DEFAULT_MAX_POOL_SIZE = 10;
static const size_t DEFAULT_MAX_BLOCK_SIZE = 3;
// Constants
static const size_t DEFAULT_MAX_POOL_SIZE = 10;
static const size_t DEFAULT_MAX_BLOCK_SIZE = 3;
// Types
typedef std::pair<Runnable*, TaskListener*> Task;
// Types
typedef std::pair<Runnable*, TaskListener*> Task;
private:
private:
// Vector of threads that this object has created for its pool.
std::vector< PooledThread* > pool;
// Queue of Task that are in need of completion
util::Queue<Task> queue;
// Max number of Threads this Pool can contian
unsigned long maxThreads;
// Max number of tasks that can be allocated at a time
unsigned long blockSize;
// boolean flag use to indocate that this object is shutting down.
bool shutdown;
// Count of threads that are currently free to perfom some work.
unsigned long freeThreads;
// Mutex for locking operations that affect the pool.
Mutex poolLock;
// Vector of threads that this object has created for its pool.
std::vector< PooledThread* > pool;
// Logger Init
LOGCMS_DECLARE(logger);
LOGCMS_DECLARE(marker);
// Queue of Task that are in need of completion
util::Queue<Task> queue;
private: // Statics
// Max number of Threads this Pool can contian
unsigned long maxThreads;
// Max number of tasks that can be allocated at a time
unsigned long blockSize;
// boolean flag use to indocate that this object is shutting down.
bool shutdown;
// Count of threads that are currently free to perfom some work.
unsigned long freeThreads;
// Mutex for locking operations that affect the pool.
Mutex poolLock;
// Logger Init
LOGCMS_DECLARE(logger);
LOGCMS_DECLARE(marker);
private: // Statics
// The singleton instance of this class
static ThreadPool instance;
// The singleton instance of this class
static ThreadPool instance;
public:
public:
/**
* Constructor
*/
ThreadPool(void);
ThreadPool(void);
virtual ~ThreadPool(void);
/**
* Destructor
*/
virtual ~ThreadPool(void);
/**
* Queue a task to be completed by one of the Pooled Threads.
* tasks are serviced as soon as a <code>PooledThread</code>
* is available to run it.
* @param object that derives from Runnable
* @throws ActiveMQException
*/
virtual void queueTask(Task task)
throw ( exceptions::ActiveMQException );
/**
* Queue a task to be completed by one of the Pooled Threads.
* tasks are serviced as soon as a <code>PooledThread</code>
* is available to run it.
* @param object that derives from Runnable
* @throws ActiveMQException
*/
virtual void queueTask(Task task)
throw ( exceptions::ActiveMQException );
/**
* DeQueue a task to be completed by one of the Pooled Threads.
* A caller of this method will block until there is something
* in the tasks queue, therefore care must be taken when calling
* this function. Normally clients of ThreadPool don't use
* this, only the <code>PooledThread</code> objects owned by
* this ThreadPool.
* @return object that derives from Runnable
* @throws ActiveMQException
*/
virtual Task deQueueTask(void)
throw ( exceptions::ActiveMQException );
/**
* DeQueue a task to be completed by one of the Pooled Threads.
* A caller of this method will block until there is something
* in the tasks queue, therefore care must be taken when calling
* this function. Normally clients of ThreadPool don't use
* this, only the <code>PooledThread</code> objects owned by
* this ThreadPool.
* @return object that derives from Runnable
* @throws ActiveMQException
*/
virtual Task deQueueTask(void)
throw ( exceptions::ActiveMQException );
/**
* Returns the current number of Threads in the Pool, this is
* how many there are now, not how many are active or the max
* number that might exist.
* @return integer number of threads in existance.
*/
virtual unsigned long getPoolSize(void) const { return pool.size(); }
/**
* Returns the current backlog of items in the tasks queue, this
* is how much work is still waiting to get done.
* @return number of outstanding tasks.
*/
virtual unsigned long getBacklog(void) const { return queue.size(); }
/**
* Ensures that there is at least the specified number of Threads
* allocated to the pool. If the size is greater than the MAX
* number of threads in the pool, then only MAX threads are
* reservved. If the size is smaller than the number of threads
* currently in the pool, than nothing is done.
* @param number of threads to reserve.
*/
virtual void reserve( unsigned long size );
/**
* Get the Max Number of Threads this Pool can contain
* @return max size
*/
virtual unsigned long getMaxThreads(void) const { return maxThreads; }
/**
* Returns the current number of Threads in the Pool, this is
* how many there are now, not how many are active or the max
* number that might exist.
* @return integer number of threads in existance.
*/
virtual unsigned long getPoolSize(void) const { return pool.size(); }
/**
* Sets the Max number of threads this pool can contian.
* if this value is smaller than the current size of the
* pool nothing is done.
*/
virtual void setMaxThreads( unsigned long maxThreads );
/**
* Returns the current backlog of items in the tasks queue, this
* is how much work is still waiting to get done.
* @return number of outstanding tasks.
*/
virtual unsigned long getBacklog(void) const { return queue.size(); }
/**
* Gets the Max number of threads that can be allocated at a time
* when new threads are needed.
* @return max Thread Block Size
*/
virtual unsigned long getBlockSize(void) const { return blockSize; }
/**
* Ensures that there is at least the specified number of Threads
* allocated to the pool. If the size is greater than the MAX
* number of threads in the pool, then only MAX threads are
* reservved. If the size is smaller than the number of threads
* currently in the pool, than nothing is done.
* @param number of threads to reserve.
*/
virtual void reserve(unsigned long size);
/**
* Sets the Max number of Threads that can be allocated at a time
* when the Thread Pool determines that more Threads are needed.
* @param Max Thread Block Size
*/
virtual void setBlockSize( unsigned long blockSize );
/**
* Get the Max Number of Threads this Pool can contain
* @return max size
*/
virtual unsigned long getMaxThreads(void) const { return maxThreads; }
/**
* Sets the Max number of threads this pool can contian.
* if this value is smaller than the current size of the
* pool nothing is done.
*/
virtual void setMaxThreads(unsigned long maxThreads);
/**
* Gets the Max number of threads that can be allocated at a time
* when new threads are needed.
* @return max Thread Block Size
*/
virtual unsigned long getBlockSize(void) const { return blockSize; }
/**
* Sets the Max number of Threads that can be allocated at a time
* when the Thread Pool determines that more Threads are needed.
* @param Max Thread Block Size
*/
virtual void setBlockSize(unsigned long blockSize);
/**
* Returns the current number of available threads in the pool, threads
* that are performing a user task are considered unavailable. This value
* could change immeadiately after calling as Threads could finish right
* after and be available again. This is informational only.
* @return totoal free threads
*/
virtual unsigned long getFreeThreadCount(void) const { return freeThreads; }
/**
* Returns the current number of available threads in the pool, threads
* that are performing a user task are considered unavailable. This value
* could change immeadiately after calling as Threads could finish right
* after and be available again. This is informational only.
* @return totoal free threads
*/
virtual unsigned long getFreeThreadCount(void) const { return freeThreads; }
public: // PooledThreadListener Callbacks
public: // PooledThreadListener Callbacks
/**
* Called by a pooled thread when it is about to begin
* executing a new task. This will decrement the available
* threads counter so that this object knows when there are
* no more free threads and must create new ones.
* @param Pointer to the Pooled Thread that is making this call
*/
virtual void onTaskStarted(PooledThread* thread);
/**
* Called by a pooled thread when it is about to begin
* executing a new task. This will decrement the available
* threads counter so that this object knows when there are
* no more free threads and must create new ones.
* @param Pointer to the Pooled Thread that is making this call
*/
virtual void onTaskStarted( PooledThread* thread );
/**
* Called by a pooled thread when it has completed a task
* and is going back to waiting for another task to run,
* this will increment the free threads counter.
* @param Pointer the the Pooled Thread that is making this call.
*/
virtual void onTaskCompleted(PooledThread* thread);
/**
* Called by a pooled thread when it has completed a task
* and is going back to waiting for another task to run,
* this will increment the free threads counter.
* @param Pointer the the Pooled Thread that is making this call.
*/
virtual void onTaskCompleted( PooledThread* thread );
/**
* Called by a pooled thread when it has encountered an exception
* while running a user task, after receiving this notification
* the callee should assume that the PooledThread is now no longer
* running.
* @param Pointer to the Pooled Thread that is making this call
* @param The Exception that occured.
*/
virtual void onTaskException(PooledThread* thread,
exceptions::ActiveMQException& ex);
/**
* Called by a pooled thread when it has encountered an exception
* while running a user task, after receiving this notification
* the callee should assume that the PooledThread is now no longer
* running.
* @param Pointer to the Pooled Thread that is making this call
* @param The Exception that occured.
*/
virtual void onTaskException( PooledThread* thread,
exceptions::ActiveMQException& ex);
public: // Statics
public: // Statics
/**
* Return the one and only Thread Pool instance.
* @return The Thread Pool Pointer
*/
static ThreadPool* getInstance(void) { return &instance; }
/**
* Return the one and only Thread Pool instance.
* @return The Thread Pool Pointer
*/
static ThreadPool* getInstance(void) { return &instance; }
private:
private:
/**
* Allocates the requested ammount of Threads, won't exceed
* <code>maxThreads</code>.
* @param the number of threads to create
*/
void AllocateThreads(unsigned long count);
/**
* Allocates the requested ammount of Threads, won't exceed
* <code>maxThreads</code>.
* @param the number of threads to create
*/
void AllocateThreads( unsigned long count );
};
};
}}

View File

@ -72,6 +72,20 @@ namespace connector{
*/
virtual std::string getClientId(void) const = 0;
/**
* Gets the Username for this connection, if this
* connection has been closed, then this method returns ""
* @return Username String
*/
virtual std::string getUsername(void) const = 0;
/**
* Gets the Password for this connection, if this
* connection has been closed, then this method returns ""
* @return Password String
*/
virtual std::string getPassword(void) const = 0;
/**
* Gets a reference to the Transport that this connection
* is using.
@ -88,7 +102,7 @@ namespace connector{
* @throws ConnectorException
*/
virtual SessionInfo* createSession(
cms::Session::AcknowledgeMode ackMode)
cms::Session::AcknowledgeMode ackMode )
throw( ConnectorException ) = 0;
/**
@ -99,9 +113,9 @@ namespace connector{
* @throws ConnectorException
*/
virtual ConsumerInfo* createConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& selector = "")
const std::string& selector = "" )
throw ( ConnectorException ) = 0;
/**
@ -116,11 +130,11 @@ namespace connector{
* @throws ConnectorException
*/
virtual ConsumerInfo* createDurableConsumer(
cms::Topic* topic,
const cms::Topic* topic,
SessionInfo* session,
const std::string& name,
const std::string& selector = "",
bool noLocal = false)
bool noLocal = false )
throw ( ConnectorException ) = 0;
/**
@ -131,8 +145,8 @@ namespace connector{
* @throws ConnectorException
*/
virtual ProducerInfo* createProducer(
cms::Destination* destination,
SessionInfo* session)
const cms::Destination* destination,
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -142,8 +156,8 @@ namespace connector{
* @return a newly created Topic Object
* @throws ConnectorException
*/
virtual cms::Topic* createTopic(const std::string& name,
SessionInfo* session)
virtual cms::Topic* createTopic( const std::string& name,
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -153,8 +167,8 @@ namespace connector{
* @return a newly created Queue Object
* @throws ConnectorException
*/
virtual cms::Queue* createQueue(const std::string& name,
SessionInfo* session)
virtual cms::Queue* createQueue( const std::string& name,
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -165,7 +179,7 @@ namespace connector{
* @throws ConnectorException
*/
virtual cms::TemporaryTopic* createTemporaryTopic(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -176,7 +190,7 @@ namespace connector{
* @throws ConnectorException
*/
virtual cms::TemporaryQueue* createTemporaryQueue(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -185,7 +199,7 @@ namespace connector{
* @param Producer Info for the sender of this message
* @throws ConnectorException
*/
virtual void send(cms::Message* message, ProducerInfo* producerInfo)
virtual void send( cms::Message* message, ProducerInfo* producerInfo )
throw ( ConnectorException ) = 0;
/**
@ -194,8 +208,8 @@ namespace connector{
* @param Producer Info for the sender of this message
* @throws ConnectorException
*/
virtual void send(std::list<cms::Message*>& messages,
ProducerInfo* producerInfo)
virtual void send( std::list<cms::Message*>& messages,
ProducerInfo* producerInfo)
throw ( ConnectorException ) = 0;
/**
@ -203,9 +217,9 @@ namespace connector{
* @param An ActiveMQMessage to Ack.
* @throws ConnectorException
*/
virtual void acknowledge(const SessionInfo* session,
const cms::Message* message,
AckType ackType = ConsumedAck)
virtual void acknowledge( const SessionInfo* session,
const cms::Message* message,
AckType ackType = ConsumedAck)
throw ( ConnectorException ) = 0;
/**
@ -214,7 +228,7 @@ namespace connector{
* @throws ConnectorException
*/
virtual TransactionInfo* startTransaction(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -223,8 +237,8 @@ namespace connector{
* @param Session Information
* @throws ConnectorException
*/
virtual void commit(TransactionInfo* transaction,
SessionInfo* session)
virtual void commit( TransactionInfo* transaction,
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -233,8 +247,8 @@ namespace connector{
* @param Session Information
* @throws ConnectorException
*/
virtual void rollback(TransactionInfo* transaction,
SessionInfo* session)
virtual void rollback( TransactionInfo* transaction,
SessionInfo* session )
throw ( ConnectorException ) = 0;
/**
@ -245,7 +259,7 @@ namespace connector{
*/
virtual cms::Message* createMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException ) = 0;
/**
@ -256,7 +270,7 @@ namespace connector{
*/
virtual cms::BytesMessage* createBytesMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException ) = 0;
/**
@ -267,7 +281,7 @@ namespace connector{
*/
virtual cms::TextMessage* createTextMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException ) = 0;
/**
@ -278,7 +292,7 @@ namespace connector{
*/
virtual cms::MapMessage* createMapMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException ) = 0;
/**
@ -286,7 +300,7 @@ namespace connector{
* @param name of the Subscription
* @throws ConnectorException
*/
virtual void unsubscribe(const std::string& name)
virtual void unsubscribe( const std::string& name )
throw ( ConnectorException ) = 0;
/**
@ -302,14 +316,14 @@ namespace connector{
* @param listener the observer.
*/
virtual void setConsumerMessageListener(
ConsumerMessageListener* listener) = 0;
ConsumerMessageListener* listener ) = 0;
/**
* Sets the Listner of exceptions for this connector
* @param ExceptionListener the observer.
*/
virtual void setExceptionListener(
cms::ExceptionListener* listener) = 0;
cms::ExceptionListener* listener ) = 0;
};
}}

View File

@ -22,42 +22,44 @@
namespace activemq{
namespace connector{
/*
* Signals that an Connector exception of some sort has occurred.
*/
class ConnectorException : public exceptions::ActiveMQException
{
public:
/*
* Signals that an Connector exception of some sort has occurred.
*/
class ConnectorException : public exceptions::ActiveMQException
{
public:
ConnectorException() {}
ConnectorException( const exceptions::ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
ConnectorException( const ConnectorException& ex ){
*(exceptions::ActiveMQException*)this = ex;
}
ConnectorException(const char* file, const int lineNumber,
const char* msg, ...)
{
va_list vargs ;
va_start(vargs, msg) ;
buildMessage(msg, vargs) ;
ConnectorException() {}
ConnectorException( const exceptions::ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
ConnectorException( const ConnectorException& ex ){
*(exceptions::ActiveMQException*)this = ex;
}
ConnectorException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start( vargs, msg );
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark( file, lineNumber );
}
// Set the first mark for this exception.
setMark( file, lineNumber );
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual exceptions::ActiveMQException* clone() const{
return new ConnectorException( *this );
}
virtual ~ConnectorException() {}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual exceptions::ActiveMQException* clone() const{
return new ConnectorException( *this );
}
virtual ~ConnectorException() {}
};
};
}}

View File

@ -36,10 +36,11 @@ namespace connector{
/**
* Creates a connector
* @param The Properties that the new connector is configured with
* @param the Transport that the connector should use
*/
virtual Connector* createConnector(
const activemq::util::Properties& properties,
activemq::transport::Transport* transport) = 0;
activemq::transport::Transport* transport ) = 0;
};

View File

@ -31,25 +31,25 @@ ConnectorFactoryMap* ConnectorFactoryMap::getInstance(void)
}
////////////////////////////////////////////////////////////////////////////////
void ConnectorFactoryMap::registerConnectorFactory(const std::string& name,
ConnectorFactory* factory)
void ConnectorFactoryMap::registerConnectorFactory( const std::string& name,
ConnectorFactory* factory )
{
factoryMap[name] = factory;
}
////////////////////////////////////////////////////////////////////////////////
void ConnectorFactoryMap::unregisterConnectorFactory(const std::string& name)
void ConnectorFactoryMap::unregisterConnectorFactory( const std::string& name )
{
factoryMap.erase(name);
factoryMap.erase( name );
}
////////////////////////////////////////////////////////////////////////////////
ConnectorFactory* ConnectorFactoryMap::lookup(const std::string& name)
ConnectorFactory* ConnectorFactoryMap::lookup( const std::string& name )
{
std::map<std::string, ConnectorFactory*>::const_iterator itr =
factoryMap.find(name);
factoryMap.find( name );
if(itr != factoryMap.end())
if( itr != factoryMap.end() )
{
return itr->second;
}
@ -60,14 +60,14 @@ ConnectorFactory* ConnectorFactoryMap::lookup(const std::string& name)
////////////////////////////////////////////////////////////////////////////////
std::size_t ConnectorFactoryMap::getFactoryNames(
std::vector<std::string>& factoryList)
std::vector<std::string>& factoryList )
{
std::map<std::string, ConnectorFactory*>::const_iterator itr =
factoryMap.begin();
for(; itr != factoryMap.end(); ++itr)
for( ; itr != factoryMap.end(); ++itr )
{
factoryList.insert(factoryList.end(), itr->first);
factoryList.insert( factoryList.end(), itr->first );
}
return factoryMap.size();

View File

@ -27,66 +27,66 @@
namespace activemq{
namespace connector{
/**
* Lookup Map for Connector Factories. Use the Connector name to
* find the associated factory. This class does not take ownership
* of the stored factories, they must be deallocated somewhere.
*/
class ConnectorFactoryMap
{
public:
/**
* Lookup Map for Connector Factories. Use the Connector name to
* find the associated factory. This class does not take ownership
* of the stored factories, they must be deallocated somewhere.
*/
class ConnectorFactoryMap
{
public:
/**
* Gets a singleton instance of this class.
*/
static ConnectorFactoryMap* getInstance(void);
/**
* Gets a singleton instance of this class.
*/
static ConnectorFactoryMap* getInstance(void);
/**
* Registers a new Connector Factory with this map
* @param name to associate the factory with
* @param factory to store.
*/
void registerConnectorFactory(const std::string& name,
ConnectorFactory* factory);
/**
* Registers a new Connector Factory with this map
* @param name to associate the factory with
* @param factory to store.
*/
void registerConnectorFactory( const std::string& name,
ConnectorFactory* factory );
/**
* Unregisters a Connector Factory with this map
* @param name of the factory to remove
*/
void unregisterConnectorFactory(const std::string& name);
/**
* Unregisters a Connector Factory with this map
* @param name of the factory to remove
*/
void unregisterConnectorFactory( const std::string& name );
/**
* Lookup the named factory in the Map
* @param the factory name to lookup
* @return the factory assciated with the name, or NULL
*/
ConnectorFactory* lookup(const std::string& name);
/**
* Lookup the named factory in the Map
* @param the factory name to lookup
* @return the factory assciated with the name, or NULL
*/
ConnectorFactory* lookup( const std::string& name );
/**
* Fetch a list of factory names that this Map contains
* @param vector object to receive the list
* @returns count of factories.
*/
std::size_t getFactoryNames(std::vector<std::string>& factoryList);
/**
* Fetch a list of factory names that this Map contains
* @param vector object to receive the list
* @returns count of factories.
*/
std::size_t getFactoryNames( std::vector< std::string >& factoryList );
private:
private:
// Hidden Contrustor, prevents instantiation
ConnectorFactoryMap() {};
// Hidden Contrustor, prevents instantiation
ConnectorFactoryMap() {};
// Hidden Destructor.
virtual ~ConnectorFactoryMap() {};
// Hidden Destructor.
virtual ~ConnectorFactoryMap() {};
// Hidden Copy Constructore
ConnectorFactoryMap(const ConnectorFactoryMap& factoryMap);
// Hidden Copy Constructore
ConnectorFactoryMap( const ConnectorFactoryMap& factoryMap );
// Hidden Assignment operator
ConnectorFactoryMap operator=(const ConnectorFactoryMap& factoryMap);
// Hidden Assignment operator
ConnectorFactoryMap operator=( const ConnectorFactoryMap& factoryMap );
// Map of Factories
std::map<std::string, ConnectorFactory*> factoryMap;
// Map of Factories
std::map< std::string, ConnectorFactory* > factoryMap;
};
};
}}

View File

@ -59,9 +59,9 @@ namespace connector{
{
// UnRegister it in the map.
ConnectorFactoryMap::getInstance()->
unregisterConnectorFactory(name);
unregisterConnectorFactory( name );
if(manageLifetime)
if( manageLifetime )
{
delete factory;
}

View File

@ -14,10 +14,8 @@ namespace connector{
{
public:
/**
* Destructor
*/
virtual ~ConnectorResource() {}
};
}}

View File

@ -29,9 +29,6 @@ namespace connector{
{
public:
/**
* Destructor
*/
virtual ~ConsumerInfo(void) {}
/**

View File

@ -37,8 +37,10 @@ namespace connector{
* @param consumer the target consumer of the dispatch.
* @param msg the message to be dispatched.
*/
virtual void onConsumerMessage( ConsumerInfo* consumer,
virtual void onConsumerMessage(
ConsumerInfo* consumer,
core::ActiveMQMessage* msg ) = 0;
};
}}

View File

@ -28,9 +28,6 @@ namespace connector{
{
public:
/**
* Destructor
*/
virtual ~SessionInfo(void) {}
/**

View File

@ -28,9 +28,6 @@ namespace connector{
{
public:
/**
* Destructor
*/
virtual ~TransactionInfo(void) {}
/**

View File

@ -33,7 +33,7 @@ namespace stomp{
{
public:
virtual ~StompCommandListener(void) {}
virtual ~StompCommandListener(void) {}
/**
* Process the Stomp Command

View File

@ -35,14 +35,14 @@ StompCommandReader::StompCommandReader(void)
}
////////////////////////////////////////////////////////////////////////////////
StompCommandReader::StompCommandReader(InputStream* is)
StompCommandReader::StompCommandReader( InputStream* is )
{
inputStream = is;
}
////////////////////////////////////////////////////////////////////////////////
Command* StompCommandReader::readCommand(void)
throw (CommandIOException)
throw ( CommandIOException )
{
try
{
@ -70,53 +70,53 @@ Command* StompCommandReader::readCommand(void)
void StompCommandReader::readStompCommand( StompFrame& frame )
throw ( StompConnectorException )
{
while( true )
{
// Clean up the mess.
buffer.clear();
while( true )
{
// Clean up the mess.
buffer.clear();
// Read the command;
readStompHeaderLine();
// Read the command;
readStompHeaderLine();
// Ignore all white space before the command.
int offset=-1;
for( size_t ix = 0; ix < buffer.size()-1; ++ix )
{
// Find the first non space character
char b = buffer[ix];
// Find the first non space character
char b = buffer[ix];
switch ( b )
{
case '\n':
case '\t':
case '\r':
break;
default:
offset = ix;
break;
case '\n':
case '\t':
case '\r':
break;
default:
offset = ix;
break;
}
if( offset != -1 )
{
break;
}
if( offset != -1 )
{
break;
}
}
if( offset >= 0 )
{
// Set the command in the frame - copy the memory.
frame.setCommand( reinterpret_cast<char*>(&buffer[offset]) );
break;
}
}
if( offset >= 0 )
{
// Set the command in the frame - copy the memory.
frame.setCommand( reinterpret_cast<char*>(&buffer[offset]) );
break;
}
}
// Clean up the mess.
buffer.clear();
}
////////////////////////////////////////////////////////////////////////////////
void StompCommandReader::readStompHeaders( StompFrame& frame )
throw (StompConnectorException)
throw ( StompConnectorException )
{
// Read the command;
bool endOfHeaders = false;
@ -173,7 +173,7 @@ void StompCommandReader::readStompHeaders( StompFrame& frame )
////////////////////////////////////////////////////////////////////////////////
int StompCommandReader::readStompHeaderLine(void)
throw (StompConnectorException)
throw ( StompConnectorException )
{
int count = 0;
@ -223,10 +223,10 @@ void StompCommandReader::readStompBody( StompFrame& frame )
content_length = strtoul(
length.c_str(),
&stopped_string,
10);
10 );
}
if(content_length != 0)
if( content_length != 0 )
{
// For this case its assumed that content length indicates how
// much to read. We reserve space in the buffer for it to
@ -271,7 +271,7 @@ void StompCommandReader::readStompBody( StompFrame& frame )
content_length++;
if(byte != '\0')
if( byte != '\0' )
{
continue;
}
@ -283,7 +283,7 @@ void StompCommandReader::readStompBody( StompFrame& frame )
if( content_length != 0 )
{
char* cpyBody = new char[content_length];
memcpy(cpyBody, &buffer[0], content_length);
memcpy( cpyBody, &buffer[0], content_length );
// Set the body contents in the frame - copy the memory
frame.setBody( cpyBody, content_length );
@ -294,8 +294,8 @@ void StompCommandReader::readStompBody( StompFrame& frame )
}
////////////////////////////////////////////////////////////////////////////////
int StompCommandReader::read(unsigned char* buffer, int count)
throw(io::IOException)
int StompCommandReader::read( unsigned char* buffer, int count )
throw( io::IOException )
{
if( inputStream == NULL )
{
@ -312,9 +312,9 @@ int StompCommandReader::read(unsigned char* buffer, int count)
// pause in hopes that some more data will show up.
while( true )
{
head += inputStream->read(&buffer[head], count - head);
head += inputStream->read( &buffer[head], count - head );
if(head == count)
if( head == count )
{
return count;
}
@ -325,7 +325,7 @@ int StompCommandReader::read(unsigned char* buffer, int count)
}
////////////////////////////////////////////////////////////////////////////////
unsigned char StompCommandReader::readByte(void) throw(io::IOException)
unsigned char StompCommandReader::readByte(void) throw( io::IOException )
{
if( inputStream == NULL )
{
@ -335,6 +335,6 @@ unsigned char StompCommandReader::readByte(void) throw(io::IOException)
}
unsigned char c = 0;
inputStream->read(&c, 1);
inputStream->read( &c, 1 );
return c;
}

View File

@ -53,7 +53,7 @@ namespace stomp{
/**
* Deafult Constructor
*/
StompCommandReader( void );
StompCommandReader( void );
/**
* Constructor.
@ -61,24 +61,21 @@ namespace stomp{
*/
StompCommandReader( io::InputStream* is );
/**
* Destructor
*/
virtual ~StompCommandReader(void) {}
virtual ~StompCommandReader(void) {}
/**
* Reads a command from the given input stream.
* @return The next command available on the stream.
* @throws CommandIOException if a problem occurs during the read.
*/
virtual transport::Command* readCommand( void )
virtual transport::Command* readCommand(void)
throw ( transport::CommandIOException );
/**
* Sets the target input stream.
* @param Target Input Stream
*/
virtual void setInputStream(io::InputStream* is){
virtual void setInputStream( io::InputStream* is ){
inputStream = is;
}
@ -86,7 +83,7 @@ namespace stomp{
* Gets the target input stream.
* @return Target Input Stream
*/
virtual io::InputStream* getInputStream( void ){
virtual io::InputStream* getInputStream(void){
return inputStream;
}
@ -97,7 +94,7 @@ namespace stomp{
* @return The number of bytes read.
* @throws IOException thrown if an error occurs.
*/
virtual int read(unsigned char* buffer, int count)
virtual int read( unsigned char* buffer, int count )
throw( io::IOException );
/**
@ -130,7 +127,7 @@ namespace stomp{
* @return number of bytes read, zero if there was a problem.
* @throws StompConnectorException
*/
int readStompHeaderLine( void ) throw ( StompConnectorException );
int readStompHeaderLine(void) throw ( StompConnectorException );
/**
* Reads the Stomp Body from the Wire and store it in the frame.

View File

@ -35,7 +35,7 @@ StompCommandWriter::StompCommandWriter(void)
}
////////////////////////////////////////////////////////////////////////////////
StompCommandWriter::StompCommandWriter(OutputStream* os)
StompCommandWriter::StompCommandWriter( OutputStream* os )
{
outputStream = os;
}
@ -103,8 +103,8 @@ void StompCommandWriter::writeCommand( const Command* command )
}
////////////////////////////////////////////////////////////////////////////////
void StompCommandWriter::write(const unsigned char* buffer, int count)
throw(IOException)
void StompCommandWriter::write( const unsigned char* buffer, int count )
throw( IOException )
{
if( outputStream == NULL )
{
@ -117,7 +117,7 @@ void StompCommandWriter::write(const unsigned char* buffer, int count)
}
////////////////////////////////////////////////////////////////////////////////
void StompCommandWriter::writeByte(unsigned char v) throw(IOException)
void StompCommandWriter::writeByte( unsigned char v ) throw( IOException )
{
if( outputStream == NULL )
{
@ -130,8 +130,8 @@ void StompCommandWriter::writeByte(unsigned char v) throw(IOException)
}
////////////////////////////////////////////////////////////////////////////////
void StompCommandWriter::write(const char* buffer, int count)
throw(io::IOException)
void StompCommandWriter::write( const char* buffer, int count )
throw( io::IOException )
{
write(reinterpret_cast<const unsigned char*>(buffer), count);
write( reinterpret_cast<const unsigned char*>( buffer ), count );
}

View File

@ -48,7 +48,7 @@ namespace stomp{
/**
* Default Constructor
*/
StompCommandWriter(void);
StompCommandWriter(void);
/**
* Constructor.
@ -56,15 +56,12 @@ namespace stomp{
*/
StompCommandWriter( io::OutputStream* os );
/**
* Destructor
*/
virtual ~StompCommandWriter(void) {}
virtual ~StompCommandWriter(void) {}
/**
* Sets the target output stream.
*/
virtual void setOutputStream(io::OutputStream* os){
virtual void setOutputStream( io::OutputStream* os ){
outputStream = os;
}
@ -90,7 +87,7 @@ namespace stomp{
* @param count the number of bytes in the array to write.
* @throws IOException thrown if an error occurs.
*/
virtual void write(const unsigned char* buffer, int count)
virtual void write( const unsigned char* buffer, int count )
throw( io::IOException );
/**
@ -98,7 +95,7 @@ namespace stomp{
* @param v The value to be written.
* @throws IOException thrown if an error occurs.
*/
virtual void writeByte(unsigned char v) throw( io::IOException );
virtual void writeByte( unsigned char v ) throw( io::IOException );
private:
@ -108,7 +105,7 @@ namespace stomp{
* @param count the number of bytes in the array to write.
* @throws IOException thrown if an error occurs.
*/
virtual void write(const char* buffer, int count)
virtual void write( const char* buffer, int count )
throw( io::IOException );
};

View File

@ -52,7 +52,7 @@ StompConnector::StompConnector( Transport* transport,
const util::Properties& properties )
throw ( IllegalArgumentException )
{
if(transport == NULL)
if( transport == NULL )
{
throw IllegalArgumentException(
__FILE__, __LINE__,
@ -64,8 +64,8 @@ StompConnector::StompConnector( Transport* transport,
this->exceptionListener = NULL;
this->messageListener = NULL;
this->sessionManager = NULL;
this->nextProducerId = 0;
this->nextTransactionId = 0;
this->nextProducerId = 1;
this->nextTransactionId = 1;
this->properties.copy( &properties );
// Observe the transport for events.
@ -96,7 +96,7 @@ StompConnector::~StompConnector(void)
////////////////////////////////////////////////////////////////////////////////
unsigned int StompConnector::getNextProducerId(void)
{
synchronized(&mutex)
synchronized( &mutex )
{
return nextProducerId++;
}
@ -107,7 +107,7 @@ unsigned int StompConnector::getNextProducerId(void)
////////////////////////////////////////////////////////////////////////////////
unsigned int StompConnector::getNextTransactionId(void)
{
synchronized(&mutex)
synchronized( &mutex )
{
return nextTransactionId++;
}
@ -138,7 +138,7 @@ void StompConnector::addCmdListener(
void StompConnector::removeCmdListener(
commands::CommandConstants::CommandId commandId )
{
cmdListenerMap.erase(commandId);
cmdListenerMap.erase( commandId );
}
////////////////////////////////////////////////////////////////////////////////
@ -199,7 +199,7 @@ void StompConnector::connect(void)
ConnectCommand cmd;
// Encode User Name and Password and Client ID
string login = getLogin();
string login = getUsername();
if( login.length() > 0 ){
cmd.setLogin( login );
}
@ -216,6 +216,8 @@ void StompConnector::connect(void)
if( dynamic_cast< ExceptionResponse* >( response ) != NULL )
{
delete response;
throw StompConnectorException(
__FILE__, __LINE__,
"StompConnector::connect - Failed on Connect Request" );
@ -226,6 +228,8 @@ void StompConnector::connect(void)
if( connected == NULL )
{
delete response;
throw StompConnectorException(
__FILE__, __LINE__,
"StompConnector::connect - "
@ -281,7 +285,7 @@ void StompConnector::disconnect(void)
////////////////////////////////////////////////////////////////////////////////
SessionInfo* StompConnector::createSession(
cms::Session::AcknowledgeMode ackMode)
cms::Session::AcknowledgeMode ackMode )
throw( ConnectorException )
{
try
@ -296,9 +300,9 @@ SessionInfo* StompConnector::createSession(
////////////////////////////////////////////////////////////////////////////////
ConsumerInfo* StompConnector::createConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& selector)
const std::string& selector )
throw ( ConnectorException )
{
try
@ -314,11 +318,11 @@ ConsumerInfo* StompConnector::createConsumer(
////////////////////////////////////////////////////////////////////////////////
ConsumerInfo* StompConnector::createDurableConsumer(
cms::Topic* topic,
const cms::Topic* topic,
SessionInfo* session,
const std::string& name,
const std::string& selector,
bool noLocal)
bool noLocal )
throw ( ConnectorException )
{
try
@ -334,8 +338,8 @@ ConsumerInfo* StompConnector::createDurableConsumer(
////////////////////////////////////////////////////////////////////////////////
ProducerInfo* StompConnector::createProducer(
cms::Destination* destination,
SessionInfo* session)
const cms::Destination* destination,
SessionInfo* session )
throw ( ConnectorException )
{
try
@ -355,30 +359,30 @@ ProducerInfo* StompConnector::createProducer(
}
////////////////////////////////////////////////////////////////////////////////
cms::Topic* StompConnector::createTopic(const std::string& name,
SessionInfo* session)
cms::Topic* StompConnector::createTopic( const std::string& name,
SessionInfo* session )
throw ( ConnectorException )
{
try
{
enforceConnected();
return new StompTopic(name);
return new StompTopic( name );
}
AMQ_CATCH_RETHROW( ConnectorException )
AMQ_CATCHALL_THROW( ConnectorException );
}
////////////////////////////////////////////////////////////////////////////////
cms::Queue* StompConnector::createQueue(const std::string& name,
SessionInfo* session)
cms::Queue* StompConnector::createQueue( const std::string& name,
SessionInfo* session )
throw ( ConnectorException )
{
try
{
enforceConnected();
return new StompQueue(name);
return new StompQueue( name );
}
AMQ_CATCH_RETHROW( ConnectorException )
AMQ_CATCHALL_THROW( ConnectorException );
@ -386,7 +390,7 @@ cms::Queue* StompConnector::createQueue(const std::string& name,
////////////////////////////////////////////////////////////////////////////////
cms::TemporaryTopic* StompConnector::createTemporaryTopic(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException )
{
try
@ -401,7 +405,7 @@ cms::TemporaryTopic* StompConnector::createTemporaryTopic(
////////////////////////////////////////////////////////////////////////////////
cms::TemporaryQueue* StompConnector::createTemporaryQueue(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException )
{
try
@ -416,7 +420,7 @@ cms::TemporaryQueue* StompConnector::createTemporaryQueue(
////////////////////////////////////////////////////////////////////////////////
void StompConnector::send(cms::Message* message,
ProducerInfo* producerInfo)
ProducerInfo* producerInfo )
throw ( ConnectorException )
{
try
@ -434,7 +438,7 @@ void StompConnector::send(cms::Message* message,
"Message is not a valid stomp type.");
}
if( session->getAckMode() == cms::Session::Transactional )
if( session->getAckMode() == cms::Session::SESSION_TRANSACTED )
{
StompCommand* stompCommand =
dynamic_cast< StompCommand* >( message );
@ -460,19 +464,19 @@ void StompConnector::send(cms::Message* message,
}
////////////////////////////////////////////////////////////////////////////////
void StompConnector::send(std::list<cms::Message*>& messages,
ProducerInfo* producerInfo)
void StompConnector::send( std::list<cms::Message*>& messages,
ProducerInfo* producerInfo )
throw ( ConnectorException )
{
try
{
enforceConnected();
list<cms::Message*>::const_iterator itr = messages.begin();
list< cms::Message* >::const_iterator itr = messages.begin();
for(; itr != messages.end(); ++itr)
for( ; itr != messages.end(); ++itr )
{
this->send(*itr, producerInfo);
this->send( *itr, producerInfo );
}
}
AMQ_CATCH_RETHROW( ConnectorException )
@ -491,7 +495,7 @@ void StompConnector::acknowledge( const SessionInfo* session,
// Auto to Stomp means don't do anything, so we drop it here
// for client acknowledge we have to send and ack.
if( session->getAckMode() == cms::Session::ClientAcknowledge )
if( session->getAckMode() == cms::Session::CLIENT_ACKNOWLEDGE )
{
AckCommand cmd;
@ -505,7 +509,7 @@ void StompConnector::acknowledge( const SessionInfo* session,
cmd.setMessageId( message->getCMSMessageId() );
if( session->getAckMode() == cms::Session::Transactional )
if( session->getAckMode() == cms::Session::SESSION_TRANSACTED )
{
cmd.setTransactionId(
Integer::toString(
@ -521,7 +525,7 @@ void StompConnector::acknowledge( const SessionInfo* session,
////////////////////////////////////////////////////////////////////////////////
TransactionInfo* StompConnector::startTransaction(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException )
{
try
@ -548,8 +552,8 @@ TransactionInfo* StompConnector::startTransaction(
}
////////////////////////////////////////////////////////////////////////////////
void StompConnector::commit(TransactionInfo* transaction,
SessionInfo* session)
void StompConnector::commit( TransactionInfo* transaction,
SessionInfo* session )
throw ( ConnectorException )
{
try
@ -568,8 +572,8 @@ void StompConnector::commit(TransactionInfo* transaction,
}
////////////////////////////////////////////////////////////////////////////////
void StompConnector::rollback(TransactionInfo* transaction,
SessionInfo* session)
void StompConnector::rollback( TransactionInfo* transaction,
SessionInfo* session )
throw ( ConnectorException )
{
try
@ -590,7 +594,7 @@ void StompConnector::rollback(TransactionInfo* transaction,
////////////////////////////////////////////////////////////////////////////////
cms::Message* StompConnector::createMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException )
{
try
@ -614,7 +618,7 @@ cms::Message* StompConnector::createMessage(
////////////////////////////////////////////////////////////////////////////////
cms::BytesMessage* StompConnector::createBytesMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException )
{
try
@ -638,7 +642,7 @@ cms::BytesMessage* StompConnector::createBytesMessage(
////////////////////////////////////////////////////////////////////////////////
cms::TextMessage* StompConnector::createTextMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException )
{
try
@ -662,7 +666,7 @@ cms::TextMessage* StompConnector::createTextMessage(
////////////////////////////////////////////////////////////////////////////////
cms::MapMessage* StompConnector::createMapMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException )
{
try
@ -676,7 +680,7 @@ cms::MapMessage* StompConnector::createMapMessage(
}
////////////////////////////////////////////////////////////////////////////////
void StompConnector::unsubscribe(const std::string& name)
void StompConnector::unsubscribe( const std::string& name )
throw ( ConnectorException )
{
try
@ -723,7 +727,7 @@ void StompConnector::onCommand( transport::Command* command )
{
StompCommand* stompCommand = dynamic_cast< StompCommand* >(command);
if(stompCommand == NULL)
if( stompCommand == NULL )
{
fire( ConnectorException(
__FILE__, __LINE__,
@ -777,18 +781,21 @@ void StompConnector::onStompCommand( commands::StompCommand* command )
try
{
ErrorCommand* error =
dynamic_cast<ErrorCommand*>(command);
dynamic_cast<ErrorCommand*>( command );
if(error != NULL)
if( error != NULL )
{
fire( StompConnectorException(
__FILE__, __LINE__,
(string( "StompConnector::onStompCommand - " ) +
error->getErrorMessage() ).c_str() ) );
__FILE__, __LINE__,
( string( "StompConnector::onStompCommand - " ) +
error->getErrorMessage() ).c_str() ) );
// Shutdown
close();
}
// command is done here, delete it.
delete command;
}
AMQ_CATCH_RETHROW( StompConnectorException )
AMQ_CATCHALL_THROW( StompConnectorException );

View File

@ -29,6 +29,7 @@
#include <activemq/connector/stomp/StompCommandListener.h>
#include <activemq/connector/stomp/StompSessionManager.h>
#include <activemq/connector/stomp/commands/CommandConstants.h>
#include <activemq/core/ActiveMQConstants.h>
#include <activemq/exceptions/IllegalArgumentException.h>
namespace activemq{
@ -57,7 +58,7 @@ namespace stomp{
// Maps Command Ids to listener that are interested
typedef std::map< commands::CommandConstants::CommandId,
StompCommandListener*> CmdListenerMap;
StompCommandListener* > CmdListenerMap;
private:
@ -192,20 +193,30 @@ namespace stomp{
*/
virtual std::string getClientId(void) const {
return properties.getProperty(
commands::CommandConstants::toString(
commands::CommandConstants::HEADER_CLIENT_ID ), "" );
core::ActiveMQConstants::toString(
core::ActiveMQConstants::PARAM_CLIENTID ), "" );
}
virtual std::string getLogin(void) const {
/**
* Gets the Username for this connection, if this
* connection has been closed, then this method returns ""
* @return Username String
*/
virtual std::string getUsername(void) const {
return properties.getProperty(
commands::CommandConstants::toString(
commands::CommandConstants::HEADER_LOGIN ), "" );
core::ActiveMQConstants::toString(
core::ActiveMQConstants::PARAM_USERNAME ), "" );
}
/**
* Gets the Password for this connection, if this
* connection has been closed, then this method returns ""
* @return Password String
*/
virtual std::string getPassword(void) const {
return properties.getProperty(
commands::CommandConstants::toString(
commands::CommandConstants::HEADER_PASSWORD ), "" );
core::ActiveMQConstants::toString(
core::ActiveMQConstants::PARAM_PASSWORD ), "" );
}
/**
@ -215,7 +226,7 @@ namespace stomp{
* @throws InvalidStateException if the Transport is not set
*/
virtual transport::Transport& getTransport(void) const
throw (exceptions::InvalidStateException ) {
throw ( exceptions::InvalidStateException ) {
if( transport == NULL ) {
throw exceptions::InvalidStateException(
@ -234,7 +245,7 @@ namespace stomp{
* @throws ConnectorException
*/
virtual SessionInfo* createSession(
cms::Session::AcknowledgeMode ackMode)
cms::Session::AcknowledgeMode ackMode )
throw( ConnectorException );
/**
@ -245,9 +256,9 @@ namespace stomp{
* @throws ConnectorException
*/
virtual ConsumerInfo* createConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& selector = "")
const std::string& selector = "" )
throw ( ConnectorException );
/**
@ -262,11 +273,11 @@ namespace stomp{
* @throws ConnectorException
*/
virtual ConsumerInfo* createDurableConsumer(
cms::Topic* topic,
const cms::Topic* topic,
SessionInfo* session,
const std::string& name,
const std::string& selector = "",
bool noLocal = false)
bool noLocal = false )
throw ( ConnectorException );
/**
@ -277,7 +288,7 @@ namespace stomp{
* @throws ConnectorException
*/
virtual ProducerInfo* createProducer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session)
throw ( ConnectorException );
@ -311,7 +322,7 @@ namespace stomp{
* @throws ConnectorException
*/
virtual cms::TemporaryTopic* createTemporaryTopic(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException );
/**
@ -322,7 +333,7 @@ namespace stomp{
* @throws ConnectorException
*/
virtual cms::TemporaryQueue* createTemporaryQueue(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException );
/**
@ -351,7 +362,7 @@ namespace stomp{
*/
virtual void acknowledge( const SessionInfo* session,
const cms::Message* message,
AckType ackType)
AckType ackType )
throw ( ConnectorException );
/**
@ -360,7 +371,7 @@ namespace stomp{
* @throws ConnectorException
*/
virtual TransactionInfo* startTransaction(
SessionInfo* session)
SessionInfo* session )
throw ( ConnectorException );
/**
@ -369,8 +380,8 @@ namespace stomp{
* @param Session Information
* @throws ConnectorException
*/
virtual void commit(TransactionInfo* transaction,
SessionInfo* session)
virtual void commit( TransactionInfo* transaction,
SessionInfo* session )
throw ( ConnectorException );
/**
@ -379,8 +390,8 @@ namespace stomp{
* @param Session Information
* @throws ConnectorException
*/
virtual void rollback(TransactionInfo* transaction,
SessionInfo* session)
virtual void rollback( TransactionInfo* transaction,
SessionInfo* session )
throw ( ConnectorException );
/**
@ -391,7 +402,7 @@ namespace stomp{
*/
virtual cms::Message* createMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException );
/**
@ -402,7 +413,7 @@ namespace stomp{
*/
virtual cms::BytesMessage* createBytesMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException );
/**
@ -413,7 +424,7 @@ namespace stomp{
*/
virtual cms::TextMessage* createTextMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException );
/**
@ -424,7 +435,7 @@ namespace stomp{
*/
virtual cms::MapMessage* createMapMessage(
SessionInfo* session,
TransactionInfo* transaction)
TransactionInfo* transaction )
throw ( ConnectorException );
/**
@ -448,7 +459,7 @@ namespace stomp{
* @param listener the observer.
*/
virtual void setConsumerMessageListener(
ConsumerMessageListener* listener)
ConsumerMessageListener* listener )
{
this->messageListener = listener;
@ -463,7 +474,7 @@ namespace stomp{
* @param ExceptionListener the observer.
*/
virtual void setExceptionListener(
cms::ExceptionListener* listener)
cms::ExceptionListener* listener )
{
this->exceptionListener = listener;
}
@ -520,8 +531,8 @@ namespace stomp{
private:
unsigned int getNextProducerId( void );
unsigned int getNextTransactionId( void );
unsigned int getNextProducerId(void);
unsigned int getNextTransactionId(void);
// Check for Connected State and Throw an exception if not.
void enforceConnected( void ) throw ( ConnectorException );

View File

@ -40,9 +40,9 @@ namespace stomp{
StompConnectorException(const char* file, const int lineNumber,
const char* msg, ...)
{
va_list vargs ;
va_start(vargs, msg) ;
buildMessage(msg, vargs) ;
va_list vargs;
va_start( vargs, msg );
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark( file, lineNumber );
@ -56,6 +56,7 @@ namespace stomp{
virtual exceptions::ActiveMQException* clone() const{
return new StompConnectorException( *this );
}
virtual ~StompConnectorException() {}
};

View File

@ -31,10 +31,10 @@ using namespace activemq::connector::stomp;
////////////////////////////////////////////////////////////////////////////////
Connector* StompConnectorFactory::createConnector(
const activemq::util::Properties& properties,
activemq::transport::Transport* transport)
activemq::transport::Transport* transport )
{
return dynamic_cast<Connector*>(
new StompConnector(transport, properties));
new StompConnector( transport, properties ) );
}
////////////////////////////////////////////////////////////////////////////////
@ -43,7 +43,7 @@ ConnectorFactory& StompConnectorFactory::getInstance(void)
// Create a static instance of the registrar and return a reference to
// its internal instance of this class.
static ConnectorFactoryMapRegistrar registrar(
"stomp", new StompConnectorFactory());
"stomp", new StompConnectorFactory() );
return registrar.getFactory();
}

View File

@ -26,9 +26,6 @@ namespace stomp{
class StompConnectorFactory : public connector::ConnectorFactory
{
private:
public:
virtual ~StompConnectorFactory(void) {}
@ -39,7 +36,7 @@ namespace stomp{
*/
virtual Connector* createConnector(
const activemq::util::Properties& properties,
activemq::transport::Transport* transport);
activemq::transport::Transport* transport );
/**
* Returns an instance of this Factory by reference

View File

@ -45,7 +45,8 @@ namespace stomp{
consumerId = 0;
destination = NULL;
}
virtual ~StompConsumerInfo(void) { delete destination; }
virtual ~StompConsumerInfo(void) { delete destination; }
/**
* Gets this message consumer's message selector expression.

View File

@ -20,7 +20,7 @@
#include <string>
#include <cms/Destination.h>
#include <activemq/core/ActiveMQDestination.h>
namespace activemq{
namespace connector{
@ -32,26 +32,25 @@ namespace stomp{
* one of Topic, Queue, TemporaryTopic, or TemporaryQueue.
*/
template <typename T>
class StompDestination : public T
class StompDestination : public core::ActiveMQDestination<T>
{
private:
// Destination type
cms::Destination::DestinationType destType;
// Name of the Destination
std::string name;
public:
StompDestination(void) {}
/**
* Copy Consturctor
* @param CMS Dest to Copy, must be a compatible type
*/
StompDestination( const cms::Destination* source ) :
core::ActiveMQDestination<T>( source ) {}
/**
* Custom Constructor
* @param string destination name plus any params
* @param type of destination this represents.
*/
StompDestination( const std::string& name,
cms::Destination::DestinationType type )
{
this->name = name;
this->destType = type;
}
cms::Destination::DestinationType type ) :
core::ActiveMQDestination<T>( name, type ){}
virtual ~StompDestination(void) {}
@ -61,15 +60,7 @@ namespace stomp{
* @return name
*/
virtual std::string toProviderString(void) const {
return getPrefix() + name;
}
/**
* Retrieve the Destination Type for this Destination
* @return The Destination Type
*/
virtual cms::Destination::DestinationType getDestinationType(void) const {
return destType;
return getPrefix() + core::ActiveMQDestination<T>::getName();
}
/**
@ -78,16 +69,7 @@ namespace stomp{
* @return string name
*/
virtual std::string toString(void) const {
return name;
}
/**
* Copies the contents of the given Destinastion object to this one.
* @param source The source Destination object.
*/
virtual void copy( const cms::Destination& source ) {
this->destType = source.getDestinationType();
this->name = source.toString();
return core::ActiveMQDestination<T>::getName();
}
protected:

View File

@ -26,17 +26,27 @@ namespace activemq{
namespace connector{
namespace stomp{
class StompQueue : public StompDestination<cms::Queue>
class StompQueue : public StompDestination< cms::Queue >
{
public:
StompQueue(void) : StompDestination< cms::Queue >() {}
/**
* Copy Consturctor
* @param CMS Dest to Copy, must be a compatible type
*/
StompQueue( const cms::Destination* source ) :
StompDestination< cms::Queue >( source ) {}
/**
* Custom Constructor
* @param string destination name plus any params
* @param type of destination this represents.
*/
StompQueue(const std::string& name) :
StompDestination< cms::Queue >( name, cms::Destination::QUEUE )
{}
virtual ~StompQueue(void) {}
virtual ~StompQueue(void) {}
/**
* Gets the name of this queue.

View File

@ -44,18 +44,12 @@ namespace stomp{
public:
/**
* Constructor
*/
StompSessionInfo(void)
{
sessionId = 0;
ackMode = cms::Session::AutoAcknowledge;
ackMode = cms::Session::AUTO_ACKNOWLEDGE;
}
/**
* Destructor
*/
virtual ~StompSessionInfo(void) {}
/**

View File

@ -18,16 +18,19 @@
#include "StompSessionManager.h"
#include <activemq/core/ActiveMQMessage.h>
#include <activemq/core/ActiveMQConstants.h>
#include <activemq/concurrent/Concurrent.h>
#include <activemq/connector/stomp/StompSessionInfo.h>
#include <activemq/connector/stomp/StompConsumerInfo.h>
#include <activemq/connector/stomp/commands/SubscribeCommand.h>
#include <activemq/connector/stomp/commands/UnsubscribeCommand.h>
#include <activemq/connector/stomp/StompSelector.h>
#include <activemq/util/Properties.h>
using namespace std;
using namespace activemq;
using namespace activemq::core;
using namespace activemq::util;
using namespace activemq::exceptions;
using namespace activemq::transport;
using namespace activemq::connector;
@ -65,7 +68,7 @@ StompSessionManager::~StompSessionManager(void)
////////////////////////////////////////////////////////////////////////////////
unsigned int StompSessionManager::getNextSessionId(void)
{
synchronized(&mutex)
synchronized( &mutex )
{
return nextSessionId++;
}
@ -76,7 +79,7 @@ unsigned int StompSessionManager::getNextSessionId(void)
////////////////////////////////////////////////////////////////////////////////
unsigned int StompSessionManager::getNextConsumerId(void)
{
synchronized(&mutex)
synchronized( &mutex )
{
return nextConsumerId++;
}
@ -86,7 +89,7 @@ unsigned int StompSessionManager::getNextConsumerId(void)
////////////////////////////////////////////////////////////////////////////////
connector::SessionInfo* StompSessionManager::createSession(
cms::Session::AcknowledgeMode ackMode)
cms::Session::AcknowledgeMode ackMode )
throw ( exceptions::ActiveMQException )
{
try
@ -94,7 +97,7 @@ connector::SessionInfo* StompSessionManager::createSession(
SessionInfo* session = new StompSessionInfo();
// Init data
session->setAckMode(ackMode);
session->setAckMode( ackMode );
session->setConnectionId( connectionId );
session->setSessionId( getNextSessionId() );
@ -114,10 +117,10 @@ void StompSessionManager::removeSession(
////////////////////////////////////////////////////////////////////////////////
connector::ConsumerInfo* StompSessionManager::createConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& selector)
throw( ConnectorException )
const std::string& selector )
throw( StompConnectorException )
{
try
{
@ -127,46 +130,54 @@ connector::ConsumerInfo* StompSessionManager::createConsumer(
return createDurableConsumer(
destination, session, "", selector, false );
}
AMQ_CATCH_RETHROW( ConnectorException )
AMQ_CATCHALL_THROW( ConnectorException )
AMQ_CATCH_RETHROW( StompConnectorException )
AMQ_CATCHALL_THROW( StompConnectorException )
}
////////////////////////////////////////////////////////////////////////////////
connector::ConsumerInfo* StompSessionManager::createDurableConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& name,
const std::string& selector,
bool noLocal )
throw ( ConnectorException )
throw ( StompConnectorException )
{
try
{
synchronized(&mutex)
synchronized( &mutex )
{
// Find the right mapping to consumers
ConsumerMap& consumerMap =
destinationMap[ destination->toString() ];
// We only need to send a sub request if there are no active
// consumers on this destination.
if( consumerMap.empty() )
{
// Send the request to the Broker
SubscribeCommand cmd;
if( session->getAckMode() == cms::Session::ClientAcknowledge )
if( session->getAckMode() == cms::Session::CLIENT_ACKNOWLEDGE )
{
cmd.setAckMode( CommandConstants::ACK_CLIENT );
}
cmd.setDestination( destination->toProviderString() );
cmd.setNoLocal( noLocal );
if( noLocal == true )
{
cmd.setNoLocal( noLocal );
}
if( name != "" )
{
cmd.setSubscriptionName( name );
}
// Grab any options from the destination and set them
// for this subscription.
setSubscribeOptions( destination, cmd );
// The Selector is set on the first subscribe on this dest,
// and if another consumer is created on this destination
// that specifies a selector it will be ignored. While
@ -198,18 +209,18 @@ connector::ConsumerInfo* StompSessionManager::createDurableConsumer(
return NULL;
}
AMQ_CATCH_RETHROW( ConnectorException )
AMQ_CATCHALL_THROW( ConnectorException )
AMQ_CATCH_RETHROW( StompConnectorException )
AMQ_CATCHALL_THROW( StompConnectorException )
}
////////////////////////////////////////////////////////////////////////////////
void StompSessionManager::removeConsumer(
connector::ConsumerInfo* consumer)
throw( ConnectorException )
connector::ConsumerInfo* consumer )
throw( StompConnectorException )
{
try
{
synchronized(&mutex)
synchronized( &mutex )
{
DestinationMap::iterator itr =
destinationMap.find( consumer->getDestination().toString() );
@ -238,8 +249,8 @@ void StompSessionManager::removeConsumer(
}
}
}
AMQ_CATCH_RETHROW( ConnectorException )
AMQ_CATCHALL_THROW( ConnectorException )
AMQ_CATCH_RETHROW( StompConnectorException )
AMQ_CATCHALL_THROW( StompConnectorException )
}
////////////////////////////////////////////////////////////////////////////////
@ -265,10 +276,10 @@ void StompSessionManager::onStompCommand( commands::StompCommand* command )
"No Message Listener Registered." );
}
synchronized(&mutex)
synchronized( &mutex )
{
DestinationMap::iterator itr =
destinationMap.find( message->getCMSDestination().toString() );
destinationMap.find( message->getCMSDestination()->toString() );
if( itr == destinationMap.end() )
{
@ -280,7 +291,7 @@ void StompSessionManager::onStompCommand( commands::StompCommand* command )
// If we only have 1 consumer, we don't need to clone the original
// message.
if(itr->second.size() == 1)
if( itr->second.size() == 1 )
{
ConsumerInfo* consumerInfo = itr->second.begin()->second;
@ -301,7 +312,7 @@ void StompSessionManager::onStompCommand( commands::StompCommand* command )
// message.
ConsumerMap::iterator c_itr = itr->second.begin();
for(; c_itr != itr->second.end(); ++c_itr )
for( ; c_itr != itr->second.end(); ++c_itr )
{
ConsumerInfo* consumerInfo = c_itr->second;
@ -324,3 +335,110 @@ void StompSessionManager::onStompCommand( commands::StompCommand* command )
AMQ_CATCH_EXCEPTION_CONVERT( ActiveMQException, StompConnectorException )
AMQ_CATCHALL_THROW( StompConnectorException )
}
void StompSessionManager::setSubscribeOptions( const cms::Destination* dest,
SubscribeCommand& command )
throw ( StompConnectorException )
{
try
{
// Get the properties of this destination
const Properties& destProperties = dest->getProperties();
if( destProperties.isEmpty() )
{
// Nothing to do, so save some work and quit now.
return;
}
std::string noLocalStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_NOLOCAL );
if( destProperties.getProperty( noLocalStr, "false" ) == "true" )
{
command.setNoLocal(
Boolean::parseBoolean(
destProperties.getProperty( noLocalStr ) ) );
}
std::string selectorStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_SELECTOR );
if( destProperties.hasProperty( selectorStr ) )
{
command.setMessageSelector(
destProperties.getProperty( selectorStr ) );
}
std::string priorityStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_PRIORITY );
if( destProperties.hasProperty( priorityStr ) )
{
command.setPriority(
Integer::parseInt(
destProperties.getProperty( priorityStr ) ) );
}
std::string dispatchAsyncStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_DISPATCHASYNC );
if( destProperties.hasProperty( dispatchAsyncStr ) )
{
command.setDispatchAsync(
Boolean::parseBoolean(
destProperties.getProperty( dispatchAsyncStr ) ) );
}
std::string exclusiveStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_EXCLUSIVE );
if( destProperties.hasProperty( exclusiveStr ) )
{
command.setExclusive(
Boolean::parseBoolean(
destProperties.getProperty( exclusiveStr ) ) );
}
std::string maxPendingMsgLimitStr =
ActiveMQConstants::toString(
ActiveMQConstants::CUNSUMER_MAXPENDINGMSGLIMIT );
if( destProperties.hasProperty( maxPendingMsgLimitStr ) )
{
command.setMaxPendingMsgLimit(
Integer::parseInt(
destProperties.getProperty( maxPendingMsgLimitStr ) ) );
}
std::string prefetchSizeStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_PREFECTCHSIZE );
if( destProperties.hasProperty( prefetchSizeStr ) )
{
command.setPrefetchSize(
Integer::parseInt(
destProperties.getProperty( prefetchSizeStr ) ) );
}
std::string retroactiveStr =
ActiveMQConstants::toString(
ActiveMQConstants::CONSUMER_RETROACTIVE );
if( destProperties.hasProperty( retroactiveStr ) )
{
command.setRetroactive(
Boolean::parseBoolean(
destProperties.getProperty( retroactiveStr ) ) );
}
}
AMQ_CATCH_RETHROW( StompConnectorException )
AMQ_CATCH_EXCEPTION_CONVERT( ActiveMQException, StompConnectorException )
AMQ_CATCHALL_THROW( StompConnectorException )
}

View File

@ -25,6 +25,7 @@
#include <activemq/connector/ConnectorException.h>
#include <activemq/connector/stomp/StompCommandListener.h>
#include <activemq/connector/ConsumerMessageListener.h>
#include <activemq/connector/stomp/commands/SubscribeCommand.h>
namespace activemq{
namespace connector{
@ -44,8 +45,8 @@ namespace stomp{
private:
// Map Types
typedef std::map<unsigned int, ConsumerInfo*> ConsumerMap;
typedef std::map<std::string, ConsumerMap> DestinationMap;
typedef std::map< unsigned int, ConsumerInfo* > ConsumerMap;
typedef std::map< std::string, ConsumerMap > DestinationMap;
private:
@ -85,7 +86,7 @@ namespace stomp{
* @return new SessionInfo object
*/
virtual connector::SessionInfo* createSession(
cms::Session::AcknowledgeMode ackMode)
cms::Session::AcknowledgeMode ackMode )
throw ( exceptions::ActiveMQException );
/**
@ -108,10 +109,10 @@ namespace stomp{
* @return new ConsumerInfo object.
*/
virtual connector::ConsumerInfo* createConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& selector)
throw( ConnectorException );
const std::string& selector )
throw( StompConnectorException );
/**
* Creates a new durable consumer to the specified session, will
@ -126,12 +127,12 @@ namespace stomp{
* @return new ConsumerInfo object.
*/
virtual connector::ConsumerInfo* createDurableConsumer(
cms::Destination* destination,
const cms::Destination* destination,
SessionInfo* session,
const std::string& name,
const std::string& selector,
bool noLocal )
throw ( ConnectorException );
throw ( StompConnectorException );
/**
* Removes the Consumer from the session, will unsubscrive if the
@ -142,7 +143,7 @@ namespace stomp{
* @throws ConnectorException
*/
virtual void removeConsumer( connector::ConsumerInfo* consumer )
throw( ConnectorException );
throw( StompConnectorException );
/**
* Sets the listener of consumer messages.
@ -162,7 +163,19 @@ namespace stomp{
* @throw ConnterException
*/
virtual void onStompCommand( commands::StompCommand* command )
throw ( StompConnectorException );
throw ( StompConnectorException );
protected:
/**
* Sets Subscribe Command options from the properties of a
* destination object.
* @param The destination that we are subscribing to.
* @param The pending Subscribe command
*/
virtual void setSubscribeOptions( const cms::Destination* dest,
commands::SubscribeCommand& command )
throw ( StompConnectorException );
protected:

View File

@ -30,8 +30,18 @@ namespace stomp{
{
public:
StompTopic(void) : StompDestination<cms::Topic>() {}
/**
* Copy Consturctor
* @param CMS Dest to Copy, must be a compatible type
*/
StompTopic( const cms::Destination* source ) :
StompDestination< cms::Topic >( source ) {}
/**
* Custom Constructor
* @param string destination name plus any params
* @param type of destination this represents.
*/
StompTopic(const std::string& name) :
StompDestination< cms::Topic >( name, cms::Destination::TOPIC )
{}

View File

@ -37,16 +37,13 @@ namespace stomp{
public:
/**
* TransactionInfo Constructor
* Default Constructor
*/
StompTransactionInfo(void) {
transactionId = 0;
session = NULL;
}
/**
* Destructor
*/
virtual ~StompTransactionInfo(void) {}
/**

View File

@ -113,13 +113,24 @@ namespace commands{
AbstractCommand(void){
frame = new StompFrame;
}
AbstractCommand(StompFrame* frame){
AbstractCommand( StompFrame* frame ){
this->frame = frame;
}
virtual ~AbstractCommand(void){
destroyFrame();
}
/**
* Gets the properties map for this command.
* @return Reference to a Properties object
*/
virtual util::Properties& getProperties(void){
return getFrame().getProperties();
}
virtual const util::Properties& getProperties(void) const{
return getFrame().getProperties();
}
/**
* Sets the Command Id of this Message
* @param Command Id

View File

@ -44,7 +44,7 @@ namespace commands{
initialize( getFrame() );
}
AckCommand( StompFrame* frame ) :
AbstractCommand<transport::Command>(frame) {
AbstractCommand<transport::Command>( frame ) {
validate( getFrame() );
}
virtual ~AckCommand(void) {}

View File

@ -45,7 +45,7 @@ namespace commands{
initialize( getFrame() );
}
BeginCommand( StompFrame* frame ) :
AbstractCommand<transport::Command>(frame) {
AbstractCommand<transport::Command>( frame ) {
validate( getFrame() );
}
virtual ~BeginCommand(void) {}

View File

@ -41,7 +41,7 @@ namespace commands{
initialize( getFrame() );
}
BytesMessageCommand( StompFrame* frame ) :
StompMessage< cms::BytesMessage >(frame) {
StompMessage< cms::BytesMessage >( frame ) {
validate( getFrame() );
}
virtual ~BytesMessageCommand(void) {}

View File

@ -62,7 +62,8 @@ CommandConstants::StaticInitializer::StaticInitializer(){
stompHeaders[HEADER_RESPONSEID] = "response-id";
stompHeaders[HEADER_EXPIRES] = "expires";
stompHeaders[HEADER_PERSISTANT] = "persistent";
stompHeaders[HEADER_PRIORITY] = "priority";
stompHeaders[HEADER_JMSPRIORITY] = "priority";
stompHeaders[HEADER_CONSUMERPRIORITY] = "activemq.priority";
stompHeaders[HEADER_REPLYTO] = "reply-to";
stompHeaders[HEADER_TYPE] = "type";
stompHeaders[HEADER_AMQMSGTYPE] = "amq-msg-type";
@ -74,7 +75,7 @@ CommandConstants::StaticInitializer::StaticInitializer(){
stompHeaders[HEADER_MAXPENDINGMSGLIMIT] = "activemq.maximumPendingMessageLimit";
stompHeaders[HEADER_NOLOCAL] = "activemq.noLocal";
stompHeaders[HEADER_PREFETCHSIZE] = "activemq.prefetchSize";
stompHeaders[HEADER_PRIORITY] = "activemq.priority";
stompHeaders[HEADER_CONSUMERPRIORITY] = "activemq.priority";
stompHeaders[HEADER_RETROACTIVE] = "activemq.retroactive";
stompHeaders[HEADER_SUBSCRIPTIONNAME] = "activemq.subscriptionName";
stompHeaders[HEADER_TIMESTAMP] = "timestamp";

View File

@ -76,7 +76,8 @@ namespace commands{
HEADER_MAXPENDINGMSGLIMIT,
HEADER_NOLOCAL,
HEADER_PREFETCHSIZE,
HEADER_PRIORITY,
HEADER_JMSPRIORITY,
HEADER_CONSUMERPRIORITY,
HEADER_RETROACTIVE,
HEADER_SUBSCRIPTIONNAME,
HEADER_TIMESTAMP,

View File

@ -40,7 +40,7 @@ namespace commands{
initialize( getFrame() );
}
CommitCommand( StompFrame* frame ) :
AbstractCommand<transport::Command>(frame) {
AbstractCommand<transport::Command>( frame ) {
validate( getFrame() );
}
virtual ~CommitCommand(void) {}

View File

@ -39,7 +39,7 @@ namespace commands{
initialize( getFrame() );
}
ConnectCommand( StompFrame* frame ) :
AbstractCommand<transport::Command>(frame) {
AbstractCommand<transport::Command>( frame ) {
validate( getFrame() );
}
virtual ~ConnectCommand(void) {};

View File

@ -40,7 +40,7 @@ namespace commands{
initialize( getFrame() );
}
DisconnectCommand( StompFrame* frame ) :
AbstractCommand<transport::Command>(frame) {
AbstractCommand<transport::Command>( frame ) {
validate( getFrame() );
}
virtual ~DisconnectCommand(void){};

View File

@ -40,7 +40,7 @@ namespace commands{
initialize( getFrame() );
}
ErrorCommand( StompFrame* frame ) :
AbstractCommand<transport::Command>(frame) {
AbstractCommand<transport::Command>( frame ) {
validate( getFrame() );
}
virtual ~ErrorCommand(void) {};

View File

@ -40,7 +40,7 @@ namespace commands{
initialize( getFrame() );
}
ReceiptCommand( StompFrame* frame ) :
AbstractCommand<transport::Response>(frame) {
AbstractCommand<transport::Response>( frame ) {
validate( getFrame() );
}
virtual ~ReceiptCommand(void) {}
@ -60,7 +60,7 @@ namespace commands{
virtual void setReceiptId( const std::string& id ){
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_RECEIPTID),
CommandConstants::HEADER_RECEIPTID ),
id );
}

View File

@ -103,6 +103,13 @@ namespace commands{
* @return Stomp CommandId enum
*/
virtual CommandConstants::CommandId getStompCommandId(void) const = 0;
/**
* Retrieves the Properties that are part of this command
* @return const reference to a properties object
*/
virtual util::Properties& getProperties(void) = 0;
virtual const util::Properties& getProperties(void) const = 0;
};

View File

@ -62,7 +62,7 @@ namespace commands{
StompMessage(void) :
AbstractCommand< transport::Command >(),
ackHandler( NULL ) { dest = new StompTopic(); }
ackHandler( NULL ) { dest = NULL; }
StompMessage( StompFrame* frame ) :
AbstractCommand< transport::Command >( frame ),
ackHandler( NULL )
@ -112,55 +112,57 @@ namespace commands{
* of this consumed message.
*/
virtual void acknowledge(void) const throw( cms::CMSException ) {
if(ackHandler != NULL) ackHandler->acknowledgeMessage(this);
if(ackHandler != NULL) ackHandler->acknowledgeMessage( this );
}
/**
* Sets the DeliveryMode for this message
* @return DeliveryMode enumerated value.
*/
virtual cms::Message::DeliveryMode getCMSDeliveryMode(void) const {
virtual int getCMSDeliveryMode(void) const {
if(!getFrame().getProperties().hasProperty(
CommandConstants::toString(
CommandConstants::HEADER_PERSISTANT ) ) ) {
return cms::Message::PERSISTANT;
return cms::DeliveryMode::PERSISTANT;
}
return (cms::Message::DeliveryMode)(
util::Integer::parseInt( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PERSISTANT ) ) ) );
return util::Integer::parseInt( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PERSISTANT ) ) );
}
/**
* Sets the DeliveryMode for this message
* @param DeliveryMode enumerated value.
*/
virtual void setCMSDeliveryMode(cms::Message::DeliveryMode mode) {
virtual void setCMSDeliveryMode( int mode ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PERSISTANT ) ,
util::Integer::toString((int)mode) );
util::Integer::toString( mode ) );
}
/**
* Gets the Destination for this Message
* @return Destination object
* @return Destination object can be NULL
*/
virtual const cms::Destination& getCMSDestination(void) const{
return *dest;
virtual const cms::Destination* getCMSDestination(void) const{
return dest;
}
/**
* Sets the Destination for this message
* @param Destination Object
*/
virtual void setCMSDestination(const cms::Destination& destination) {
dest->copy( destination );
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DESTINATION ),
dest->toProviderString() );
virtual void setCMSDestination( const cms::Destination* destination ) {
if( destination != NULL )
{
dest = destination->clone();
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DESTINATION ),
dest->toProviderString() );
}
}
/**
@ -177,7 +179,7 @@ namespace commands{
* Sets the Expiration Time for this message
* @param time value
*/
virtual void setCMSExpiration(long expireTime) {
virtual void setCMSExpiration( long expireTime ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_EXPIRES) ,
@ -198,7 +200,7 @@ namespace commands{
* Sets the CMS Message Id for this message
* @param time value
*/
virtual void setCMSMessageId(const std::string& id) {
virtual void setCMSMessageId( const std::string& id ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_MESSAGEID ),
@ -212,17 +214,17 @@ namespace commands{
virtual int getCMSPriority(void) const {
return util::Integer::parseInt( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PRIORITY ), "0" ) );
CommandConstants::HEADER_JMSPRIORITY ), "0" ) );
}
/**
* Sets the Priority Value for this message
* @param priority value
*/
virtual void setCMSPriority(int priority) {
virtual void setCMSPriority( int priority ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PRIORITY),
CommandConstants::HEADER_JMSPRIORITY),
util::Integer::toString( priority ) );
}
@ -241,7 +243,7 @@ namespace commands{
* Sets the Redelivered Flag for this message
* @param redelivered value
*/
virtual void setCMSRedelivered(bool redelivered) {
virtual void setCMSRedelivered( bool redelivered ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_REDELIVERED ),
@ -262,7 +264,7 @@ namespace commands{
* Sets the CMS Reply To Address for this message
* @param Reply To value
*/
virtual void setCMSReplyTo(const std::string& id) {
virtual void setCMSReplyTo( const std::string& id ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_REPLYTO ),
@ -283,7 +285,7 @@ namespace commands{
* Sets the Time Stamp for this message
* @param time stamp value
*/
virtual void setCMSTimeStamp(long timeStamp) {
virtual void setCMSTimeStamp( long timeStamp ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_TIMESTAMP ),
@ -304,7 +306,7 @@ namespace commands{
* Sets the CMS Message Type for this message
* @param type value
*/
virtual void setCMSMessageType(const std::string& type) {
virtual void setCMSMessageType( const std::string& type ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_TYPE ),
@ -318,7 +320,7 @@ namespace commands{
* when the Acknowledge method is called.
* @param ActiveMQAckHandler
*/
virtual void setAckHandler(core::ActiveMQAckHandler* handler) {
virtual void setAckHandler( core::ActiveMQAckHandler* handler ) {
this->ackHandler = handler;
}
@ -338,7 +340,7 @@ namespace commands{
* redelivered
* @param redelivery count
*/
virtual void setRedeliveryCount(int count) {
virtual void setRedeliveryCount( int count ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_REDELIVERYCOUNT ),

View File

@ -53,7 +53,7 @@ namespace commands{
virtual const char* getDestination(void) const{
return getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DESTINATION) );
CommandConstants::HEADER_DESTINATION ) );
}
/**
@ -63,7 +63,7 @@ namespace commands{
virtual void setDestination( const std::string& dest ){
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DESTINATION),
CommandConstants::HEADER_DESTINATION ),
dest );
}
@ -74,7 +74,7 @@ namespace commands{
virtual void setAckMode( const CommandConstants::AckMode mode ){
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_ACK),
CommandConstants::HEADER_ACK ),
CommandConstants::toString( mode ) );
}
@ -86,7 +86,7 @@ namespace commands{
return CommandConstants::toAckMode(
getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_ACK) ) );
CommandConstants::HEADER_ACK ) ) );
}
/**
@ -97,7 +97,7 @@ namespace commands{
virtual void setMessageSelector( const std::string& selector ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_SELECTOR),
CommandConstants::HEADER_SELECTOR ),
selector );
}
@ -109,7 +109,7 @@ namespace commands{
virtual const char* getMessageSelector(void) const{
return getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_SELECTOR) );
CommandConstants::HEADER_SELECTOR ) );
}
/**
@ -120,7 +120,7 @@ namespace commands{
virtual void setSubscriptionName( const std::string& name ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_SUBSCRIPTIONNAME),
CommandConstants::HEADER_SUBSCRIPTIONNAME ),
name );
}
@ -132,11 +132,11 @@ namespace commands{
virtual const char* getSubscriptionName(void) const{
return getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_SUBSCRIPTIONNAME) );
CommandConstants::HEADER_SUBSCRIPTIONNAME ) );
}
/**
* Gets hether or not locally sent messages should be ignored for
* Gets whether or not locally sent messages should be ignored for
* subscriptions. Set to true to filter out locally sent messages
* @return NoLocal value
*/
@ -148,7 +148,7 @@ namespace commands{
}
/**
* Gets hether or not locally sent messages should be ignored for
* Sets whether or not locally sent messages should be ignored for
* subscriptions. Set to true to filter out locally sent messages
* @param NoLocal value
*/
@ -159,6 +159,162 @@ namespace commands{
util::Boolean::toString( noLocal ) );
}
/**
* Sets whether or not the broker is to dispatch messages in an
* asynchronous manner. Set to true if you want Async.
* @return true if in dispatch async mode
*/
virtual bool getDispatchAsync(void) const {
return util::Boolean::parseBoolean( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DISPATCH_ASYNC ),
"false" ) );
}
/**
* Sets whether or not the broker is to dispatch messages in an
* asynchronous manner. Set to true if you want Async.
* @param true for async dispatch mode
*/
virtual void setDispatchAsync( bool dispatchAsync ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DISPATCH_ASYNC ),
util::Boolean::toString( dispatchAsync ) );
}
/**
* Gets whether or not this consumer is an exclusive consumer for
* this destination.
* @return true for exclusive mode
*/
virtual bool getExclusive(void) const {
return util::Boolean::parseBoolean( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_EXCLUSIVE ),
"false" ) );
}
/**
* Sets whether or not this consumer is an exclusive consumer for
* this destination.
* @param true if in exclusive mode
*/
virtual void setExclusive( bool exclusive ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_EXCLUSIVE ),
util::Boolean::toString( exclusive ) );
}
/**
* Get the max number of pending messages on a destination
* For Slow Consumer Handlingon non-durable topics by dropping old
* messages - we can set a maximum pending limit which once a slow
* consumer backs up to this high water mark we begin to discard
* old messages
* @return Max value
*/
virtual int getMaxPendingMsgLimit(void) const {
return util::Integer::parseInt( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_MAXPENDINGMSGLIMIT ),
"0" ) );
}
/**
* Set the max number of pending messages on a destination
* For Slow Consumer Handlingon non-durable topics by dropping old
* messages - we can set a maximum pending limit which once a slow
* consumer backs up to this high water mark we begin to discard
* old messages
* @param Max value
*/
virtual void setMaxPendingMsgLimit( int limit ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_MAXPENDINGMSGLIMIT ),
util::Integer::toString( limit ) );
}
/**
* Get the maximum number of pending messages that will be
* dispatched to the client. Once this maximum is reached no more
* messages are dispatched until the client acknowledges a message.
* Set to 1 for very fair distribution of messages across consumers
* where processing messages can be slow
* @return prefetch size value
*/
virtual int getPrefetchSize(void) const {
return util::Integer::parseInt( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PREFETCHSIZE ),
"1000" ) );
}
/**
* Set the maximum number of pending messages that will be
* dispatched to the client. Once this maximum is reached no more
* messages are dispatched until the client acknowledges a message.
* Set to 1 for very fair distribution of messages across consumers
* where processing messages can be slow
* @param prefetch size value
*/
virtual void setPrefetchSize( int size ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_PREFETCHSIZE ),
util::Integer::toString( size ) );
}
/**
* Gets the priority of the consumer so that dispatching can be
* weighted in priority order
* @return priority level
*/
virtual int getPriority(void) const {
return util::Integer::parseInt( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_CONSUMERPRIORITY ),
"0" ) );
}
/**
* Sets the priority of the consumer so that dispatching can be
* weighted in priority order
* @param prioirty level
*/
virtual void setPriority( int priority ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_CONSUMERPRIORITY ),
util::Integer::toString( priority ) );
}
/**
* Get For non-durable topics if this subscription is set to be
* retroactive
* @return true for retroactive mode
*/
virtual bool getRetroactive(void) const {
return util::Boolean::parseBoolean( getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_RETROACTIVE ),
"false" ) );
}
/**
* Set For non-durable topics if this subscription is set to be
* retroactive
* @param true if in retroactive mode
*/
virtual void setRetroactive( bool retroactive ) {
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_RETROACTIVE ),
util::Boolean::toString( retroactive ) );
}
protected:
/**
@ -173,7 +329,7 @@ namespace commands{
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_ACK),
CommandConstants::HEADER_ACK ),
CommandConstants::toString(
CommandConstants::ACK_AUTO ) );
}

View File

@ -68,6 +68,14 @@ namespace commands{
setBytes( msg, strlen(msg) + 1, false );
}
/**
* Sets the message contents.
* @param msg The message buffer.
*/
virtual void setText( const std::string& msg ) throw( cms::CMSException ) {
setBytes( msg.c_str(), msg.length() + 1, false );
}
};
}}}}

View File

@ -51,7 +51,7 @@ namespace commands{
virtual const char* getDestination(void) const{
return getPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DESTINATION) );
CommandConstants::HEADER_DESTINATION ) );
}
/**
@ -60,7 +60,7 @@ namespace commands{
virtual void setDestination( const std::string& dest ){
setPropertyValue(
CommandConstants::toString(
CommandConstants::HEADER_DESTINATION) ,
CommandConstants::HEADER_DESTINATION ),
dest );
}

View File

@ -30,7 +30,7 @@ namespace marshal{
{
public:
virtual ~Marshalable(void) {}
virtual ~Marshalable(void) {}
/**
* Marshals the command to a stomp frame.

View File

@ -32,7 +32,7 @@ namespace core{
{
public:
virtual ~ActiveMQAckHandler(void) {};
virtual ~ActiveMQAckHandler(void) {};
/**
* Method called to acknowledge the message passed

View File

@ -34,6 +34,7 @@ ActiveMQConnection::ActiveMQConnection(ActiveMQConnectionData* connectionData)
{
this->connectionData = connectionData;
this->started = false;
this->closed = false;
this->exceptionListener = NULL;
// We want to be the sink for all messages from the Connector
@ -57,7 +58,7 @@ cms::Session* ActiveMQConnection::createSession(void)
{
try
{
return this->createSession( Session::AutoAcknowledge );
return this->createSession( Session::AUTO_ACKNOWLEDGE );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
@ -90,10 +91,20 @@ void ActiveMQConnection::close(void) throw ( cms::CMSException )
{
try
{
if( closed )
{
return;
}
// Once current deliveries are done this stops the delivery
// of any new messages.
started = false;
closed = true;
// Shutdown connector and transport
connectionData->getConnector()->close();
connectionData->getTransport()->close();
// Destroy the connection data
delete connectionData;
connectionData = NULL;
@ -124,7 +135,7 @@ void ActiveMQConnection::addMessageListener( const unsigned int consumerId,
ActiveMQMessageListener* listener )
{
// Place in Map
synchronized(&mutex)
synchronized( &mutex )
{
consumers[consumerId] = listener;
}
@ -134,7 +145,7 @@ void ActiveMQConnection::addMessageListener( const unsigned int consumerId,
void ActiveMQConnection::removeMessageListener( const unsigned int consumerId )
{
// Remove from Map
synchronized(&mutex)
synchronized( &mutex )
{
consumers.erase( consumerId );
}
@ -175,9 +186,9 @@ void ActiveMQConnection::onConsumerMessage( connector::ConsumerInfo* consumer,
}
// Started, so lock map and dispatch the message.
synchronized(&mutex)
synchronized( &mutex )
{
if(consumers.find(consumer->getConsumerId()) != consumers.end())
if(consumers.find( consumer->getConsumerId()) != consumers.end() )
{
consumers[consumer->getConsumerId()]->
onActiveMQMessage( message );

View File

@ -32,147 +32,149 @@
namespace activemq{
namespace core{
class cms::Session;
class ActiveMQConsumer;
class cms::Session;
class ActiveMQConsumer;
class ActiveMQConnection :
public cms::Connection,
public connector::ConsumerMessageListener
{
private:
class ActiveMQConnection :
public cms::Connection,
public connector::ConsumerMessageListener
{
private:
// the registered exception listener
cms::ExceptionListener* exceptionListener;
// the registered exception listener
cms::ExceptionListener* exceptionListener;
// All the data that is used to connect this Connection
ActiveMQConnectionData* connectionData;
// All the data that is used to connect this Connection
ActiveMQConnectionData* connectionData;
// Indicates if this Connection is started
bool started;
// Map of Consumer Ids to ActiveMQMessageListeners
std::map<unsigned int, ActiveMQMessageListener*> consumers;
// Mutex to lock the Consumers Map
concurrent::Mutex mutex;
public:
// Indicates if this Connection is started
bool started;
/**
* Constructor
*/
ActiveMQConnection(ActiveMQConnectionData* connectionData);
/**
* Destructor
*/
virtual ~ActiveMQConnection(void);
public: // Connection Interface Methods
/**
* Creates a new Session to work for this Connection
*/
virtual cms::Session* createSession(void) throw ( cms::CMSException );
// Indicates that this connection has been closed, it is no longer
// usable after this becomes true
bool closed;
/**
* Creates a new Session to work for this Connection using the
* specified acknowledgment mode
* @param the Acknowledgement Mode to use.
*/
virtual cms::Session* createSession(cms::Session::AcknowledgeMode ackMode)
throw ( cms::CMSException );
// Map of Consumer Ids to ActiveMQMessageListeners
std::map< unsigned int, ActiveMQMessageListener* > consumers;
// Mutex to lock the Consumers Map
concurrent::Mutex mutex;
public:
/**
* Constructor
* @param Pointer to an ActiveMQConnectionData object, owned here
*/
ActiveMQConnection( ActiveMQConnectionData* connectionData );
virtual ~ActiveMQConnection(void);
public: // Connection Interface Methods
/**
* Creates a new Session to work for this Connection
*/
virtual cms::Session* createSession(void) throw ( cms::CMSException );
/**
* Creates a new Session to work for this Connection using the
* specified acknowledgment mode
* @param the Acknowledgement Mode to use.
*/
virtual cms::Session* createSession( cms::Session::AcknowledgeMode ackMode )
throw ( cms::CMSException );
/**
* Get the Client Id for this session
* @return string version of Client Id
*/
virtual std::string getClientId(void) const;
/**
* Get the Client Id for this session
* @return string version of Client Id
*/
virtual std::string getClientId(void) const;
/**
* Retrieves the Connection Data object for this object.
* @return pointer to a connection data object.
*/
virtual ActiveMQConnectionData* getConnectionData(void){
return connectionData;
}
/**
* Retrieves the Connection Data object for this object.
* @return pointer to a connection data object.
*/
virtual ActiveMQConnectionData* getConnectionData(void){
return connectionData;
}
/**
* Gets the registered Exception Listener for this connection
* @return pointer to an exception listnener or NULL
*/
virtual cms::ExceptionListener* getExceptionListener(void) const{
return exceptionListener; };
/**
* Gets the registered Exception Listener for this connection
* @return pointer to an exception listnener or NULL
*/
virtual cms::ExceptionListener* getExceptionListener(void) const{
return exceptionListener; };
/**
* Sets the registed Exception Listener for this connection
* @param pointer to and <code>ExceptionListener</code>
*/
virtual void setExceptionListener(cms::ExceptionListener* listener){
exceptionListener = listener; };
/**
* Sets the registed Exception Listener for this connection
* @param pointer to and <code>ExceptionListener</code>
*/
virtual void setExceptionListener( cms::ExceptionListener* listener ){
exceptionListener = listener; };
/**
* Close the currently open connection
* @throws CMSException
*/
virtual void close(void) throw ( cms::CMSException );
/**
* Close the currently open connection
* @throws CMSException
*/
virtual void close(void) throw ( cms::CMSException );
/**
* Starts or (restarts) a connections delivery of incoming messages
* @throws CMSException
*/
virtual void start(void) throw ( cms::CMSException );
/**
* Starts or (restarts) a connections delivery of incoming messages
* @throws CMSException
*/
virtual void start(void) throw ( cms::CMSException );
/**
* Stop the flow of incoming messages
* @throws CMSException
*/
virtual void stop(void) throw ( cms::CMSException );
/**
* Stop the flow of incoming messages
* @throws CMSException
*/
virtual void stop(void) throw ( cms::CMSException );
public: // ActiveMQConnection Methods
public: // ActiveMQConnection Methods
/**
* Adds the ActiveMQMessageListener to the Mapping of Consumer Id's
* to listeners, all message to that id will be routed to the given
* listener
* @param Consumer Id String
* @param ActiveMQMessageListener Pointer
*/
virtual void addMessageListener(const unsigned int consumerId,
ActiveMQMessageListener* listener);
/**
* Adds the ActiveMQMessageListener to the Mapping of Consumer Id's
* to listeners, all message to that id will be routed to the given
* listener
* @param Consumer Id String
* @param ActiveMQMessageListener Pointer
*/
virtual void addMessageListener( const unsigned int consumerId,
ActiveMQMessageListener* listener );
/**
* Remove the Listener for the specified Consumer Id
* @param Consumer Id string
*/
virtual void removeMessageListener(const unsigned int consumerId);
/**
* Remove the Listener for the specified Consumer Id
* @param Consumer Id string
*/
virtual void removeMessageListener( const unsigned int consumerId );
private:
private:
/**
* Notify the excpetion listener
*/
void fire( exceptions::ActiveMQException& ex )
{
if( exceptionListener != NULL )
{
try
/**
* Notify the excpetion listener
*/
void fire( exceptions::ActiveMQException& ex )
{
if( exceptionListener != NULL )
{
exceptionListener->onException( ex );
try
{
exceptionListener->onException( ex );
}
catch(...){}
}
catch(...){}
}
}
}
/**
* Called to dispatch a message to a particular consumer.
* @param consumer the target consumer of the dispatch.
* @param msg the message to be dispatched.
*/
virtual void onConsumerMessage( connector::ConsumerInfo* consumer,
core::ActiveMQMessage* message );
/**
* Called to dispatch a message to a particular consumer.
* @param consumer the target consumer of the dispatch.
* @param msg the message to be dispatched.
*/
virtual void onConsumerMessage( connector::ConsumerInfo* consumer,
core::ActiveMQMessage* message );
};
};
}}

View File

@ -25,6 +25,7 @@
#include <activemq/network/Socket.h>
#include <activemq/exceptions/NullPointerException.h>
#include <activemq/core/ActiveMQConnection.h>
#include <activemq/core/ActiveMQConstants.h>
#include <activemq/util/StringTokenizer.h>
#include <activemq/support/LibraryInit.h>
@ -48,10 +49,11 @@ ActiveMQConnectionFactory::ActiveMQConnectionFactory(void)
}
////////////////////////////////////////////////////////////////////////////////
ActiveMQConnectionFactory::ActiveMQConnectionFactory(const std::string& url,
const std::string& username,
const std::string& password,
const std::string& clientId)
ActiveMQConnectionFactory::ActiveMQConnectionFactory(
const std::string& url,
const std::string& username,
const std::string& password,
const std::string& clientId )
{
brokerURL = url;
@ -64,7 +66,7 @@ ActiveMQConnectionFactory::ActiveMQConnectionFactory(const std::string& url,
cms::Connection* ActiveMQConnectionFactory::createConnection(void)
throw ( cms::CMSException )
{
return createConnection(username, password);
return createConnection( username, password, clientId );
}
////////////////////////////////////////////////////////////////////////////////
@ -96,9 +98,18 @@ cms::Connection* ActiveMQConnectionFactory::createConnection(
}
// Store login data in the properties
properties->setProperty( "username", this->username );
properties->setProperty( "password", this->password );
properties->setProperty( "clientId", this->clientId );
properties->setProperty(
ActiveMQConstants::toString(
ActiveMQConstants::PARAM_USERNAME ),
this->username );
properties->setProperty(
ActiveMQConstants::toString(
ActiveMQConstants::PARAM_PASSWORD ),
this->password );
properties->setProperty(
ActiveMQConstants::toString(
ActiveMQConstants::PARAM_CLIENTID ),
this->clientId );
// Parse out the properties from the URI
parseURL( brokerURL, *properties );
@ -112,7 +123,7 @@ cms::Connection* ActiveMQConnectionFactory::createConnection(
throw ActiveMQException(
__FILE__, __LINE__,
"ActiveMQConnectionFactory::createConnection - "
"unknown transport factory");
"unknown transport factory" );
}
// Create the transport.
@ -121,7 +132,7 @@ cms::Connection* ActiveMQConnectionFactory::createConnection(
throw ActiveMQException(
__FILE__, __LINE__,
"ActiveMQConnectionFactory::createConnection - "
"failed creating new Transport");
"failed creating new Transport" );
}
// What wire format are we using, defaults to Stomp
@ -137,18 +148,18 @@ cms::Connection* ActiveMQConnectionFactory::createConnection(
throw NullPointerException(
__FILE__, __LINE__,
"ActiveMQConnectionFactory::createConnection - "
"Connector for Wire Format not registered in Map");
"Connector for Wire Format not registered in Map" );
}
// Create the Connector.
connector = connectorfactory->createConnector( *properties, transport );
if(connector == NULL)
if( connector == NULL )
{
throw NullPointerException(
__FILE__, __LINE__,
"ActiveMQConnectionFactory::createConnection - "
"Failed to Create the Connector");
"Failed to Create the Connector" );
}
// Start the Connector
@ -177,9 +188,9 @@ cms::Connection* ActiveMQConnectionFactory::createConnection(
catch( ... )
{
exceptions::ActiveMQException ex(
__FILE__, __LINE__,
"ActiveMQConnectionFactory::create - "
"caught unknown exception" );
__FILE__, __LINE__,
"ActiveMQConnectionFactory::create - "
"caught unknown exception" );
delete connection;
delete connector;
@ -191,8 +202,8 @@ cms::Connection* ActiveMQConnectionFactory::createConnection(
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQConnectionFactory::parseURL(const std::string& URI,
Properties& properties)
void ActiveMQConnectionFactory::parseURL( const std::string& URI,
Properties& properties )
throw ( exceptions::IllegalArgumentException )
{
try
@ -203,14 +214,14 @@ void ActiveMQConnectionFactory::parseURL(const std::string& URI,
// Require that there be three tokens at the least, these are
// transport, url, port.
if(tokenizer.countTokens() < 3)
if( tokenizer.countTokens() < 3 )
{
throw exceptions::IllegalArgumentException(
__FILE__, __LINE__,
(string("ActiveMQConnectionFactory::parseURL - "
"Marlformed URI: ") + URI).c_str());
}
// First element should be the Transport Type, following that is the
// URL and any params.
properties.setProperty( "transport", tokenizer.nextToken() );
@ -219,24 +230,29 @@ void ActiveMQConnectionFactory::parseURL(const std::string& URI,
// and then each param set is delimited with & we extract first
// three chars as they are the left over ://
properties.setProperty( "uri", tokenizer.nextToken("&?").substr(3) );
// Now get all the optional parameters and store them as properties
int count = tokenizer.toArray(tokens);
for(int i = 0; i < count; ++i)
for( int i = 0; i < count; ++i )
{
tokenizer.reset(tokens[i], "=");
tokenizer.reset( tokens[i], "=" );
if(tokenizer.countTokens() != 2)
if( tokenizer.countTokens() != 2 )
{
throw exceptions::IllegalArgumentException(
__FILE__, __LINE__,
(string("ActiveMQConnectionFactory::parseURL - "
"Marlformed Parameter = ") + tokens[i]).c_str());
( string( "ActiveMQConnectionFactory::parseURL - "
"Marlformed Parameter = " ) + tokens[i] ).c_str() );
}
// Get them in order, passing both as nextToken calls in the
// set Property can cause reversed order.
string key = tokenizer.nextToken();
string value = tokenizer.nextToken();
// Store this param as a property
properties.setProperty(tokenizer.nextToken(), tokenizer.nextToken());
properties.setProperty( key, value );
}
}
AMQ_CATCH_RETHROW( IllegalArgumentException )

View File

@ -25,153 +25,150 @@
namespace activemq{
namespace core{
class util::Properties;
class util::Properties;
class ActiveMQConnectionFactory : public cms::ConnectionFactory
{
private:
class ActiveMQConnectionFactory : public cms::ConnectionFactory
{
private:
// The user name this factory will use to connect
std::string username;
// The user name this factory will use to connect
std::string username;
// The password this factory will use to connect
std::string password;
// The password this factory will use to connect
std::string password;
// The client id to assign to the connection created
std::string clientId;
// The client id to assign to the connection created
std::string clientId;
// The URL of the Broker, the default is:
// "tcp://localhost:61616"
std::string brokerURL;
// The URL of the Broker, the default is:
// "tcp://localhost:61616"
std::string brokerURL;
public:
public:
/**
* Constructor
*/
ActiveMQConnectionFactory(void);
/**
* Constructor
*/
ActiveMQConnectionFactory(void);
/**
* Constructor
* @param the URL of the Broker we are connecting to.
* @param username to authenticate with, defaults to ""
* @param password to authenticate with, defaults to ""
* @param client Id to assign to connection, defaults to ""
*/
ActiveMQConnectionFactory(const std::string& url,
const std::string& username = "",
const std::string& password = "",
const std::string& clientId = "");
/**
* Constructor
* @param the URL of the Broker we are connecting to.
* @param username to authenticate with, defaults to ""
* @param password to authenticate with, defaults to ""
* @param client Id to assign to connection, defaults to ""
*/
ActiveMQConnectionFactory( const std::string& url,
const std::string& username = "",
const std::string& password = "",
const std::string& clientId = "" );
/**
* Destructor
*/
virtual ~ActiveMQConnectionFactory(void) {}
virtual ~ActiveMQConnectionFactory(void) {}
/**
* Creates a connection with the default user identity. The
* connection is created in stopped mode. No messages will be
* delivered until the Connection.start method is explicitly
* called.
* @throws CMSException
*/
virtual cms::Connection* createConnection(void) throw ( cms::CMSException );
/**
* Creates a connection with the default user identity. The
* connection is created in stopped mode. No messages will be
* delivered until the Connection.start method is explicitly
* called.
* @throws CMSException
*/
virtual cms::Connection* createConnection(void) throw ( cms::CMSException );
/**
* Creates a connection with the specified user identity. The
* connection is created in stopped mode. No messages will be
* delivered until the Connection.start method is explicitly called.
* @throw CMSException.
*/
virtual cms::Connection* createConnection(const std::string& username,
const std::string& password,
const std::string& clientId = "")
throw ( cms::CMSException );
/**
* Creates a connection with the specified user identity. The
* connection is created in stopped mode. No messages will be
* delivered until the Connection.start method is explicitly called.
* @throw CMSException.
*/
virtual cms::Connection* createConnection( const std::string& username,
const std::string& password,
const std::string& clientId = "" )
throw ( cms::CMSException );
/**
* Sets the username that should be used when creating a new connection
* @param username string
*/
virtual void setUsername(const std::string& username){
this->username = username;
}
/**
* Sets the username that should be used when creating a new connection
* @param username string
*/
virtual void setUsername( const std::string& username ){
this->username = username;
}
/**
* Gets the username that this factory will use when creating a new
* connection instance.
* @return username string, "" for default credentials
*/
virtual const std::string& getUsername(void) const {
return username;
}
/**
* Gets the username that this factory will use when creating a new
* connection instance.
* @return username string, "" for default credentials
*/
virtual const std::string& getUsername(void) const {
return username;
}
/**
* Sets the password that should be used when creating a new connection
* @param password string
*/
virtual void setPassword(const std::string& password){
this->password = password;
}
/**
* Sets the password that should be used when creating a new connection
* @param password string
*/
virtual void setPassword( const std::string& password ){
this->password = password;
}
/**
* Gets the password that this factory will use when creating a new
* connection instance.
* @return password string, "" for default credentials
*/
virtual const std::string& getPassword(void) const {
return password;
}
/**
* Gets the password that this factory will use when creating a new
* connection instance.
* @return password string, "" for default credentials
*/
virtual const std::string& getPassword(void) const {
return password;
}
/**
* Sets the Broker URL that should be used when creating a new
* connection instance
* @param brokerURL string
*/
virtual void setBrokerURL(const std::string& brokerURL){
this->brokerURL = brokerURL;
}
/**
* Sets the Broker URL that should be used when creating a new
* connection instance
* @param brokerURL string
*/
virtual void setBrokerURL( const std::string& brokerURL ){
this->brokerURL = brokerURL;
}
/**
* Gets the Broker URL that this factory will use when creating a new
* connection instance.
* @return brokerURL string
*/
virtual const std::string& getBrokerURL(void) const {
return brokerURL;
}
/**
* Gets the Broker URL that this factory will use when creating a new
* connection instance.
* @return brokerURL string
*/
virtual const std::string& getBrokerURL(void) const {
return brokerURL;
}
/**
* Sets the Client Id that should be used when creating a new
* connection instance
* @param clientId string
*/
virtual void setClientId(const std::string& clientId){
this->clientId = clientId;
}
/**
* Sets the Client Id that should be used when creating a new
* connection instance
* @param clientId string
*/
virtual void setClientId( const std::string& clientId ){
this->clientId = clientId;
}
/**
* Gets the Client Id that this factory will use when creating a new
* connection instance.
* @return clientId string
*/
virtual const std::string& getClientId(void) const {
return clientId;
}
/**
* Gets the Client Id that this factory will use when creating a new
* connection instance.
* @return clientId string
*/
virtual const std::string& getClientId(void) const {
return clientId;
}
protected:
protected:
/**
* Parses the properties out of the provided Broker URI and sets
* them in the passed Properties Object.
* @param a Broker URI to parse
* @param a Properties object to set the parsed values in
* @throws IllegalArgumentException if the passed URI is invalid
*/
virtual void parseURL(const std::string& URI,
util::Properties& properties)
throw ( exceptions::IllegalArgumentException );
/**
* Parses the properties out of the provided Broker URI and sets
* them in the passed Properties Object.
* @param a Broker URI to parse
* @param a Properties object to set the parsed values in
* @throws IllegalArgumentException if the passed URI is invalid
*/
virtual void parseURL( const std::string& URI,
util::Properties& properties )
throw ( exceptions::IllegalArgumentException );
};
};
}}

View File

@ -0,0 +1,58 @@
/*
* Copyright 2006 The Apache Software Foundation or its licensors, as
* applicable.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ActiveMQConstants.h"
#include <stdio.h>
using namespace std;
using namespace activemq;
using namespace activemq::core;
////////////////////////////////////////////////////////////////////////////////
string ActiveMQConstants::StaticInitializer::destOptions[NUM_OPTIONS];
string ActiveMQConstants::StaticInitializer::uriParams[NUM_PARAMS];
map< std::string, ActiveMQConstants::DestinationOption >
ActiveMQConstants::StaticInitializer::destOptionMap;
map< std::string, ActiveMQConstants::URIParam >
ActiveMQConstants::StaticInitializer::uriParamsMap;
ActiveMQConstants::StaticInitializer ActiveMQConstants::staticInits;
////////////////////////////////////////////////////////////////////////////////
ActiveMQConstants::StaticInitializer::StaticInitializer(){
destOptions[CONSUMER_PREFECTCHSIZE] = "consumer.prefetchSize";
destOptions[CUNSUMER_MAXPENDINGMSGLIMIT] = "consumer.maximumPendingMessageLimit";
destOptions[CONSUMER_NOLOCAL] = "consumer.noLocal";
destOptions[CONSUMER_DISPATCHASYNC] = "consumer.dispatchAsync";
destOptions[CONSUMER_RETROACTIVE] = "consumer.retroactive";
destOptions[CONSUMER_SELECTOR] = "consumer.selector";
destOptions[CONSUMER_EXCLUSIVE] = "consumer.exclusive";
destOptions[CONSUMER_PRIORITY] = "consumer.priority";
uriParams[PARAM_USERNAME] = "username";
uriParams[PARAM_PASSWORD] = "password";
uriParams[PARAM_CLIENTID] = "client-id";
for( int ix=0; ix<NUM_OPTIONS; ++ix ){
destOptionMap[destOptions[ix]] = (DestinationOption)ix;
}
for( int ix=0; ix<NUM_PARAMS; ++ix ){
uriParamsMap[uriParams[ix]] = (URIParam)ix;
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2006 The Apache Software Foundation or its licensors, as
* applicable.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ACTIVEMQ_CORE_ACTIVEMQCONSTANTS_H_
#define ACTIVEMQ_CORE_ACTIVEMQCONSTANTS_H_
#include <activemq/exceptions/IllegalArgumentException.h>
#include <string>
#include <map>
namespace activemq{
namespace core{
/**
* Class holding constant values for various ActiveMQ specific things
* Each constant is defined as an enumeration and has functions that
* convert back an forth between string and enum values.
*/
class ActiveMQConstants{
public:
/**
* These values represent the options that can be appended to an
* Destination name, i.e. /topic/foo?consumer.exclusive=true
*/
enum DestinationOption{
CONSUMER_PREFECTCHSIZE,
CUNSUMER_MAXPENDINGMSGLIMIT,
CONSUMER_NOLOCAL,
CONSUMER_DISPATCHASYNC,
CONSUMER_RETROACTIVE,
CONSUMER_SELECTOR,
CONSUMER_EXCLUSIVE,
CONSUMER_PRIORITY,
NUM_OPTIONS
};
/**
* These values represent the parameters that can be added to the
* connection URI that affect the ActiveMQ Core API
*/
enum URIParam
{
PARAM_USERNAME,
PARAM_PASSWORD,
PARAM_CLIENTID,
NUM_PARAMS
};
static const std::string& toString( const DestinationOption option ){
return StaticInitializer::destOptions[option];
}
static DestinationOption toDestinationOption( const std::string& option ){
std::map< std::string, DestinationOption >::iterator iter =
StaticInitializer::destOptionMap.find( option );
if( iter == StaticInitializer::destOptionMap.end() ){
return NUM_OPTIONS;
}
return iter->second;
}
static const std::string& toString( const URIParam option ){
return StaticInitializer::uriParams[option];
}
static URIParam toURIOption( const std::string& option ){
std::map< std::string, URIParam >::iterator iter =
StaticInitializer::uriParamsMap.find( option );
if( iter == StaticInitializer::uriParamsMap.end() ){
return NUM_PARAMS;
}
return iter->second;
}
class StaticInitializer{
public:
StaticInitializer();
virtual ~StaticInitializer(){}
static std::string destOptions[NUM_OPTIONS];
static std::string uriParams[NUM_PARAMS];
static std::map<std::string, DestinationOption> destOptionMap;
static std::map<std::string, URIParam> uriParamsMap;
};
private:
static StaticInitializer staticInits;
};
}}
#endif /*ACTIVEMQ_CORE_ACTIVEMQCONSTANTS_H_*/

View File

@ -29,10 +29,10 @@ using namespace activemq::exceptions;
using namespace activemq::concurrent;
////////////////////////////////////////////////////////////////////////////////
ActiveMQConsumer::ActiveMQConsumer(connector::ConsumerInfo* consumerInfo,
ActiveMQSession* session)
ActiveMQConsumer::ActiveMQConsumer( connector::ConsumerInfo* consumerInfo,
ActiveMQSession* session )
{
if(session == NULL || consumerInfo == NULL)
if( session == NULL || consumerInfo == NULL )
{
throw NullPointerException(
__FILE__, __LINE__,
@ -54,7 +54,7 @@ ActiveMQConsumer::~ActiveMQConsumer(void)
{
// Dispose of the Consumer Info, this should stop us from getting
// any more messages.
session->onDestroySessionResource(this);
session->onDestroySessionResource( this );
// Stop the asynchronous message processin thread if it's
// running.
@ -85,11 +85,11 @@ cms::Message* ActiveMQConsumer::receive(void) throw ( cms::CMSException )
{
try
{
synchronized(&msgQueue)
synchronized( &msgQueue )
{
// Check for empty in case of spurious wakeup, or race to
// queue lock.
while(!shutdown && msgQueue.empty())
while( !shutdown && msgQueue.empty() )
{
msgQueue.wait();
}
@ -123,12 +123,12 @@ cms::Message* ActiveMQConsumer::receive(void) throw ( cms::CMSException )
}
////////////////////////////////////////////////////////////////////////////////
cms::Message* ActiveMQConsumer::receive(int millisecs)
cms::Message* ActiveMQConsumer::receive( int millisecs )
throw ( cms::CMSException )
{
try
{
synchronized(&msgQueue)
synchronized( &msgQueue )
{
// Check for empty, and wait if its not
if( msgQueue.empty() ){
@ -166,9 +166,9 @@ cms::Message* ActiveMQConsumer::receiveNoWait(void)
{
try
{
synchronized(&msgQueue)
synchronized( &msgQueue )
{
if(!msgQueue.empty())
if( !msgQueue.empty() )
{
// Fetch the Message then copy it so it can be handed off
// to the user.
@ -192,11 +192,11 @@ cms::Message* ActiveMQConsumer::receiveNoWait(void)
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQConsumer::setMessageListener(cms::MessageListener* listener)
void ActiveMQConsumer::setMessageListener( cms::MessageListener* listener )
{
try
{
synchronized(&listenerLock)
synchronized( &listenerLock )
{
this->listener = listener;
}
@ -220,7 +220,7 @@ void ActiveMQConsumer::acknowledgeMessage( const ActiveMQMessage* message )
// Delegate the Ack to the Session, we cast away copnstness since
// in a transactional session we might need to redeliver this
// message and update its data.
session->acknowledge(this, const_cast< ActiveMQMessage*>( message ) );
session->acknowledge( this, const_cast< ActiveMQMessage*>( message ) );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
@ -231,18 +231,18 @@ void ActiveMQConsumer::run(void)
{
try
{
while(!shutdown)
while( !shutdown )
{
Message* message = NULL;
synchronized(&msgQueue)
synchronized( &msgQueue )
{
// Gaurd against spurious wakeup or race to sync lock
// also if the listner has been unregistered we don't
// have anyone to notify, so we wait till a new one is
// registered, and then we will deliver the backlog
while(msgQueue.empty() || listener == NULL)
while( msgQueue.empty() || listener == NULL )
{
if( shutdown )
{
@ -252,7 +252,7 @@ void ActiveMQConsumer::run(void)
}
// don't want to process messages if we are shutting down.
if(shutdown)
if( shutdown )
{
return;
}
@ -275,18 +275,18 @@ void ActiveMQConsumer::run(void)
{
cms::ExceptionListener* listener = session->getExceptionListener();
if(listener != NULL)
if( listener != NULL )
{
listener->onException( ActiveMQException(
__FILE__, __LINE__,
"ActiveMQConsumer::run - "
"MessageListener threw an unknown Exception, recovering..."));
"MessageListener threw an unknown Exception, recovering..." ) );
}
}
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQConsumer::dispatch(ActiveMQMessage* message)
void ActiveMQConsumer::dispatch( ActiveMQMessage* message )
throw ( cms::CMSException )
{
try
@ -294,19 +294,19 @@ void ActiveMQConsumer::dispatch(ActiveMQMessage* message)
// If the Session is in ClientAcknowledge mode, then we set the
// handler in the message to this object and send it out. Otherwise
// we ack it here for all the other Modes.
if(session->getAcknowledgeMode() == Session::ClientAcknowledge)
if( session->getAcknowledgeMode() == Session::CLIENT_ACKNOWLEDGE )
{
// Register ourself so that we can handle the Message's
// acknowledge method.
message->setAckHandler(this);
message->setAckHandler( this );
}
else
{
session->acknowledge(this, message);
session->acknowledge( this, message );
}
// No listener, so we queue it
synchronized(&msgQueue)
synchronized( &msgQueue )
{
msgQueue.push( dynamic_cast< cms::Message* >( message ) );
msgQueue.notifyAll();
@ -321,9 +321,9 @@ void ActiveMQConsumer::purgeMessages(void)
{
try
{
synchronized(&msgQueue)
synchronized( &msgQueue )
{
while(!msgQueue.empty())
while( !msgQueue.empty() )
{
// destroy these messages if this is not a transacted
// session, if it is then the tranasction will clean
@ -361,13 +361,13 @@ void ActiveMQConsumer::notifyListener( Message* message ){
try
{
MessageListener* listener = NULL;
synchronized(&listenerLock)
synchronized( &listenerLock )
{
listener = getMessageListener();
}
if(listener != NULL)
{
listener->onMessage(*message);
listener->onMessage( message );
}
}
AMQ_CATCH_RETHROW( ActiveMQException )
@ -398,14 +398,14 @@ void ActiveMQConsumer::startThread(){
try
{
// Start the thread, if it's not already started.
if(listenerThread == NULL)
if( listenerThread == NULL )
{
listenerThread = new Thread(this);
listenerThread = new Thread( this );
listenerThread->start();
}
// notify the Queue so that any pending messages get delivered
synchronized(&msgQueue)
synchronized( &msgQueue )
{
msgQueue.notifyAll();
}
@ -423,7 +423,7 @@ void ActiveMQConsumer::stopThread(){
// if the thread is running signal it to quit and then
// wait for run to return so thread can die
if(listenerThread != NULL)
if( listenerThread != NULL )
{
synchronized( &msgQueue )
{

View File

@ -57,7 +57,7 @@ namespace core{
concurrent::Mutex listenerLock;
// Message Queue
util::Queue<cms::Message*> msgQueue;
util::Queue< cms::Message* > msgQueue;
// Thread to notif a listener if one is added
concurrent::Thread* listenerThread;
@ -71,12 +71,9 @@ namespace core{
/**
* Constructor
*/
ActiveMQConsumer(connector::ConsumerInfo* consumerInfo,
ActiveMQSession* session);
ActiveMQConsumer( connector::ConsumerInfo* consumerInfo,
ActiveMQSession* session );
/**
* Destructor
*/
virtual ~ActiveMQConsumer(void);
public: // Interface Implementation
@ -94,7 +91,7 @@ namespace core{
* @return new message
* @throws CMSException
*/
virtual cms::Message* receive(int millisecs) throw ( cms::CMSException );
virtual cms::Message* receive( int millisecs ) throw ( cms::CMSException );
/**
* Receive a Message, does not wait if there isn't a new message
@ -108,7 +105,7 @@ namespace core{
* Sets the MessageListener that this class will send notifs on
* @param MessageListener interface pointer
*/
virtual void setMessageListener(cms::MessageListener* listener);
virtual void setMessageListener( cms::MessageListener* listener );
/**
* Gets the MessageListener that this class will send notifs on
@ -178,7 +175,7 @@ namespace core{
* @param cms::Message pointer to the message to dispatch
* @throw cms::CMSException
*/
virtual void dispatch(ActiveMQMessage* message)
virtual void dispatch( ActiveMQMessage* message )
throw ( cms::CMSException );
/**
@ -220,6 +217,7 @@ namespace core{
* Stops the asynchronous message processing thread if it's started.
*/
void stopThread();
};
}}

View File

@ -0,0 +1,192 @@
/*
* Copyright 2006 The Apache Software Foundation or its licensors, as
* applicable.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ACTIVEMQ_CORE_ACTIVEMQDESTINATION_H_
#define _ACTIVEMQ_CORE_ACTIVEMQDESTINATION_H_
#include <activemq/util/SimpleProperties.h>
#include <activemq/util/StringTokenizer.h>
#include <activemq/exceptions/IllegalArgumentException.h>
#include <cms/Destination.h>
namespace activemq{
namespace core{
template< typename T >
class ActiveMQDestination : public T
{
private:
// Params that are optional on the destination
util::SimpleProperties properties;
// Destination type
cms::Destination::DestinationType destType;
// Name of the Destination
std::string name;
public:
/**
* Copy Consturctor
* @param CMS Dest to Copy, must be a compatible type
*/
ActiveMQDestination( const cms::Destination* source ){
this->copy( *source );
}
/**
* Custom Constructor
* @param string destination name plus any params
* @param type of destination this represents.
*/
ActiveMQDestination( const std::string& dest,
cms::Destination::DestinationType destType )
{
try
{
util::StringTokenizer tokenizer(dest, "?&");
std::vector<std::string> tokens;
// Set the type, we know that much anyway
this->destType = destType;
// Require that there at least one token, the dest
if( tokenizer.countTokens() < 1 )
{
throw exceptions::IllegalArgumentException(
__FILE__, __LINE__,
( std::string(
"ActiveMQDestination::ActiveMQDestination - "
"Marlformed Dest: " ) + dest ).c_str() );
}
// Grab the name, that's always first.
this->name = tokenizer.nextToken();
// Now get all the optional parameters and store them as properties
int count = tokenizer.toArray( tokens );
for( int i = 0; i < count; ++i )
{
tokenizer.reset( tokens[i], "=" );
if( tokenizer.countTokens() != 2 )
{
throw exceptions::IllegalArgumentException(
__FILE__, __LINE__,
( std::string(
"ActiveMQDestination::ActiveMQDestination - "
"Marlformed Parameter = ") + tokens[i] ).c_str() );
}
// Get the out in the right order
std::string key = tokenizer.nextToken();
std::string value = tokenizer.nextToken();
// Store this param as a property
properties.setProperty( key, value );
}
}
AMQ_CATCH_RETHROW( exceptions::IllegalArgumentException )
AMQ_CATCH_EXCEPTION_CONVERT( exceptions::ActiveMQException, exceptions::IllegalArgumentException )
AMQ_CATCHALL_THROW( exceptions::IllegalArgumentException )
}
virtual ~ActiveMQDestination() {}
/**
* Get the properties of this Destination, these are the optional
* params that can be specified on a destination name i.e/
* TEST.QUEUE?consumer.dispatchAsync=false&consumer.prefetchSize=10
* @returns const reference to a properties object
*/
virtual const util::Properties& getProperties() const {
return properties;
}
/**
* Copy the contents of the given properties object to this
* objects Properties object. Existing values are erased.
* @param Properties to copy to this object.
*/
virtual void setProperties( const util::Properties& properties ){
this->properties.copy( &properties );
}
/**
* Gets the Destination Name minus any optional params that can
* be appended to the destination with an ?
* @returns destination name minus params
*/
virtual const std::string& getName() const {
return name;
}
/**
* Sets the Destination Name minus any optional params that can
* be appended to the destination with an ?
* @param destination name minus params
*/
virtual void setName( const std::string& ) {
this->name = name;
}
/**
* Retrieve the Destination Type for this Destination
* @return The Destination Type
*/
virtual cms::Destination::DestinationType getDestinationType() const {
return destType;
}
/**
* Set the Destination Type for this Destination
* @param The Destination Type
*/
virtual void setDestinationType( cms::Destination::DestinationType destType ) {
this->destType = destType;
}
/**
* Copies the contents of the given Destinastion object to this one.
* @param source The source Destination object.
*/
virtual void copy( const cms::Destination& source ) {
try
{
// This will throw an Bad Cast Exception if the destination
// isn't a compatible type
const ActiveMQDestination<T>& destination =
dynamic_cast< const ActiveMQDestination<T>& >( source );
this->name = destination.getName();
this->destType = destination.getDestinationType();
this->properties.copy( &destination.getProperties() );
}
AMQ_CATCHALL_THROW( exceptions::ActiveMQException )
}
};
}}
#endif /*_ACTIVEMQ_CORE_ACTIVEMQDESTINATION_H_*/

View File

@ -36,17 +36,14 @@ namespace core{
{
public:
/**
* Destructor
*/
virtual ~ActiveMQMessage(void) {}
virtual ~ActiveMQMessage(void) {}
/**
* Sets the Acknowledgement Handler that this Message will use
* when the Acknowledge method is called.
* @param ActiveMQAckHandler
*/
virtual void setAckHandler(ActiveMQAckHandler* handler) = 0;
virtual void setAckHandler( ActiveMQAckHandler* handler ) = 0;
/**
* Gets the number of times this message has been redelivered.
@ -59,7 +56,7 @@ namespace core{
* redelivered
* @param redelivery count
*/
virtual void setRedeliveryCount(int count) = 0;
virtual void setRedeliveryCount( int count ) = 0;
};

View File

@ -29,7 +29,7 @@ namespace core{
{
public:
virtual ~ActiveMQMessageListener(void) {}
virtual ~ActiveMQMessageListener(void) {}
/**
* Called asynchronously when a new message is received, the message

View File

@ -26,14 +26,14 @@ using namespace activemq::connector;
using namespace activemq::exceptions;
////////////////////////////////////////////////////////////////////////////////
ActiveMQProducer::ActiveMQProducer(connector::ProducerInfo* producerInfo,
ActiveMQSession* session)
ActiveMQProducer::ActiveMQProducer( connector::ProducerInfo* producerInfo,
ActiveMQSession* session )
{
if(session == NULL || producerInfo == NULL)
if( session == NULL || producerInfo == NULL )
{
throw NullPointerException(
__FILE__, __LINE__,
"ActiveMQProducer::ActiveMQProducer - Init with NULL Session");
"ActiveMQProducer::ActiveMQProducer - Init with NULL Session" );
}
// Init Producer Data
@ -41,7 +41,7 @@ ActiveMQProducer::ActiveMQProducer(connector::ProducerInfo* producerInfo,
this->producerInfo = producerInfo;
// Default the Delivery options
deliveryMode = cms::Message::PERSISTANT;
deliveryMode = cms::DeliveryMode::PERSISTANT;
disableMsgId = false;
disableTimestamps = false;
priority = 4;
@ -54,37 +54,37 @@ ActiveMQProducer::~ActiveMQProducer(void)
try
{
// Dispose of the ProducerInfo
session->onDestroySessionResource(this);
session->onDestroySessionResource( this );
}
AMQ_CATCH_NOTHROW( ActiveMQException )
AMQ_CATCHALL_NOTHROW( )
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQProducer::send(cms::Message& message)
void ActiveMQProducer::send( cms::Message* message )
throw ( cms::CMSException )
{
try
{
send(producerInfo->getDestination(), message);
send( &producerInfo->getDestination(), message );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQProducer::send(const cms::Destination& destination,
cms::Message& message) throw ( cms::CMSException )
void ActiveMQProducer::send( const cms::Destination* destination,
cms::Message* message) throw ( cms::CMSException )
{
try
{
// configure the message
message.setCMSDestination(destination);
message.setCMSDeliveryMode(deliveryMode);
message.setCMSPriority(priority);
message.setCMSExpiration(timeToLive);
message->setCMSDestination( destination );
message->setCMSDeliveryMode( deliveryMode );
message->setCMSPriority( priority );
message->setCMSExpiration( timeToLive );
session->send(&message, this);
session->send( message, this );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )

View File

@ -20,6 +20,7 @@
#include <cms/MessageProducer.h>
#include <cms/Message.h>
#include <cms/Destination.h>
#include <cms/DeliveryMode.h>
#include <activemq/core/ActiveMQSessionResource.h>
#include <activemq/connector/ProducerInfo.h>
@ -35,7 +36,7 @@ namespace core{
private:
// Delivery Mode of this Producer
cms::Message::DeliveryMode deliveryMode;
int deliveryMode;
// Disable the Message Id
bool disableMsgId;
@ -63,9 +64,6 @@ namespace core{
ActiveMQProducer( connector::ProducerInfo* producerInfo,
ActiveMQSession* session );
/**
* Destructor
*/
virtual ~ActiveMQProducer(void);
/**
@ -73,21 +71,21 @@ namespace core{
* @param a Message Object Pointer
* @throws CMSException
*/
virtual void send( cms::Message& message ) throw ( cms::CMSException );
virtual void send( cms::Message* message ) throw ( cms::CMSException );
/**
* Sends the message to the designated destination.
* @param a Message Object Pointer
* @throws CMSException
*/
virtual void send( const cms::Destination& destination,
cms::Message& message) throw ( cms::CMSException );
virtual void send( const cms::Destination* destination,
cms::Message* message ) throw ( cms::CMSException );
/**
* Sets the delivery mode for this Producer
* @param The DeliveryMode
*/
virtual void setDeliveryMode(cms::Message::DeliveryMode mode) {
virtual void setDeliveryMode( int mode ) {
deliveryMode = mode;
}
@ -95,7 +93,7 @@ namespace core{
* Gets the delivery mode for this Producer
* @return The DeliveryMode
*/
virtual cms::Message::DeliveryMode getDeliveryMode(void) const {
virtual int getDeliveryMode(void) const {
return deliveryMode;
}

View File

@ -40,7 +40,7 @@ ActiveMQSession::ActiveMQSession( SessionInfo* sessionInfo,
const Properties& properties,
ActiveMQConnection* connection)
{
if(sessionInfo == NULL || connection == NULL)
if( sessionInfo == NULL || connection == NULL )
{
throw NullPointerException(
__FILE__, __LINE__,
@ -53,7 +53,7 @@ ActiveMQSession::ActiveMQSession( SessionInfo* sessionInfo,
this->closed = false;
// Create a Transaction object only if the session is transactional
if(isTransacted())
if( isTransacted() )
{
transaction =
new ActiveMQTransaction(connection, this, properties );
@ -87,7 +87,7 @@ void ActiveMQSession::close(void) throw ( cms::CMSException )
// Destroy this sessions resources
connection->getConnectionData()->
getConnector()->destroyResource(sessionInfo);
getConnector()->destroyResource( sessionInfo );
// mark as done
closed = true;
@ -101,7 +101,7 @@ void ActiveMQSession::commit(void) throw ( cms::CMSException )
{
try
{
if(closed || !isTransacted())
if( closed || !isTransacted() )
{
throw InvalidStateException(
__FILE__, __LINE__,
@ -120,11 +120,11 @@ void ActiveMQSession::rollback(void) throw ( cms::CMSException )
{
try
{
if(closed || !isTransacted())
if( closed || !isTransacted() )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::rollback - This Session Can't Rollback");
"ActiveMQSession::rollback - This Session Can't Rollback" );
}
// Rollback the Transaction
@ -136,19 +136,19 @@ void ActiveMQSession::rollback(void) throw ( cms::CMSException )
////////////////////////////////////////////////////////////////////////////////
cms::MessageConsumer* ActiveMQSession::createConsumer(
cms::Destination& destination)
const cms::Destination* destination )
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createConsumer - Session Already Closed");
"ActiveMQSession::createConsumer - Session Already Closed" );
}
return createConsumer(destination, "");
return createConsumer( destination, "" );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
@ -156,22 +156,22 @@ cms::MessageConsumer* ActiveMQSession::createConsumer(
////////////////////////////////////////////////////////////////////////////////
cms::MessageConsumer* ActiveMQSession::createConsumer(
cms::Destination& destination,
const std::string& selector)
const cms::Destination* destination,
const std::string& selector )
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createConsumer - Session Already Closed");
"ActiveMQSession::createConsumer - Session Already Closed" );
}
ActiveMQConsumer* consumer = new ActiveMQConsumer(
connection->getConnectionData()->getConnector()->
createConsumer(&destination, sessionInfo, selector), this);
createConsumer( destination, sessionInfo, selector), this );
connection->addMessageListener(
consumer->getConsumerInfo()->getConsumerId(), consumer );
@ -184,7 +184,7 @@ cms::MessageConsumer* ActiveMQSession::createConsumer(
////////////////////////////////////////////////////////////////////////////////
cms::MessageConsumer* ActiveMQSession::createDurableConsumer(
cms::Topic& destination,
const cms::Topic* destination,
const std::string& name,
const std::string& selector,
bool noLocal )
@ -192,16 +192,16 @@ cms::MessageConsumer* ActiveMQSession::createDurableConsumer(
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createProducer - Session Already Closed");
"ActiveMQSession::createProducer - Session Already Closed" );
}
ActiveMQConsumer* consumer = new ActiveMQConsumer(
connection->getConnectionData()->getConnector()->
createDurableConsumer( &destination, sessionInfo, name, selector, noLocal ), this);
createDurableConsumer( destination, sessionInfo, name, selector, noLocal ), this );
connection->addMessageListener(
consumer->getConsumerInfo()->getConsumerId(), consumer );
@ -214,53 +214,53 @@ cms::MessageConsumer* ActiveMQSession::createDurableConsumer(
////////////////////////////////////////////////////////////////////////////////
cms::MessageProducer* ActiveMQSession::createProducer(
cms::Destination& destination)
const cms::Destination* destination )
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createProducer - Session Already Closed");
"ActiveMQSession::createProducer - Session Already Closed" );
}
return new ActiveMQProducer(
connection->getConnectionData()->getConnector()->
createProducer(&destination, sessionInfo), this);
createProducer( destination, sessionInfo ), this );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
cms::Queue* ActiveMQSession::createQueue(const std::string& queueName)
cms::Queue* ActiveMQSession::createQueue( const std::string& queueName )
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createQueue - Session Already Closed");
"ActiveMQSession::createQueue - Session Already Closed" );
}
return connection->getConnectionData()->
getConnector()->createQueue(queueName, sessionInfo);
getConnector()->createQueue( queueName, sessionInfo );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
}
////////////////////////////////////////////////////////////////////////////////
cms::Topic* ActiveMQSession::createTopic(const std::string& topicName)
cms::Topic* ActiveMQSession::createTopic( const std::string& topicName )
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
@ -268,7 +268,7 @@ cms::Topic* ActiveMQSession::createTopic(const std::string& topicName)
}
return connection->getConnectionData()->
getConnector()->createTopic(topicName, sessionInfo);
getConnector()->createTopic( topicName, sessionInfo );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
@ -280,15 +280,16 @@ cms::TemporaryQueue* ActiveMQSession::createTemporaryQueue(void)
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createTemporaryQueue - Session Already Closed");
"ActiveMQSession::createTemporaryQueue - "
"Session Already Closed" );
}
return connection->getConnectionData()->
getConnector()->createTemporaryQueue(sessionInfo);
getConnector()->createTemporaryQueue( sessionInfo );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
@ -300,15 +301,16 @@ cms::TemporaryTopic* ActiveMQSession::createTemporaryTopic(void)
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createTemporaryTopic - Session Already Closed");
"ActiveMQSession::createTemporaryTopic - "
"Session Already Closed" );
}
return connection->getConnectionData()->
getConnector()->createTemporaryTopic(sessionInfo);
getConnector()->createTemporaryTopic( sessionInfo );
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
@ -320,11 +322,11 @@ cms::Message* ActiveMQSession::createMessage(void)
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createMessage - Session Already Closed");
"ActiveMQSession::createMessage - Session Already Closed" );
}
return connection->getConnectionData()->
@ -336,15 +338,15 @@ cms::Message* ActiveMQSession::createMessage(void)
////////////////////////////////////////////////////////////////////////////////
cms::BytesMessage* ActiveMQSession::createBytesMessage(void)
throw ( cms::CMSException)
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createBytesMessage - Session Already Closed");
"ActiveMQSession::createBytesMessage - Session Already Closed" );
}
return connection->getConnectionData()->
@ -357,14 +359,14 @@ cms::BytesMessage* ActiveMQSession::createBytesMessage(void)
////////////////////////////////////////////////////////////////////////////////
cms::BytesMessage* ActiveMQSession::createBytesMessage(
const unsigned char* bytes,
unsigned long bytesSize)
throw ( cms::CMSException)
unsigned long bytesSize )
throw ( cms::CMSException )
{
try
{
BytesMessage* msg = createBytesMessage();
msg->setBodyBytes(bytes, bytesSize);
msg->setBodyBytes( bytes, bytesSize );
return msg;
}
@ -378,11 +380,11 @@ cms::TextMessage* ActiveMQSession::createTextMessage(void)
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createTextMessage - Session Already Closed");
"ActiveMQSession::createTextMessage - Session Already Closed" );
}
return connection->getConnectionData()->
@ -393,14 +395,14 @@ cms::TextMessage* ActiveMQSession::createTextMessage(void)
}
////////////////////////////////////////////////////////////////////////////////
cms::TextMessage* ActiveMQSession::createTextMessage(const std::string& text)
cms::TextMessage* ActiveMQSession::createTextMessage( const std::string& text )
throw ( cms::CMSException )
{
try
{
TextMessage* msg = createTextMessage();
msg->setText(text.c_str());
msg->setText( text.c_str() );
return msg;
}
@ -414,11 +416,11 @@ cms::MapMessage* ActiveMQSession::createMapMessage(void)
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::createMapMessage - Session Already Closed");
"ActiveMQSession::createMapMessage - Session Already Closed" );
}
return connection->
@ -433,19 +435,19 @@ cms::MapMessage* ActiveMQSession::createMapMessage(void)
cms::Session::AcknowledgeMode ActiveMQSession::getAcknowledgeMode(void) const
{
return sessionInfo != NULL ?
sessionInfo->getAckMode() : Session::AutoAcknowledge;
sessionInfo->getAckMode() : Session::AUTO_ACKNOWLEDGE;
}
////////////////////////////////////////////////////////////////////////////////
bool ActiveMQSession::isTransacted(void) const
{
return sessionInfo != NULL ?
sessionInfo->getAckMode() == Session::Transactional : false;
sessionInfo->getAckMode() == Session::SESSION_TRANSACTED : false;
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQSession::acknowledge(ActiveMQConsumer* consumer,
ActiveMQMessage* message)
void ActiveMQSession::acknowledge( ActiveMQConsumer* consumer,
ActiveMQMessage* message )
throw ( cms::CMSException )
{
try
@ -454,12 +456,12 @@ void ActiveMQSession::acknowledge(ActiveMQConsumer* consumer,
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::acknowledgeMessage - Session Already Closed");
"ActiveMQSession::acknowledgeMessage - Session Already Closed" );
}
// Stores the Message and its consumer in the tranasction, if the
// session is a transactional one.
if(isTransacted())
if( isTransacted() )
{
transaction->addToTransaction( message, consumer );
}
@ -474,16 +476,16 @@ void ActiveMQSession::acknowledge(ActiveMQConsumer* consumer,
}
////////////////////////////////////////////////////////////////////////////////
void ActiveMQSession::send(cms::Message* message, ActiveMQProducer* producer)
void ActiveMQSession::send( cms::Message* message, ActiveMQProducer* producer )
throw ( cms::CMSException )
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
"ActiveMQSession::onProducerClose - Session Already Closed");
"ActiveMQSession::onProducerClose - Session Already Closed" );
}
// Send via the connection
@ -501,7 +503,7 @@ void ActiveMQSession::onDestroySessionResource(
{
try
{
if(closed)
if( closed )
{
throw InvalidStateException(
__FILE__, __LINE__,
@ -515,13 +517,13 @@ void ActiveMQSession::onDestroySessionResource(
{
// Remove this Consumer from the Connection
connection->removeMessageListener(
consumer->getConsumerInfo()->getConsumerId());
consumer->getConsumerInfo()->getConsumerId() );
// Remove this consumer from the Transaction if we are
// transactional
if( transaction != NULL )
{
transaction->removeFromTransaction(consumer);
transaction->removeFromTransaction( consumer );
}
}
@ -536,7 +538,7 @@ void ActiveMQSession::onDestroySessionResource(
////////////////////////////////////////////////////////////////////////////////
cms::ExceptionListener* ActiveMQSession::getExceptionListener(void)
{
if(connection != NULL)
if( connection != NULL )
{
return connection->getExceptionListener();
}

View File

@ -25,244 +25,242 @@
namespace activemq{
namespace core{
class ActiveMQTransaction;
class ActiveMQConnection;
class ActiveMQConsumer;
class ActiveMQMessage;
class ActiveMQProducer;
class ActiveMQConsumer;
class ActiveMQTransaction;
class ActiveMQConnection;
class ActiveMQConsumer;
class ActiveMQMessage;
class ActiveMQProducer;
class ActiveMQConsumer;
class ActiveMQSession : public cms::Session
{
private:
class ActiveMQSession : public cms::Session
{
private:
// SessionInfo for this Session
connector::SessionInfo* sessionInfo;
// SessionInfo for this Session
connector::SessionInfo* sessionInfo;
// Transaction Management object
ActiveMQTransaction* transaction;
// Transaction Management object
ActiveMQTransaction* transaction;
// Connection
ActiveMQConnection* connection;
// Connection
ActiveMQConnection* connection;
// Bool to indicate if this session was closed.
bool closed;
// Bool to indicate if this session was closed.
bool closed;
public:
public:
/**
* Constructor
*/
ActiveMQSession( connector::SessionInfo* sessionInfo,
const util::Properties& properties,
ActiveMQConnection* connection);
ActiveMQSession( connector::SessionInfo* sessionInfo,
const util::Properties& properties,
ActiveMQConnection* connection );
/**
* Destructor
*/
virtual ~ActiveMQSession(void);
virtual ~ActiveMQSession(void);
public: // Implements Mehtods
public: // Implements Mehtods
/**
* Closes the Session
* @throw CMSException
*/
virtual void close(void) throw ( cms::CMSException );
/**
* Closes the Session
* @throw CMSException
*/
virtual void close(void) throw ( cms::CMSException );
/**
* Commits all messages done in this transaction and releases any
* locks currently held.
* @throws CMSException
*/
virtual void commit(void) throw ( cms::CMSException );
/**
* Commits all messages done in this transaction and releases any
* locks currently held.
* @throws CMSException
*/
virtual void commit(void) throw ( cms::CMSException );
/**
* Rollsback all messages done in this transaction and releases any
* locks currently held.
* @throws CMSException
*/
virtual void rollback(void) throw ( cms::CMSException );
/**
* Rollsback all messages done in this transaction and releases any
* locks currently held.
* @throws CMSException
*/
virtual void rollback(void) throw ( cms::CMSException );
/**
* Creates a MessageConsumer for the specified destination.
* @param the Destination that this consumer receiving messages for.
* @throws CMSException
*/
virtual cms::MessageConsumer* createConsumer(cms::Destination& destination)
throw ( cms::CMSException );
/**
* Creates a MessageConsumer for the specified destination.
* @param the Destination that this consumer receiving messages for.
* @throws CMSException
*/
virtual cms::MessageConsumer* createConsumer(
const cms::Destination* destination )
throw ( cms::CMSException );
/**
* Creates a MessageConsumer for the specified destination, using a
* message selector.
* @param the Destination that this consumer receiving messages for.
* @throws CMSException
*/
virtual cms::MessageConsumer* createConsumer(cms::Destination& destination,
const std::string& selector)
throw ( cms::CMSException );
/**
* Creates a MessageConsumer for the specified destination, using a
* message selector.
* @param the Destination that this consumer receiving messages for.
* @throws CMSException
*/
virtual cms::MessageConsumer* createConsumer(
const cms::Destination* destination,
const std::string& selector )
throw ( cms::CMSException );
/**
* Creates a durable subscriber to the specified topic, using a
* message selector
* @param the topic to subscribe to
* @param name used to identify the subscription
* @param only messages matching the selector are received
* @throws CMSException
*/
virtual cms::MessageConsumer* createDurableConsumer(
cms::Topic& destination,
const std::string& name,
const std::string& selector,
bool noLocal = false)
/**
* Creates a durable subscriber to the specified topic, using a
* message selector
* @param the topic to subscribe to
* @param name used to identify the subscription
* @param only messages matching the selector are received
* @throws CMSException
*/
virtual cms::MessageConsumer* createDurableConsumer(
const cms::Topic* destination,
const std::string& name,
const std::string& selector,
bool noLocal = false )
throw ( cms::CMSException );
/**
* Creates a MessageProducer to send messages to the specified
* destination.
* @param the Destination to publish on
* @throws CMSException
*/
virtual cms::MessageProducer* createProducer(
const cms::Destination* destination )
throw ( cms::CMSException );
/**
* Creates a queue identity given a Queue name.
* @param the name of the new Queue
* @throws CMSException
*/
virtual cms::Queue* createQueue( const std::string& queueName )
throw ( cms::CMSException );
/**
* Creates a topic identity given a Queue name.
* @param the name of the new Topic
* @throws CMSException
*/
virtual cms::Topic* createTopic( const std::string& topicName )
throw ( cms::CMSException );
/**
* Creates a MessageProducer to send messages to the specified
* destination.
* @param the Destination to publish on
* @throws CMSException
*/
virtual cms::MessageProducer* createProducer(cms::Destination& destination)
throw ( cms::CMSException );
/**
* Creates a TemporaryQueue object.
* @throws CMSException
*/
virtual cms::TemporaryQueue* createTemporaryQueue(void)
throw ( cms::CMSException );
/**
* Creates a TemporaryTopic object.
* @throws CMSException
*/
virtual cms::TemporaryTopic* createTemporaryTopic(void)
throw ( cms::CMSException );
/**
* Creates a queue identity given a Queue name.
* @param the name of the new Queue
* @throws CMSException
*/
virtual cms::Queue* createQueue(const std::string& queueName)
throw ( cms::CMSException );
/**
* Creates a new Message
* @throws CMSException
*/
virtual cms::Message* createMessage(void)
throw ( cms::CMSException );
/**
* Creates a BytesMessage
* @throws CMSException
*/
virtual cms::BytesMessage* createBytesMessage(void)
throw ( cms::CMSException );
/**
* Creates a BytesMessage and sets the paylod to the passed value
* @param an array of bytes to set in the message
* @param the size of the bytes array, or number of bytes to use
* @throws CMSException
*/
virtual cms::BytesMessage* createBytesMessage(
const unsigned char* bytes,
unsigned long bytesSize )
throw ( cms::CMSException );
/**
* Creates a new TextMessage
* @throws CMSException
*/
virtual cms::TextMessage* createTextMessage(void)
throw ( cms::CMSException );
/**
* Creates a topic identity given a Queue name.
* @param the name of the new Topic
* @throws CMSException
*/
virtual cms::Topic* createTopic(const std::string& topicName)
throw ( cms::CMSException );
/**
* Creates a new TextMessage and set the text to the value given
* @param the initial text for the message
* @throws CMSException
*/
virtual cms::TextMessage* createTextMessage( const std::string& text )
throw ( cms::CMSException );
/**
* Creates a TemporaryQueue object.
* @throws CMSException
*/
virtual cms::TemporaryQueue* createTemporaryQueue(void)
throw ( cms::CMSException );
/**
* Creates a new TextMessage
* @throws CMSException
*/
virtual cms::MapMessage* createMapMessage(void)
throw ( cms::CMSException );
/**
* Creates a TemporaryTopic object.
* @throws CMSException
*/
virtual cms::TemporaryTopic* createTemporaryTopic(void)
throw ( cms::CMSException );
/**
* Creates a new Message
* @throws CMSException
*/
virtual cms::Message* createMessage(void)
throw ( cms::CMSException );
/**
* Creates a BytesMessage
* @throws CMSException
*/
virtual cms::BytesMessage* createBytesMessage(void)
throw ( cms::CMSException);
/**
* Creates a BytesMessage and sets the paylod to the passed value
* @param an array of bytes to set in the message
* @param the size of the bytes array, or number of bytes to use
* @throws CMSException
*/
virtual cms::BytesMessage* createBytesMessage(const unsigned char* bytes,
unsigned long bytesSize)
throw ( cms::CMSException);
/**
* Creates a new TextMessage
* @throws CMSException
*/
virtual cms::TextMessage* createTextMessage(void)
throw ( cms::CMSException );
/**
* Returns the acknowledgement mode of the session.
* @return the Sessions Acknowledge Mode
*/
virtual cms::Session::AcknowledgeMode getAcknowledgeMode(void) const;
/**
* Creates a new TextMessage and set the text to the value given
* @param the initial text for the message
* @throws CMSException
*/
virtual cms::TextMessage* createTextMessage(const std::string& text)
throw ( cms::CMSException );
/**
* Creates a new TextMessage
* @throws CMSException
*/
virtual cms::MapMessage* createMapMessage(void)
throw ( cms::CMSException );
/**
* Returns the acknowledgement mode of the session.
* @return the Sessions Acknowledge Mode
*/
virtual cms::Session::AcknowledgeMode getAcknowledgeMode(void) const;
/**
* Gets if the Sessions is a Transacted Session
* @return transacted true - false.
*/
virtual bool isTransacted(void) const;
/**
* Gets if the Sessions is a Transacted Session
* @return transacted true - false.
*/
virtual bool isTransacted(void) const;
public: // ActiveMQSession specific Methods
/**
* Sends a message from the Producer specified
* @param cms::Message pointer
* @param Producer Information
* @throws CMSException
*/
virtual void send(cms::Message* message, ActiveMQProducer* producer)
throw ( cms::CMSException );
/**
* Sends a message from the Producer specified
* @param cms::Message pointer
* @param Producer Information
* @throws CMSException
*/
virtual void send( cms::Message* message, ActiveMQProducer* producer )
throw ( cms::CMSException );
/**
* When a ActiveMQ core object is closed or destroyed it should call
* back and let the session know that it is going away, this allows
* the session to clean up any associated resources. This method
* destroy's the data that is associated with a Producer object
* @param The Producer that is being destoryed
* @throw CMSException
*/
virtual void onDestroySessionResource( ActiveMQSessionResource* resource )
throw ( cms::CMSException );
/**
* When a ActiveMQ core object is closed or destroyed it should call
* back and let the session know that it is going away, this allows
* the session to clean up any associated resources. This method
* destroy's the data that is associated with a Producer object
* @param The Producer that is being destoryed
* @throw CMSException
*/
virtual void onDestroySessionResource( ActiveMQSessionResource* resource )
throw ( cms::CMSException );
/**
* Called to acknowledge the receipt of a message.
* @param The consumer that received the message
* @param The Message to acknowledge.
* @throws CMSException
*/
virtual void acknowledge(ActiveMQConsumer* consumer,
ActiveMQMessage* message)
throw ( cms::CMSException);
/**
* Called to acknowledge the receipt of a message.
* @param The consumer that received the message
* @param The Message to acknowledge.
* @throws CMSException
*/
virtual void acknowledge( ActiveMQConsumer* consumer,
ActiveMQMessage* message )
throw ( cms::CMSException );
/**
* This method gets any registered exception listener of this sessions
* connection and returns it. Mainly intended for use by the objects
* that this session creates so that they can notify the client of
* exceptions that occur in the context of another thread.
* @returns cms::ExceptionListener pointer or NULL
*/
virtual cms::ExceptionListener* getExceptionListener(void);
/**
* This method gets any registered exception listener of this sessions
* connection and returns it. Mainly intended for use by the objects
* that this session creates so that they can notify the client of
* exceptions that occur in the context of another thread.
* @returns cms::ExceptionListener pointer or NULL
*/
virtual cms::ExceptionListener* getExceptionListener(void);
/**
* Gets the Session Information object for this session, if the
* session is closed than this returns null
* @return SessionInfo Pointer
*/
virtual connector::SessionInfo* getSessionInfo(void) {
return sessionInfo;
}
/**
* Gets the Session Information object for this session, if the
* session is closed than this returns null
* @return SessionInfo Pointer
*/
virtual connector::SessionInfo* getSessionInfo(void) {
return sessionInfo;
}
};

View File

@ -26,7 +26,7 @@ namespace core{
{
public:
virtual ~ActiveMQSessionResource(void) {}
virtual ~ActiveMQSessionResource(void) {}
/**
* Retrieve the Connector resource that is associated with

View File

@ -41,7 +41,7 @@ ActiveMQTransaction::ActiveMQTransaction( ActiveMQConnection* connection,
{
try
{
if(connection == NULL || session == NULL)
if( connection == NULL || session == NULL )
{
throw NullPointerException(
__FILE__, __LINE__,
@ -56,9 +56,9 @@ ActiveMQTransaction::ActiveMQTransaction( ActiveMQConnection* connection,
// convert from property Strings to int.
redeliveryDelay = Integer::parseInt(
properties.getProperty("transaction.redeliveryDelay", "25") );
properties.getProperty( "transaction.redeliveryDelay", "25" ) );
maxRedeliveries = Integer::parseInt(
properties.getProperty("transaction.maxRedeliveryCount", "5") );
properties.getProperty( "transaction.maxRedeliveryCount", "5" ) );
// Start a new Transaction
transactionInfo = connection->getConnectionData()->
@ -76,16 +76,16 @@ ActiveMQTransaction::~ActiveMQTransaction(void)
// Inform the connector we are rolling back before we close so that
// the provider knows we didn't complete this transaction
connection->getConnectionData()->getConnector()->
rollback(transactionInfo, session->getSessionInfo());
rollback( transactionInfo, session->getSessionInfo() );
// Clean up
clearTransaction();
// Must allow all the tasks to complete before we destruct otherwise
// the callbacks will cause an exception.
synchronized(&tasksDone)
synchronized( &tasksDone )
{
while(taskCount != 0)
while( taskCount != 0 )
{
tasksDone.wait(1000);
@ -102,24 +102,24 @@ void ActiveMQTransaction::clearTransaction(void)
{
try
{
if(transactionInfo != NULL)
if( transactionInfo != NULL )
{
// Dispose of the ProducerInfo
connection->getConnectionData()->
getConnector()->destroyResource(transactionInfo);
getConnector()->destroyResource( transactionInfo );
}
synchronized(&rollbackLock)
synchronized( &rollbackLock )
{
// If there are any messages that are being transacted, then
// they die once and for all here.
RollbackMap::iterator itr = rollbackMap.begin();
for(; itr != rollbackMap.end(); ++itr)
for( ; itr != rollbackMap.end(); ++itr )
{
MessageList::iterator msgItr = itr->second.begin();
for(; msgItr != itr->second.end(); ++msgItr)
for( ; msgItr != itr->second.end(); ++msgItr )
{
delete *msgItr;
}
@ -136,10 +136,10 @@ void ActiveMQTransaction::clearTransaction(void)
void ActiveMQTransaction::addToTransaction( ActiveMQMessage* message,
ActiveMQMessageListener* listener )
{
synchronized(&rollbackLock)
synchronized( &rollbackLock )
{
// Store in the Multi Map
rollbackMap[listener].push_back(message);
rollbackMap[listener].push_back( message );
}
}
@ -151,7 +151,7 @@ void ActiveMQTransaction::removeFromTransaction(
{
// Delete all the messages, then remove the consumer's entry from
// the Rollback Map.
synchronized(&rollbackLock)
synchronized( &rollbackLock )
{
RollbackMap::iterator rb_itr = rollbackMap.find( listener );
@ -162,13 +162,13 @@ void ActiveMQTransaction::removeFromTransaction(
MessageList::iterator itr = rb_itr->second.begin();
for(; itr != rollbackMap[listener].end(); ++itr)
for( ; itr != rollbackMap[listener].end(); ++itr )
{
delete *itr;
}
// Erase the entry from the map
rollbackMap.erase(listener);
rollbackMap.erase( listener );
}
}
AMQ_CATCH_RETHROW( ActiveMQException )
@ -180,7 +180,7 @@ void ActiveMQTransaction::commit(void) throw ( exceptions::ActiveMQException )
{
try
{
if(this->transactionInfo == NULL)
if( this->transactionInfo == NULL )
{
throw InvalidStateException(
__FILE__, __LINE__,
@ -208,7 +208,7 @@ void ActiveMQTransaction::rollback(void) throw ( exceptions::ActiveMQException )
{
try
{
if(this->transactionInfo == NULL)
if( this->transactionInfo == NULL )
{
throw InvalidStateException(
__FILE__, __LINE__,
@ -222,7 +222,7 @@ void ActiveMQTransaction::rollback(void) throw ( exceptions::ActiveMQException )
// Dispose of the ProducerInfo
connection->getConnectionData()->
getConnector()->destroyResource(transactionInfo);
getConnector()->destroyResource( transactionInfo );
// Start a new Transaction
transactionInfo = connection->getConnectionData()->
@ -235,7 +235,7 @@ void ActiveMQTransaction::rollback(void) throw ( exceptions::ActiveMQException )
// doesn't have to wait on this method to complete an release its
// mutex so it can dispatch new messages. That would however requre
// copying the whole map over to the thread.
synchronized(&rollbackLock)
synchronized( &rollbackLock )
{
RollbackMap::iterator itr = rollbackMap.begin();
@ -247,7 +247,7 @@ void ActiveMQTransaction::rollback(void) throw ( exceptions::ActiveMQException )
session,
itr->second,
maxRedeliveries,
redeliveryDelay) , this));
redeliveryDelay ) , this ) );
// Count the tasks started.
taskCount++;
@ -273,9 +273,9 @@ void ActiveMQTransaction::onTaskComplete( Runnable* task )
taskCount--;
if(taskCount == 0)
if( taskCount == 0 )
{
synchronized(&tasksDone)
synchronized( &tasksDone )
{
tasksDone.notifyAll();
}
@ -292,12 +292,12 @@ void ActiveMQTransaction::onTaskException( Runnable* task,
try
{
// Delegate
onTaskComplete(task);
onTaskComplete( task );
// Route the Error
ExceptionListener* listener = connection->getExceptionListener();
if(listener != NULL)
if( listener != NULL )
{
listener->onException( ex );
}
@ -313,20 +313,20 @@ void ActiveMQTransaction::RollbackTask::run(void)
{
MessageList::iterator itr = messages.begin();
for(; itr != messages.end(); ++itr)
for( ; itr != messages.end(); ++itr )
{
(*itr)->setRedeliveryCount((*itr)->getRedeliveryCount() + 1);
( *itr )->setRedeliveryCount( ( *itr )->getRedeliveryCount() + 1 );
// Redeliver Messages at some point in the future
Thread::sleep(redeliveryDelay);
Thread::sleep( redeliveryDelay );
if((*itr)->getRedeliveryCount() >= maxRedeliveries)
if( ( *itr )->getRedeliveryCount() >= maxRedeliveries )
{
// Poison Ack the Message, we give up processing this one
connection->getConnectionData()->getConnector()->
acknowledge(
session->getSessionInfo(),
dynamic_cast< Message* >(*itr),
dynamic_cast< Message* >( *itr ),
Connector::PoisonAck );
// Won't redeliver this so we kill it here.
@ -335,7 +335,7 @@ void ActiveMQTransaction::RollbackTask::run(void)
return;
}
listener->onActiveMQMessage(*itr);
listener->onActiveMQMessage( *itr );
}
}
AMQ_CATCH_RETHROW( ActiveMQException )

View File

@ -107,10 +107,7 @@ namespace core{
ActiveMQSession* session,
const util::Properties& properties );
/**
* Destructor
*/
virtual ~ActiveMQTransaction(void);
virtual ~ActiveMQTransaction(void);
/**
* Adds the Message as a part of the Transaction for the specified

View File

@ -39,6 +39,11 @@ void ActiveMQException::buildMessage(const char* format, va_list& vargs)
// Guessed size was enough. Assign the string.
message.assign (buffer, written);
// assign isn't passing ownership, just copying, delete
// the allocated buffer.
delete buffer;
break;
}

View File

@ -25,151 +25,153 @@
namespace activemq{
namespace exceptions{
/*
* Base class for all exceptions.
*/
class ActiveMQException : public cms::CMSException
{
private:
/*
* Base class for all exceptions.
*/
class ActiveMQException : public cms::CMSException
{
private:
/**
* The cause of this exception.
*/
std::string message;
/**
* The stack trace.
*/
std::vector< std::pair< std::string, int> > stackTrace;
public:
/**
* Default Constructor
*/
ActiveMQException(void) {}
/**
* Copy Constructor
*/
ActiveMQException( const ActiveMQException& ex ){
*this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
ActiveMQException(const char* file, const int lineNumber,
const char* msg, ...)
{
va_list vargs ;
va_start(vargs, msg) ;
buildMessage(msg, vargs) ;
// Set the first mark for this exception.
setMark( file, lineNumber );
}
/**
* The cause of this exception.
*/
std::string message;
/**
* Destructor
*/
virtual ~ActiveMQException(){}
/**
* The stack trace.
*/
std::vector< std::pair< std::string, int> > stackTrace;
/**
* Gets the message for this exception.
*/
virtual const char* getMessage() const{ return message.c_str(); }
public:
/**
* Default Constructor
*/
ActiveMQException(void) {}
/**
* Copy Constructor
*/
ActiveMQException( const ActiveMQException& ex ){
*this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
ActiveMQException( const char* file, const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start( vargs, msg ) ;
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark( file, lineNumber );
}
virtual ~ActiveMQException(){}
/**
* Sets the cause for this exception.
* @param msg the format string for the msg.
*/
virtual void setMessage( const char* msg, ... ){
va_list vargs ;
va_start(vargs, msg) ;
buildMessage(msg, vargs) ;
}
/**
* Adds a file/line number to the stack trace.
* @param file The name of the file calling this method (use __FILE__).
* @param lineNumber The line number in the calling file (use __LINE__).
*/
virtual void setMark( const char* file, const int lineNumber );
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone() const{
return new ActiveMQException( *this );
}
/**
* Provides the stack trace for every point where
* this exception was caught, marked, and rethrown. The first
* item in the returned vector is the first point where the mark
* was set (e.g. where the exception was created).
* @return the stack trace.
*/
virtual std::vector< std::pair< std::string, int> > getStackTrace() const{
return stackTrace;
}
/**
* Prints the stack trace to std::err
*/
virtual void printStackTrace() const{
printStackTrace( std::cerr );
}
/**
* Prints the stack trace to the given output stream.
* @param stream the target output stream.
*/
virtual void printStackTrace( std::ostream& stream ) const{
stream << getStackTraceString();
}
/**
* Gets the stack trace as one contiguous string.
*/
virtual std::string getStackTraceString() const{
// Create the output stream.
std::ostringstream stream;
// Write the message and each stack entry.
stream << message << std::endl;
for( unsigned int ix=0; ix<stackTrace.size(); ++ix ){
stream << "\tFILE: " << stackTrace[ix].first;
stream << ", LINE: " << stackTrace[ix].second;
stream << std::endl;
}
// Return the string from the output stream.
return stream.str();
}
/**
* Assignment operator.
*/
virtual ActiveMQException& operator =( const ActiveMQException& ex ){
this->message = ex.message;
this->stackTrace = ex.stackTrace;
return *this;
}
protected:
/**
* Gets the message for this exception.
* @return Text formatted error message
*/
virtual const char* getMessage() const{ return message.c_str(); }
virtual void buildMessage(const char* format, va_list& vargs);
/**
* Sets the cause for this exception.
* @param msg the format string for the msg.
* @param variable - params to format into the string
*/
virtual void setMessage( const char* msg, ... ){
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
}
/**
* Adds a file/line number to the stack trace.
* @param file The name of the file calling this method (use __FILE__).
* @param lineNumber The line number in the calling file (use __LINE__).
*/
virtual void setMark( const char* file, const int lineNumber );
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
* @return Copy of this Exception object
*/
virtual ActiveMQException* clone() const{
return new ActiveMQException( *this );
}
/**
* Provides the stack trace for every point where
* this exception was caught, marked, and rethrown. The first
* item in the returned vector is the first point where the mark
* was set (e.g. where the exception was created).
* @return the stack trace.
*/
virtual std::vector< std::pair< std::string, int> > getStackTrace() const{
return stackTrace;
}
/**
* Prints the stack trace to std::err
*/
virtual void printStackTrace() const{
printStackTrace( std::cerr );
}
/**
* Prints the stack trace to the given output stream.
* @param stream the target output stream.
*/
virtual void printStackTrace( std::ostream& stream ) const{
stream << getStackTraceString();
}
/**
* Gets the stack trace as one contiguous string.
* @return string with formatted stack trace data
*/
virtual std::string getStackTraceString() const{
// Create the output stream.
std::ostringstream stream;
// Write the message and each stack entry.
stream << message << std::endl;
for( unsigned int ix=0; ix<stackTrace.size(); ++ix ){
stream << "\tFILE: " << stackTrace[ix].first;
stream << ", LINE: " << stackTrace[ix].second;
stream << std::endl;
}
// Return the string from the output stream.
return stream.str();
}
/**
* Assignment operator.
* @param const reference to another ActiveMQException
*/
virtual ActiveMQException& operator =( const ActiveMQException& ex ){
this->message = ex.message;
this->stackTrace = ex.stackTrace;
return *this;
}
protected:
virtual void buildMessage( const char* format, va_list& vargs );
};

View File

@ -22,68 +22,65 @@
namespace activemq{
namespace exceptions{
/*
* Thrown when an error occurs from calling a method from syncronizable
* and the caller doesn't hold a lock on the object.
*/
class IllegalMonitorStateException : public ActiveMQException
{
public:
/*
* Thrown when an error occurs from calling a method from syncronizable
* and the caller doesn't hold a lock on the object.
*/
class IllegalMonitorStateException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
IllegalMonitorStateException(void) {};
/**
* Default Constructor
*/
IllegalMonitorStateException(void) {};
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
IllegalMonitorStateException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
IllegalMonitorStateException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
IllegalMonitorStateException(const IllegalMonitorStateException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
IllegalMonitorStateException(const IllegalMonitorStateException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
IllegalMonitorStateException(const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
IllegalMonitorStateException( const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
// Set the first mark for this exception.
setMark(file, lineNumber);
}
// Set the first mark for this exception.
setMark(file, lineNumber);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new IllegalMonitorStateException(*this);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new IllegalMonitorStateException(*this);
}
/**
* Destructor
*/
virtual ~IllegalMonitorStateException(void) {}
virtual ~IllegalMonitorStateException(void) {}
};

View File

@ -22,67 +22,64 @@
namespace activemq{
namespace exceptions{
/*
* Thrown when an Thread is interrupted during a wait.
*/
class InterruptedException : public ActiveMQException
{
public:
/*
* Thrown when an Thread is interrupted during a wait.
*/
class InterruptedException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
InterruptedException(void) {};
/**
* Default Constructor
*/
InterruptedException(void) {};
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
InterruptedException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
InterruptedException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
InterruptedException(const InterruptedException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
InterruptedException(const InterruptedException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
InterruptedException(const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
InterruptedException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
// Set the first mark for this exception.
setMark(file, lineNumber);
}
// Set the first mark for this exception.
setMark(file, lineNumber);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new InterruptedException(*this);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new InterruptedException(*this);
}
/**
* Destructor
*/
virtual ~InterruptedException(void) {}
virtual ~InterruptedException(void) {}
};

View File

@ -22,70 +22,67 @@
namespace activemq{
namespace exceptions{
/*
* Thrown when an operation is requested, but the state of the object
* servicing the request is not correct for that request.
*/
class InvalidStateException : public ActiveMQException
{
public:
/*
* Thrown when an operation is requested, but the state of the object
* servicing the request is not correct for that request.
*/
class InvalidStateException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
InvalidStateException(void) {}
/**
* Default Constructor
*/
InvalidStateException(void) {}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
InvalidStateException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
InvalidStateException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
InvalidStateException(const InvalidStateException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
InvalidStateException( const InvalidStateException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
InvalidStateException(const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
InvalidStateException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start( vargs, msg );
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark(file, lineNumber);
}
// Set the first mark for this exception.
setMark( file, lineNumber );
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new InvalidStateException(*this);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new InvalidStateException(*this);
}
/**
* Destructor
*/
virtual ~InvalidStateException(void) {}
virtual ~InvalidStateException(void) {}
};
};
}}

View File

@ -22,70 +22,67 @@
namespace activemq{
namespace exceptions{
/*
* Thrown from an operation that attempts to access some element that does
* not exist.
*/
class NoSuchElementException : public ActiveMQException
{
public:
/*
* Thrown from an operation that attempts to access some element that does
* not exist.
*/
class NoSuchElementException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
NoSuchElementException(void) {};
/**
* Default Constructor
*/
NoSuchElementException(void) {};
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
NoSuchElementException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
NoSuchElementException( const ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
NoSuchElementException(const NoSuchElementException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
NoSuchElementException( const NoSuchElementException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
NoSuchElementException(const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
NoSuchElementException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start( vargs, msg );
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark(file, lineNumber);
}
// Set the first mark for this exception.
setMark( file, lineNumber );
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new NoSuchElementException(*this);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new NoSuchElementException(*this);
}
/**
* Destructor
*/
virtual ~NoSuchElementException(void) {}
virtual ~NoSuchElementException(void) {}
};
};
}}

View File

@ -22,69 +22,66 @@
namespace activemq{
namespace exceptions{
/*
* Thrown when an error occurs that involves a pointer being NULL
*/
class NullPointerException : public ActiveMQException
{
public:
/*
* Thrown when an error occurs that involves a pointer being NULL
*/
class NullPointerException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
NullPointerException(void) {};
/**
* Default Constructor
*/
NullPointerException(void) {};
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
NullPointerException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
NullPointerException( const ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
NullPointerException(const NullPointerException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
NullPointerException(const NullPointerException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
NullPointerException(const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
NullPointerException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start( vargs, msg );
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark(file, lineNumber);
}
// Set the first mark for this exception.
setMark( file, lineNumber );
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new NullPointerException(*this);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new NullPointerException( *this );
}
/**
* Destructor
*/
virtual ~NullPointerException(void) {}
virtual ~NullPointerException(void) {}
};
};
}}

View File

@ -22,71 +22,68 @@
namespace activemq{
namespace exceptions{
/*
* Thrown when an error occurs that involves something in the run time
* This could be a memory allocation exception or some other generally
* unrecoverable exception.
*/
class RuntimeException : public ActiveMQException
{
public:
/*
* Thrown when an error occurs that involves something in the run time
* This could be a memory allocation exception or some other generally
* unrecoverable exception.
*/
class RuntimeException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
RuntimeException(void) {};
/**
* Default Constructor
*/
RuntimeException(void) {};
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
RuntimeException(const ActiveMQException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
RuntimeException( const ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
RuntimeException(const RuntimeException& ex){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
RuntimeException( const RuntimeException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
RuntimeException(const char* file,
const int lineNumber,
const char* msg, ...)
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
RuntimeException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start(vargs, msg);
buildMessage(msg, vargs);
// Set the first mark for this exception.
setMark(file, lineNumber);
}
// Set the first mark for this exception.
setMark(file, lineNumber);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new RuntimeException(*this);
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone(void) const{
return new RuntimeException( *this );
}
/**
* Destructor
*/
virtual ~RuntimeException(void) {}
virtual ~RuntimeException(void) {}
};
};
}}

View File

@ -22,68 +22,66 @@
namespace activemq{
namespace exceptions{
/*
* Thrown when an unsupported method is called.
*/
class UnsupportedOperationException : public ActiveMQException
{
public:
/*
* Thrown when an unsupported method is called.
*/
class UnsupportedOperationException : public ActiveMQException
{
public:
/**
* Default Constructor
*/
UnsupportedOperationException(void) {};
/**
* Default Constructor
*/
UnsupportedOperationException(void) {};
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
UnsupportedOperationException( const ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Conversion Constructor from some other ActiveMQException
* @param An exception that should become this type of Exception
*/
UnsupportedOperationException( const ActiveMQException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
UnsupportedOperationException( const UnsupportedOperationException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Copy Constructor
*/
UnsupportedOperationException( const UnsupportedOperationException& ex ){
*(ActiveMQException*)this = ex;
}
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
UnsupportedOperationException(const char* file, const int lineNumber,
const char* msg, ...)
{
va_list vargs ;
va_start(vargs, msg) ;
buildMessage(msg, vargs) ;
/**
* Constructor - Initializes the file name and line number where
* this message occured. Sets the message to report, using an
* optional list of arguments to parse into the message
* @param file name where exception occurs
* @param line number where the exception occurred.
* @param message to report
* @param list of primitives that are formatted into the message
*/
UnsupportedOperationException( const char* file,
const int lineNumber,
const char* msg, ... )
{
va_list vargs;
va_start( vargs, msg );
buildMessage( msg, vargs );
// Set the first mark for this exception.
setMark( file, lineNumber );
}
// Set the first mark for this exception.
setMark( file, lineNumber );
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone() const{
return new UnsupportedOperationException( *this );
}
/**
* Clones this exception. This is useful for cases where you need
* to preserve the type of the original exception as well as the message.
* All subclasses should override.
*/
virtual ActiveMQException* clone() const{
return new UnsupportedOperationException( *this );
}
/**
* Destructor
*/
virtual ~UnsupportedOperationException(){}
virtual ~UnsupportedOperationException(){}
};
};
}}

View File

@ -24,15 +24,15 @@ using namespace std;
////////////////////////////////////////////////////////////////////////////////
BufferedInputStream::BufferedInputStream( InputStream* stream )
{
// Default to a 1k buffer.
init( stream, 1024 );
// Default to a 1k buffer.
init( stream, 1024 );
}
////////////////////////////////////////////////////////////////////////////////
BufferedInputStream::BufferedInputStream( InputStream* stream,
const int bufferSize )
const int bufferSize )
{
init( stream, bufferSize );
init( stream, bufferSize );
}
////////////////////////////////////////////////////////////////////////////////
@ -47,99 +47,99 @@ BufferedInputStream::~BufferedInputStream()
////////////////////////////////////////////////////////////////////////////////
void BufferedInputStream::init( InputStream* stream, const int bufferSize ){
this->stream = stream;
this->bufferSize = bufferSize;
// Create the buffer and initialize the head and tail positions.
buffer = new unsigned char[bufferSize];
head = 0;
tail = 0;
this->stream = stream;
this->bufferSize = bufferSize;
// Create the buffer and initialize the head and tail positions.
buffer = new unsigned char[bufferSize];
head = 0;
tail = 0;
}
////////////////////////////////////////////////////////////////////////////////
void BufferedInputStream::close() throw(cms::CMSException){
// Close the delegate stream.
stream->close();
void BufferedInputStream::close() throw( cms::CMSException ){
// Close the delegate stream.
stream->close();
}
////////////////////////////////////////////////////////////////////////////////
unsigned char BufferedInputStream::read() throw (IOException){
// If we don't have any data buffered yet - read as much as we can.
if( tail == head ){
bufferData();
}
// Get the next character.
char returnValue = buffer[head++];
// If the buffer is now empty - reset it to the beginning of the buffer.
if( tail == head ){
tail = head = 0;
}
return returnValue;
unsigned char BufferedInputStream::read() throw ( IOException ){
// If we don't have any data buffered yet - read as much as we can.
if( tail == head ){
bufferData();
}
// Get the next character.
char returnValue = buffer[head++];
// If the buffer is now empty - reset it to the beginning of the buffer.
if( tail == head ){
tail = head = 0;
}
return returnValue;
}
////////////////////////////////////////////////////////////////////////////////
int BufferedInputStream::read( unsigned char* buffer,
const int bufferSize ) throw (IOException){
// If we still haven't filled the output buffer AND there is data
// on the input stream to be read, read a buffer's
// worth from the stream.
int totalRead = 0;
while( totalRead < bufferSize ){
// Get the remaining bytes to copy.
int bytesToCopy = min( tail-head, (bufferSize-totalRead) );
// Copy the data to the output buffer.
memcpy( buffer+totalRead, this->buffer+head, bytesToCopy );
// Increment the total bytes read.
totalRead += bytesToCopy;
// Increment the head position. If the buffer is now empty,
// reset the positions and buffer more data.
head += bytesToCopy;
if( head == tail ){
// Reset the buffer indicies.
head = tail = 0;
// If there is no more data currently available on the
// input stream, stop the loop.
if( stream->available() == 0 ){
break;
}
// Buffer as much data as we can.
bufferData();
}
}
// Return the total number of bytes read.
return totalRead;
const int bufferSize ) throw ( IOException ){
// If we still haven't filled the output buffer AND there is data
// on the input stream to be read, read a buffer's
// worth from the stream.
int totalRead = 0;
while( totalRead < bufferSize ){
// Get the remaining bytes to copy.
int bytesToCopy = min( tail-head, (bufferSize-totalRead) );
// Copy the data to the output buffer.
memcpy( buffer+totalRead, this->buffer+head, bytesToCopy );
// Increment the total bytes read.
totalRead += bytesToCopy;
// Increment the head position. If the buffer is now empty,
// reset the positions and buffer more data.
head += bytesToCopy;
if( head == tail ){
// Reset the buffer indicies.
head = tail = 0;
// If there is no more data currently available on the
// input stream, stop the loop.
if( stream->available() == 0 ){
break;
}
// Buffer as much data as we can.
bufferData();
}
}
// Return the total number of bytes read.
return totalRead;
}
////////////////////////////////////////////////////////////////////////////////
void BufferedInputStream::bufferData() throw (IOException){
if( tail == bufferSize ){
throw IOException( __FILE__, __LINE__,
void BufferedInputStream::bufferData() throw ( IOException ){
if( tail == bufferSize ){
throw IOException( __FILE__, __LINE__,
"BufferedInputStream::bufferData - buffer full" );
}
// Read in as many bytes as we can.
int bytesRead = stream->read( buffer+tail, bufferSize-tail );
if( bytesRead == 0 ){
throw IOException( __FILE__, __LINE__,
}
// Read in as many bytes as we can.
int bytesRead = stream->read( buffer+tail, bufferSize-tail );
if( bytesRead == 0 ){
throw IOException( __FILE__, __LINE__,
"BufferedInputStream::read() - failed reading bytes from stream");
}
// Increment the tail to the new end position.
tail += bytesRead;
}
// Increment the tail to the new end position.
tail += bytesRead;
}

View File

@ -24,167 +24,174 @@
namespace activemq{
namespace io{
/**
* A wrapper around another input stream that performs
* a buffered read, where it reads more data than it needs
* in order to reduce the number of io operations on the
* input stream.
*/
class BufferedInputStream : public InputStream
{
private:
/**
* A wrapper around another input stream that performs
* a buffered read, where it reads more data than it needs
* in order to reduce the number of io operations on the
* input stream.
*/
class BufferedInputStream : public InputStream
{
private:
/**
* The target input stream.
*/
InputStream* stream;
/**
* The target input stream.
*/
InputStream* stream;
/**
* The internal buffer.
*/
unsigned char* buffer;
/**
* The internal buffer.
*/
unsigned char* buffer;
/**
* The buffer size.
*/
int bufferSize;
/**
* The buffer size.
*/
int bufferSize;
/**
* The current head of the buffer.
*/
int head;
/**
* The current head of the buffer.
*/
int head;
/**
* The current tail of the buffer.
*/
int tail;
/**
* The current tail of the buffer.
*/
int tail;
public:
public:
/**
* Constructor
* @param stream The target input stream.
*/
BufferedInputStream( InputStream* stream );
/**
* Constructor
* @param stream The target input stream.
*/
BufferedInputStream( InputStream* stream );
/**
* Constructor
* @param stream the target input stream
* @param bufferSize the size for the internal buffer.
*/
BufferedInputStream( InputStream* stream, const int bufferSize );
/**
* Constructor
* @param stream the target input stream
* @param bufferSize the size for the internal buffer.
*/
BufferedInputStream( InputStream* stream, const int bufferSize );
/**
* Destructor.
*/
virtual ~BufferedInputStream();
virtual ~BufferedInputStream();
/**
* Locks the object.
*/
virtual void lock() throw(exceptions::ActiveMQException){
assert( stream != NULL );
stream->lock();
}
/**
* Locks the object.
* throws ActiveMQException
*/
virtual void lock() throw( exceptions::ActiveMQException ){
assert( stream != NULL );
stream->lock();
}
/**
* Unlocks the object.
*/
virtual void unlock() throw(exceptions::ActiveMQException){
assert( stream != NULL );
stream->unlock();
}
/**
* Unlocks the object.
* throws ActiveMQException
*/
virtual void unlock() throw( exceptions::ActiveMQException ){
assert( stream != NULL );
stream->unlock();
}
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling.
*/
virtual void wait() throw(exceptions::ActiveMQException){
assert( stream != NULL );
stream->wait();
}
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling.
* throws ActiveMQException
*/
virtual void wait() throw( exceptions::ActiveMQException ){
assert( stream != NULL );
stream->wait();
}
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling. This wait will timeout after the specified time
* interval.
* @param time in millisecsonds to wait, or WAIT_INIFINITE
* @throws ActiveMQException
*/
virtual void wait(unsigned long millisecs)
throw(exceptions::ActiveMQException) {
/**
* Waits on a signal from this object, which is generated
* by a call to Notify. Must have this object locked before
* calling. This wait will timeout after the specified time
* interval.
* @param time in millisecsonds to wait, or WAIT_INIFINITE
* @throws ActiveMQException
*/
virtual void wait( unsigned long millisecs )
throw( exceptions::ActiveMQException ) {
assert( stream != NULL );
stream->wait(millisecs);
}
assert( stream != NULL );
stream->wait(millisecs);
}
/**
* Signals a waiter on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
*/
virtual void notify() throw(exceptions::ActiveMQException){
assert( stream != NULL );
stream->notify();
}
/**
* Signals a waiter on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
* throws ActiveMQException
*/
virtual void notify() throw( exceptions::ActiveMQException ){
assert( stream != NULL );
stream->notify();
}
/**
* Signals the waiters on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
*/
virtual void notifyAll() throw(exceptions::ActiveMQException){
assert( stream != NULL );
stream->notifyAll();
}
/**
* Signals the waiters on this object that it can now wake
* up and continue. Must have this object locked before
* calling.
* throws ActiveMQException
*/
virtual void notifyAll() throw( exceptions::ActiveMQException ){
assert( stream != NULL );
stream->notifyAll();
}
/**
* Indcates the number of bytes avaialable.
* @return the sum of the amount of data avalable
* in the buffer and the data available on the target
* input stream.
*/
virtual int available() const{
return (tail-head)+stream->available();
}
/**
* Indcates the number of bytes avaialable.
* @return the sum of the amount of data avalable
* in the buffer and the data available on the target
* input stream.
*/
virtual int available() const{
return ( tail - head ) + stream->available();
}
/**
* Reads a single byte from the buffer.
* @return The next byte.
* @throws IOException thrown if an error occurs.
*/
virtual unsigned char read() throw (IOException);
/**
* Reads a single byte from the buffer.
* @return The next byte.
* @throws IOException thrown if an error occurs.
*/
virtual unsigned char read() throw ( IOException );
/**
* Reads an array of bytes from the buffer.
* @param buffer (out) the target buffer.
* @param bufferSize the size of the output buffer.
* @return The number of bytes read.
* @throws IOException thrown if an error occurs.
*/
virtual int read( unsigned char* buffer, const int bufferSize ) throw (IOException);
/**
* Reads an array of bytes from the buffer.
* @param buffer (out) the target buffer.
* @param bufferSize the size of the output buffer.
* @return The number of bytes read.
* @throws IOException thrown if an error occurs.
*/
virtual int read( unsigned char* buffer, const int bufferSize )
throw ( IOException );
/**
* Closes the target input stream.
*/
virtual void close(void) throw(cms::CMSException);
/**
* Closes the target input stream.
* @throws CMSException
*/
virtual void close(void) throw( cms::CMSException );
private:
private:
/**
* Initializes the internal structures.
*/
void init( InputStream* stream, const int bufferSize );
/**
* Initializes the internal structures.
* @param stream to read from
* @param size of buffer to allocate
*/
void init( InputStream* stream, const int bufferSize );
/**
* Populates the buffer with as much data as possible
* from the target input stream.
*/
void bufferData(void) throw (IOException);
/**
* Populates the buffer with as much data as possible
* from the target input stream.
* @throws CMSException
*/
void bufferData(void) throw ( IOException );
};
};
}}

View File

@ -24,15 +24,15 @@ using namespace std;
////////////////////////////////////////////////////////////////////////////////
BufferedOutputStream::BufferedOutputStream( OutputStream* stream )
{
// Default to 1k buffer.
init( stream, 1024 );
// Default to 1k buffer.
init( stream, 1024 );
}
////////////////////////////////////////////////////////////////////////////////
BufferedOutputStream::BufferedOutputStream( OutputStream* stream,
const int bufSize )
const int bufSize )
{
init( stream, bufSize );
init( stream, bufSize );
}
////////////////////////////////////////////////////////////////////////////////
@ -47,75 +47,74 @@ BufferedOutputStream::~BufferedOutputStream()
////////////////////////////////////////////////////////////////////////////////
void BufferedOutputStream::init( OutputStream* stream, const int bufSize ){
this->stream = stream;
this->bufferSize = bufSize;
buffer = new unsigned char[bufSize];
head = tail = 0;
this->stream = stream;
this->bufferSize = bufSize;
buffer = new unsigned char[bufSize];
head = tail = 0;
}
////////////////////////////////////////////////////////////////////////////////
void BufferedOutputStream::close() throw(cms::CMSException){
// Flush this stream.
flush();
// Close the delegate stream.
stream->close();
void BufferedOutputStream::close() throw( cms::CMSException ){
// Flush this stream.
flush();
// Close the delegate stream.
stream->close();
}
////////////////////////////////////////////////////////////////////////////////
void BufferedOutputStream::emptyBuffer() throw (IOException){
if( head != tail ){
stream->write( buffer+head, tail-head );
}
head = tail = 0;
void BufferedOutputStream::emptyBuffer() throw ( IOException ){
if( head != tail ){
stream->write( buffer+head, tail-head );
}
head = tail = 0;
}
////////////////////////////////////////////////////////////////////////////////
void BufferedOutputStream::flush() throw (IOException){
// Empty the contents of the buffer to the output stream.
emptyBuffer();
// Flush the output stream.
stream->flush();
void BufferedOutputStream::flush() throw ( IOException ){
// Empty the contents of the buffer to the output stream.
emptyBuffer();
// Flush the output stream.
stream->flush();
}
////////////////////////////////////////////////////////////////////////////////
void BufferedOutputStream::write( const unsigned char c ) throw (IOException){
if( tail >= bufferSize ){
emptyBuffer();
}
buffer[tail++] = c;
void BufferedOutputStream::write( const unsigned char c ) throw ( IOException ){
if( tail >= bufferSize ){
emptyBuffer();
}
buffer[tail++] = c;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void BufferedOutputStream::write( const unsigned char* buffer, const int len )
throw (IOException)
{
// Iterate until all the data is written.
for( int pos=0; pos < len; ){
if( tail >= bufferSize ){
emptyBuffer();
}
// Get the number of bytes left to write.
int bytesToWrite = min( bufferSize-tail, len-pos );
// Copy the data.
memcpy( this->buffer+tail, buffer+pos, bytesToWrite );
// Increase the tail position.
tail += bytesToWrite;
// Decrease the number of bytes to write.
pos += bytesToWrite;
}
throw ( IOException )
{
// Iterate until all the data is written.
for( int pos=0; pos < len; ){
if( tail >= bufferSize ){
emptyBuffer();
}
// Get the number of bytes left to write.
int bytesToWrite = min( bufferSize-tail, len-pos );
// Copy the data.
memcpy( this->buffer+tail, buffer+pos, bytesToWrite );
// Increase the tail position.
tail += bytesToWrite;
// Decrease the number of bytes to write.
pos += bytesToWrite;
}
}

Some files were not shown because too many files have changed in this diff Show More