Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 243   Methods: 0
NCLOC: 18   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
PojoCacheListener.java - - - -
coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    * Copyright 2005, JBoss Inc., and individual contributors as indicated
 4    * by the @authors tag. See the copyright.txt in the distribution for a
 5    * full listing of individual contributors.
 6    *
 7    * This is free software; you can redistribute it and/or modify it
 8    * under the terms of the GNU Lesser General Public License as
 9    * published by the Free Software Foundation; either version 2.1 of
 10    * the License, or (at your option) any later version.
 11    *
 12    * This software is distributed in the hope that it will be useful,
 13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15    * Lesser General Public License for more details.
 16    *
 17    * You should have received a copy of the GNU Lesser General Public
 18    * License along with this software; if not, write to the Free
 19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 21    */
 22    package org.jboss.cache.pojo.notification.annotation;
 23   
 24    import java.lang.annotation.ElementType;
 25    import java.lang.annotation.Retention;
 26    import java.lang.annotation.RetentionPolicy;
 27    import java.lang.annotation.Target;
 28   
 29    import org.jboss.cache.pojo.notification.NotificationContext;
 30    import org.jboss.cache.pojo.notification.event.AttachedEvent;
 31    import org.jboss.cache.pojo.notification.event.DetachedEvent;
 32    import org.jboss.cache.pojo.notification.event.FieldModifiedEvent;
 33    import org.jboss.cache.pojo.notification.event.ListModifiedEvent;
 34    import org.jboss.cache.pojo.notification.event.MapModifiedEvent;
 35    import org.jboss.cache.pojo.notification.event.SetModifiedEvent;
 36    import org.jboss.cache.pojo.notification.event.TransactionCompletedEvent;
 37    import org.jboss.cache.pojo.notification.event.TransactionRegisteredEvent;
 38   
 39    /**
 40    * Indicates that a class should receive POJO notification events. The class may
 41    * have zero or more annotated notification methods. Each method may have any
 42    * name, but must have a method signature that contains the required event type
 43    * (or super type).
 44    *
 45    * <p>
 46    * There can be multiple methods that are annotated to receive the same event,
 47    * and a method may receive multiple events by using a super type.
 48    *
 49    * <h4>Delivery Semantics</h4>
 50    * <p>
 51    * An event is delivered immediately after the
 52    * respective operation, but before the underlying cache call returns. For this
 53    * reason it is important to keep listener processing logic short-lived. If a
 54    * long running task needs to be performed, it's recommended to use another
 55    * thread.
 56    *
 57    * <h4>Transactional Semantics</h4>
 58    * <p>
 59    * Since the event is delivered during the actual cache call, the transactional
 60    * outcome is not yet known. For this reason, <i>events are always delivered, even
 61    * if the changes they represent are discarded by their containing transaction</i>.
 62    * For applications that must only process events that represent changes in a
 63    * completed transaction, {@link NotificationContext#getTransaction()} can be used,
 64    * along with {@link TransactionCompletedEvent#isSuccessful()} to record events and
 65    * later process them once the transaction has been successfully committed.
 66    * Example 4 demonstrates this.
 67    *
 68    * <h4>Threading Semantics</h4>
 69    * <p>
 70    * A listener implementation must be capable of handling concurrent invocations. Local
 71    * notifications reuse the calling thread; remote notifications reuse the network thread.
 72    *
 73    * <p>
 74    * <b>Summary of Notification Annotations</b>
 75    * <table border="1" cellpadding="1" cellspacing="1" summary="Summary of notification annotations">
 76    * <tr>
 77    * <th bgcolor="#CCCCFF" align="left">Annotation</th>
 78    * <th bgcolor="#CCCCFF" align="left">Event</th>
 79    * <th bgcolor="#CCCCFF" align="left">Description</th>
 80    * </tr>
 81    * <tr>
 82    * <td valign="top">{@link Attached}</td>
 83    * <td valign="top">{@link AttachedEvent}</td>
 84    * <td valign="top">An object was attached.</td>
 85    * </tr>
 86    * <tr>
 87    * <td valign="top">{@link Detached}</td>
 88    * <td valign="top">{@link DetachedEvent}</td>
 89    * <td valign="top">An object was detached.</td>
 90    * </tr>
 91    * <tr>
 92    * <td valign="top">{@link FieldModified}</td>
 93    * <td valign="top">{@link FieldModifiedEvent}</td>
 94    * <td valign="top">An attached object's field was modified.</td>
 95    * </tr>
 96    * <tr>
 97    * <td valign="top">{@link ListModified}</td>
 98    * <td valign="top">{@link ListModifiedEvent}</td>
 99    * <td valign="top">An attached list was modified.</td>
 100    * </tr>
 101    * <tr>
 102    * <td valign="top">{@link SetModified}</td>
 103    * <td valign="top">{@link SetModifiedEvent}</td>
 104    * <td valign="top">An attached set was modified.</td>
 105    * </tr>
 106    * <tr>
 107    * <td valign="top">{@link MapModified}</td>
 108    * <td valign="top">{@link MapModifiedEvent}</td>
 109    * <td valign="top">An attached map was modified.</td>
 110    * </tr>
 111    * <tr>
 112    * <td valign="top">{@link TransactionRegistered}</td>
 113    * <td valign="top">{@link TransactionRegisteredEvent}</td>
 114    * <td valign="top">A transaction was registered.</td>
 115    * </tr>
 116    * <tr>
 117    * <td valign="top">{@link TransactionCompleted}</td>
 118    * <td valign="top">{@link TransactionCompletedEvent}</td>
 119    * <td valign="top">A transaction was completed.</td>
 120    * </tr>
 121    * </table>
 122    *
 123    * <h4>Example 1 - Method receiving a single event</h4>
 124    * <pre>
 125    * &#064;PojoCacheListener
 126    * public class SingleEventListener
 127    * {
 128    * &#064;Attached
 129    * public void handleAttached(AttachedEvent event)
 130    * {
 131    * System.out.println(&quot;Attached = &quot; event.getSource());
 132    * }
 133    * }
 134    * </pre>
 135    *
 136    * <h4>Example 2 - Method receiving multiple events</h4>
 137    * <pre>
 138    * &#064;PojoCacheListener
 139    * public class MultipleEventListener
 140    * {
 141    * &#064;Attached
 142    * &#064;Detached
 143    * public void handleAttachDetach(Event event)
 144    * {
 145    * if (event instanceof AttachedEvent)
 146    * System.out.println(&quot;Attached = &quot; + event.getSource());
 147    * else if (event instanceof DetachedEvent)
 148    * System.out.println(&quot;Detached = &quot; + event.getSource());
 149    * }
 150    * }
 151    * </pre>
 152    *
 153    * <h4>Example 3 - Multiple methods receiving the same event</h4>
 154    * <pre>
 155    * &#064;PojoCacheListener
 156    * public class SingleEventListener
 157    * {
 158    * &#064;Attached
 159    * public void handleAttached(AttachedEvent event)
 160    * {
 161    * System.out.println(&quot;Attached = &quot; event.getSource());
 162    * }
 163    * &#064;Attached
 164    * &#064;Detached
 165    * &#064;FieldModified
 166    * &#064;ListModified
 167    * &#064;MapModified
 168    * &#064;SetModified
 169    * &#064;TransactionRegistered
 170    * &#064;TransactionCompleted
 171    * public void handleAll(Event event)
 172    * {
 173    * System.out.println(event);
 174    * }
 175    * }
 176    * </pre>
 177    *
 178    * <p>
 179    * <b>Example 4 - Processing only events with a committed transaction.</b>
 180    *
 181    * <pre>
 182    * &#064;PojoCacheListener
 183    * public class TxGauranteedListener
 184    * {
 185    * private class TxEventQueue
 186    * {
 187    * private ConcurrentMap&lt;Transaction, Queue&lt;Event&gt;&gt; map = new ConcurrentHashMap&lt;Transaction, Queue&lt;Event&gt;&gt;();
 188    *
 189    * public void offer(Event event)
 190    * {
 191    * Queue&lt;Event&gt; queue = getQueue(event.getContext().getTransaction());
 192    * queue.offer(event);
 193    * }
 194    *
 195    * private Queue&lt;Event&gt; getQueue(Transaction transaction)
 196    * {
 197    * Queue&lt;Event&gt; queue = map.get(transaction);
 198    * if (queue == null)
 199    * {
 200    * queue = new ConcurrentLinkedQueue&lt;Event&gt;();
 201    * map.putIfAbsent(transaction, queue);
 202    * }
 203    *
 204    * return queue;
 205    * }
 206    *
 207    * public Queue&lt;Event&gt; takeAll(Transaction transaction)
 208    * {
 209    * return map.remove(transaction);
 210    * }
 211    * }
 212    *
 213    * private TxEventQueue events = new TxEventQueue();
 214    *
 215    * &#064;Attached
 216    * &#064;Detached
 217    * &#064;FieldModified
 218    * &#064;ListModified
 219    * &#064;SetModified
 220    * &#064;MapModified
 221    * public void handle(Event event)
 222    * {
 223    * events.offer(event);
 224    * }
 225    *
 226    * &#064;TransactionCompleted
 227    * public void handleTx(TransactionCompletedEvent event)
 228    * {
 229    * Queue&lt;Event&gt; completed = events.takeAll(event.getContext().getTransaction());
 230    * if (completed != null &amp;&amp; event.isSuccessful())
 231    * System.out.println("Comitted events = " + completed);
 232    * }
 233    * }
 234    * </pre>
 235    *
 236    * @author Jason T. Greene
 237    * @since 2.0
 238    */
 239    @Retention(RetentionPolicy.RUNTIME)
 240    @Target(ElementType.TYPE)
 241    public @interface PojoCacheListener
 242    {
 243    }