[CVS spice] first cut of message routing component
proyal-yCVjj/[email protected] 2 Mar 2005 19:32:09 -0000
| Newsgroups | gmane.comp.java.spice.cvs |
|---|---|
| Message-ID | <[email protected]> |
<html>
<head>
<style><!--
body {background-color:#ffffff;}
.file {border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;}
.pathname {font-family:monospace; float:right;}
.fileheader {margin-bottom:.5em;}
.diff {margin:0;}
.tasklist {padding:4px;border:1px dashed #000000;margin-top:1em;}
.tasklist ul {margin-top:0;margin-bottom:0;}
tr.alt {background-color:#eeeeee}
#added {background-color:#ddffdd;}
#addedchars {background-color:#99ff99;font-weight:bolder;}
tr.alt #added {background-color:#ccf7cc;}
#removed {background-color:#ffdddd;}
#removedchars {background-color:#ff9999;font-weight:bolder;}
tr.alt #removed {background-color:#f7cccc;}
#info {color:#888888;}
#context {background-color:#eeeeee;}
td {padding-left:.3em;padding-right:.3em;}
tr.head {border-bottom-width:1px;border-bottom-style:solid;}
tr.head td {padding:0;padding-top:.2em;}
.task {background-color:#ffff00;}
.comment {padding:4px;border:1px dashed #000000;background-color:#ffffdd}
.error {color:red;}
hr {border-width:0px;height:2px;background:black;}
--></style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head"><td colspan="4">Commit in <b><tt>spice/components/message</tt></b><span id="info"> on MAIN</span></td></tr>
<tr><td><tt>src/java/org/spice/message/<a href="#file1"><span id="added">Destination.java</span></a></tt></td><td align="right" id="added">+43</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt> /<a href="#file2"><span id="added">DestinationEventHandler.java</span></a></tt></td><td align="right" id="added">+38</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt> /<a href="#file3"><span id="added">DestinationEventPipeline.java</span></a></tt></td><td align="right" id="added">+50</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt> /<a href="#file4"><span id="added">DestinationRegistrar.java</span></a></tt></td><td align="right" id="added">+34</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt> /<a href="#file5"><span id="added">Dispatcher.java</span></a></tt></td><td align="right" id="added">+30</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt> /<a href="#file6"><span id="added">DuplicateRegistrationException.java</span></a></tt></td><td align="right" id="added">+27</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt> /<a href="#file7"><span id="added">InvalidMessageException.java</span></a></tt></td><td align="right" id="added">+35</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt> /<a href="#file8"><span id="added">MessageException.java</span></a></tt></td><td align="right" id="added">+19</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt> /<a href="#file9"><span id="added">MessageTransactionSynchronization.java</span></a></tt></td><td align="right" id="added">+69</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt> /<a href="#file10"><span id="added">NoSuchDestinationException.java</span></a></tt></td><td align="right" id="added">+27</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt> /<a href="#file11"><span id="added">TransactionalMessageRouter.java</span></a></tt></td><td align="right" id="added">+168</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt> /<a href="#file12"><span id="added">ValidMessageEnqueuePredicate.java</span></a></tt></td><td align="right" id="added">+44</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>src/test/org/spice/message/<a href="#file13"><span id="added">TransactionalMessageRouterTestCase.java</span></a></tt></td><td align="right" id="added">+86</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt><a href="#file14"><span id="added">project.xml</span></a></tt></td><td align="right" id="added">+81</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td></td><td align="right" id="added">+751</td><td></td><td></td></tr>
</table>
<small id="info">14 added files</small><br />
<pre class="comment">
first cut of message routing component
</pre>
<hr /><a name="file1" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>Destination.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N Destination.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Destination.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,43 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * A Message Destination receives messages for a named destination.
+ *
+ * Message objects will be specific to the destination implementation. Please consult destination documentation on what
+ * constitutes valid messages.
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public interface Destination
+{
+ /**
+ * Get the address of this destination.
+ *
+ * @return Address of destination. Required.
+ */
+ String getAddress();
+
+ /**
+ * Is the specified message a valid message for this destination? This method is just to check message validity. All
+ * valid messages must be delivered without throwing any exceptions.
+ *
+ * @param message Message object to validate. Required.
+ *
+ * @return True if the message is valid for this destination.
+ */
+ boolean isValidMessage( Object message );
+
+ /**
+ * Deliver a message. Messages should first be tested for validity with {@link #isValidMessage(Object)}.
+ *
+ * @param message Message to deliver.
+ */
+ void deliver( Object message );
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file2" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>DestinationEventHandler.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N DestinationEventHandler.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DestinationEventHandler.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,38 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+import org.d_haven.event.EventHandler;
+
+/**
+ * EventHandler that passes messages on to a Destination
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+class DestinationEventHandler implements EventHandler
+{
+ private final Destination m_destination;
+
+ public DestinationEventHandler( final Destination destination )
+ {
+ m_destination = destination;
+ }
+
+ public void handleEvent( final Object element )
+ {
+ m_destination.deliver( element );
+ }
+
+ public void handleEvents( final Object[] elements )
+ {
+ for( int i = 0; i < elements.length; i++ )
+ {
+ handleEvent( elements[i] );
+ }
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file3" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>DestinationEventPipeline.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N DestinationEventPipeline.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DestinationEventPipeline.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,50 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+import org.d_haven.event.EventHandler;
+import org.d_haven.event.Pipe;
+import org.d_haven.event.Sink;
+import org.d_haven.event.Source;
+import org.d_haven.event.command.EventPipeline;
+import org.d_haven.event.impl.DefaultPipe;
+
+/**
+ * EventPipeline that manages a Destination, only allowing value messages to be enqueued.
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+class DestinationEventPipeline implements EventPipeline
+{
+ private final Pipe m_pipe;
+ private final Source[] m_sources;
+ private final EventHandler m_eventHandler;
+
+ public DestinationEventPipeline( final Destination destination )
+ {
+
+ m_pipe = new DefaultPipe( new ValidMessageEnqueuePredicate( destination ) );
+ m_sources = new Source[]{m_pipe};
+ m_eventHandler = new DestinationEventHandler( destination );
+ }
+
+ Sink getSink()
+ {
+ return m_pipe;
+ }
+
+ public EventHandler getEventHandler()
+ {
+ return m_eventHandler;
+ }
+
+ public Source[] getSources()
+ {
+ return m_sources;
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file4" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>DestinationRegistrar.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N DestinationRegistrar.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DestinationRegistrar.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,34 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * Registrar that deals with {@link Destination}s.
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public interface DestinationRegistrar
+{
+ /**
+ * Register a destination
+ *
+ * @param destination Destination to register. required.
+ *
+ * @throws DuplicateRegistrationException If this destination has already been registered
+ */
+ void register( Destination destination ) throws DuplicateRegistrationException;
+
+ /**
+ * Unregister a destination
+ *
+ * @param destination Destination to unregister. required.
+ *
+ * @throws NoSuchDestinationException If this destination has never been registered
+ */
+ void unregister( Destination destination ) throws NoSuchDestinationException;
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file5" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>Dispatcher.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N Dispatcher.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Dispatcher.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,30 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * A Messenger allows clients to send messages to specific named addresses.
+ *
+ * If a message is sent to an unknown address, it will merely end up in the discarded message box. The sender will not
+ * be informed.
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public interface Dispatcher
+{
+ /**
+ * Send a message to an address. Delivery is guaranteed if the destintion exists. If the destination does not exist,
+ * no notification will occur.
+ *
+ * @param address Address to send message to. Required.
+ * @param message Message to send. Required.
+ *
+ * @throws InvalidMessageException if a message is invalid
+ */
+ void send( String address, Object message );
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file6" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>DuplicateRegistrationException.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N DuplicateRegistrationException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DuplicateRegistrationException.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,27 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public class DuplicateRegistrationException extends MessageException
+{
+ private final Destination m_destination;
+
+ public DuplicateRegistrationException( final Destination destination )
+ {
+ super( "Destination with address '" + destination.getAddress() + "' already registered" );
+ m_destination = destination;
+ }
+
+ public Destination getDestination()
+ {
+ return m_destination;
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file7" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>InvalidMessageException.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N InvalidMessageException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ InvalidMessageException.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,35 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public class InvalidMessageException extends RuntimeException
+{
+ private final String m_address;
+ private final Object m_invalidMessage;
+
+ public InvalidMessageException( final String address, final Object invalidMessage )
+ {
+ super( "Invalid invalidMessage '" + invalidMessage + "' for destination '" + address + "'" );
+
+ m_address = address;
+ m_invalidMessage = invalidMessage;
+ }
+
+ public String getAddress()
+ {
+ return m_address;
+ }
+
+ public Object getInvalidMessage()
+ {
+ return m_invalidMessage;
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file8" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>MessageException.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N MessageException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ MessageException.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,19 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public class MessageException extends Exception
+{
+ public MessageException( final String message )
+ {
+ super( message );
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file9" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>MessageTransactionSynchronization.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N MessageTransactionSynchronization.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ MessageTransactionSynchronization.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,69 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+import org.d_haven.event.PreparedEnqueue;
+
+/**
+ * <code>Synchronization</code> That deals with PreparedEnqueue objects
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+class MessageTransactionSynchronization implements Synchronization
+{
+ private final List m_enqueues = new ArrayList();
+
+ public void commit()
+ {
+ final Iterator i = m_enqueues.iterator();
+
+ while( i.hasNext() )
+ {
+ ( (PreparedEnqueue)i.next() ).commit();
+ }
+ }
+
+ public void rollback()
+ {
+ final Iterator i = m_enqueues.iterator();
+
+ while( i.hasNext() )
+ {
+ ( (PreparedEnqueue)i.next() ).abort();
+ }
+ }
+
+ void addEnqueue( final PreparedEnqueue enqueue )
+ {
+ m_enqueues.add( enqueue );
+ }
+
+ public void afterCompletion( final int status )
+ {
+ switch( status )
+ {
+ case Status.STATUS_COMMITTED:
+ commit();
+ break;
+ default:
+ rollback();
+ ;
+ break;
+ }
+ }
+
+ public void beforeCompletion()
+ {
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file10" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>NoSuchDestinationException.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N NoSuchDestinationException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NoSuchDestinationException.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,27 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+/**
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public class NoSuchDestinationException extends MessageException
+{
+ private final Destination m_destination;
+
+ public NoSuchDestinationException( final Destination destination )
+ {
+ super( "Unknown destination address '" + destination.getAddress() + "'" );
+ m_destination = destination;
+ }
+
+ public Destination getDestination()
+ {
+ return m_destination;
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file11" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>TransactionalMessageRouter.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N TransactionalMessageRouter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ TransactionalMessageRouter.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,168 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+import EDU.oswego.cs.dl.util.concurrent.ReaderPreferenceReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.SyncMap;
+import org.d_haven.event.EnqueuePredicateFailedException;
+import org.d_haven.event.Sink;
+import org.d_haven.event.SinkException;
+import org.d_haven.event.command.ThreadManager;
+
+/**
+ * Default implementation of a {@link DestinationRegistrar} and {@link Dispatcher}
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public class TransactionalMessageRouter implements DestinationRegistrar, Dispatcher
+{
+ private final Map m_registrations = new ConcurrentHashMap();
+ private final Map m_transactionResources = new SyncMap( new WeakHashMap(), new ReaderPreferenceReadWriteLock() );
+
+ private final ThreadManager m_threadManager;
+ private final TransactionManager m_transactionManager;
+
+ public TransactionalMessageRouter( final ThreadManager threadManager,
+ final TransactionManager transactionManager )
+ {
+ if( null == threadManager )
+ {
+ throw new NullPointerException( "threadManager" );
+ }
+ else if( null == transactionManager )
+ {
+ throw new NullPointerException( "transactionManager" );
+ }
+
+ m_threadManager = threadManager;
+ m_transactionManager = transactionManager;
+ }
+
+ public void register( final Destination destination ) throws DuplicateRegistrationException
+ {
+ if( m_registrations.containsKey( destination.getAddress() ) )
+ {
+ throw new DuplicateRegistrationException( destination );
+ }
+ else
+ {
+ addDestination( destination );
+ }
+ }
+
+ private void addDestination( final Destination destination )
+ {
+ final DestinationEventPipeline pipeline = new DestinationEventPipeline( destination );
+
+ m_threadManager.register( pipeline );
+ m_registrations.put( destination.getAddress(), pipeline );
+ }
+
+ public void unregister( final Destination destination ) throws NoSuchDestinationException
+ {
+ if( !m_registrations.containsKey( destination.getAddress() ) )
+ {
+ throw new NoSuchDestinationException( destination );
+ }
+ else
+ {
+ removeDestination( destination );
+ }
+ }
+
+ private void removeDestination( final Destination destination )
+ {
+ final String address = destination.getAddress();
+ final DestinationEventPipeline pipeline = getDestinationEventPipeline( address );
+
+ m_threadManager.unregister( pipeline );
+ m_registrations.remove( address );
+ }
+
+ public void send( final String address, final Object message )
+ {
+ final DestinationEventPipeline pipeline = getDestinationEventPipeline( address );
+
+ if( null != pipeline )
+ {
+ try
+ {
+ final MessageTransactionSynchronization synchronization = getMessageTransactionResource();
+ final Sink sink = pipeline.getSink();
+
+ if( null == synchronization )
+ {
+ sink.enqueue( message );
+ }
+ else
+ {
+ synchronization.addEnqueue( sink.prepareEnqueue( new Object[]{message} ) );
+ }
+ }
+ catch( EnqueuePredicateFailedException e )
+ {
+ throw new InvalidMessageException( address, message );
+ }
+ catch( SinkException e )
+ {
+ final String msg = "Unable to send message '" + message + "' to destination '" + address + "'";
+ throw new RuntimeException( msg, e );
+ }
+ catch( SystemException e )
+ {
+ final String msg = "Transaction failure when sending message '" + message
+ + "' to destination '" + address + "'";
+ throw new RuntimeException( msg, e );
+ }
+ catch( RollbackException e )
+ {
+ final String msg = "Attempted to send message during rolled back transaction '" + message
+ + "' to destination '" + address + "'";
+ throw new RuntimeException( msg, e );
+ }
+ }
+ }
+
+ private MessageTransactionSynchronization getMessageTransactionResource() throws SystemException,
+ RollbackException
+ {
+ final Transaction transaction = m_transactionManager.getTransaction();
+
+ if( null == transaction )
+ {
+ return null;
+ }
+ else
+ {
+ MessageTransactionSynchronization synchronization =
+ (MessageTransactionSynchronization)m_transactionResources.get( transaction );
+
+ if( null == synchronization )
+ {
+ synchronization = new MessageTransactionSynchronization();
+ transaction.registerSynchronization( synchronization );
+ m_transactionResources.put( transaction, synchronization );
+ }
+
+ return synchronization;
+ }
+ }
+
+ private DestinationEventPipeline getDestinationEventPipeline( final String address )
+ {
+ return (DestinationEventPipeline)m_registrations.get( address );
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file12" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/java/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>ValidMessageEnqueuePredicate.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N ValidMessageEnqueuePredicate.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ValidMessageEnqueuePredicate.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,44 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+import org.d_haven.event.EnqueuePredicate;
+import org.d_haven.event.Sink;
+
+/**
+ * EnqueuePredicate that only accepts valid messages
+ *
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+class ValidMessageEnqueuePredicate implements EnqueuePredicate
+{
+ private final Destination m_destination;
+
+ public ValidMessageEnqueuePredicate( final Destination destination )
+ {
+ m_destination = destination;
+ }
+
+ public boolean accept( final Object element, final Sink modifyingSink )
+ {
+ return m_destination.isValidMessage( element );
+ }
+
+ public boolean accept( final Object[] elements, final Sink modifyingSink )
+ {
+ for( int i = 0; i < elements.length; i++ )
+ {
+ if( !accept( elements[i], modifyingSink ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file13" /><div class="file">
<span class="pathname" id="added">spice/components/message/src/test/org/spice/message<br /></span>
<div class="fileheader" id="added"><big><b>TransactionalMessageRouterTestCase.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N TransactionalMessageRouterTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ TransactionalMessageRouterTestCase.java 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,86 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.spice.message;
+
+import javax.transaction.TransactionManager;
+
+import junit.framework.TestCase;
+import org.d_haven.event.command.DefaultThreadManager;
+import org.d_haven.event.command.ThreadManager;
+import org.jmock.Mock;
+
+/**
+ * @author <a href="mailto:[email protected]">peter royal</a>
+ */
+public class TransactionalMessageRouterTestCase extends TestCase
+{
+ private TransactionalMessageRouter m_transactionalMessageRouter;
+
+ protected void setUp() throws Exception
+ {
+ final ThreadManager threadManager = new DefaultThreadManager();
+ final Mock transactionManager = new Mock( TransactionManager.class );
+
+ m_transactionalMessageRouter
+ = new TransactionalMessageRouter( threadManager,
+ (TransactionManager)transactionManager.proxy() );
+ }
+
+ public void testUnregisterUnknownDestination() throws Exception
+ {
+ final DestinationRegistrar registrar = m_transactionalMessageRouter;
+ final MockDestination destination = new MockDestination();
+
+ try
+ {
+ registrar.unregister( destination );
+
+ fail( "cannot unregister non-registered destination" );
+ }
+ catch( NoSuchDestinationException e )
+ {
+ assertEquals( destination, e.getDestination() );
+ }
+ }
+
+ public void testDuplicateRegistration() throws Exception
+ {
+ final DestinationRegistrar registrar = m_transactionalMessageRouter;
+ final MockDestination destination = new MockDestination();
+
+ registrar.register( destination );
+
+ try
+ {
+ registrar.register( destination );
+
+ fail( "allowed duplication registration" );
+ }
+ catch( DuplicateRegistrationException e )
+ {
+ assertEquals( destination, e.getDestination() );
+ }
+ }
+
+ private static class MockDestination implements Destination
+ {
+ public String getAddress()
+ {
+ return "test";
+ }
+
+ public boolean isValidMessage( final Object message )
+ {
+ return false;
+ }
+
+ public void deliver( final Object message )
+ {
+ }
+ }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file14" /><div class="file">
<span class="pathname" id="added">spice/components/message<br /></span>
<div class="fileheader" id="added"><big><b>project.xml</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N project.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ project.xml 2 Mar 2005 19:32:08 -0000 1.1
@@ -0,0 +1,81 @@
</small></pre><pre class="diff" id="added">+<?xml version="1.0"?>
+<project>
+ <extend>${basedir}/../../project.xml</extend>
+ <name>Spice Message</name>
+
+ <artifactId>spice-message</artifactId>
+ <currentVersion>1.0-M1</currentVersion>
+ <inceptionYear>2005</inceptionYear>
+
+ <shortDescription>In-Process messaging</shortDescription>
+
+ <description>
+ Spice Message is a simple in-process asychronous message delivery system.
+ </description>
+
+ <versions>
+ <version>
+ <id>current</id>
+ <name>Current</name>
+ <tag>HEAD</tag>
+ </version>
+ </versions>
+
+ <dependencies>
+ <dependency>
+ <groupId>d-haven-event</groupId>
+ <artifactId>d-haven-event</artifactId>
+ <version>1.0.3</version>
+ <properties>
+ <category>runtime</category>
+ </properties>
+ </dependency>
+
+ <dependency>
+ <groupId>d-haven-mpool</groupId>
+ <artifactId>managed-pool</artifactId>
+ <version>1.0</version>
+ <properties>
+ <category>runtime</category>
+ </properties>
+ </dependency>
+
+ <dependency>
+ <groupId>concurrent</groupId>
+ <artifactId>concurrent</artifactId>
+ <version>1.3.4</version>
+ <properties>
+ <category>runtime</category>
+ </properties>
+ </dependency>
+
+ <dependency>
+ <groupId>geronimo-spec</groupId>
+ <artifactId>geronimo-spec-jta</artifactId>
+ <version>1.0.1B-rc4</version>
+ <properties>
+ <category>runtime</category>
+ </properties>
+ </dependency>
+
+ <dependency>
+ <groupId>jmock</groupId>
+ <artifactId>jmock</artifactId>
+ <version>1.0.1</version>
+ <properties>
+ <category>test</category>
+ </properties>
+ </dependency>
+ </dependencies>
+
+ <developers>
+ <developer>
+ <name>Peter Royal</name>
+ <id>proyal</id>
+ <email>[email protected]</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+</project>
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<center><small><a href="http://www.badgers-in-foil.co.uk/projects/cvsspam/" title="commit -> email">CVSspam</a> 0.2.8</small></center>
</body></html>