EMMA Coverage Report (generated Sun May 02 20:42:29 CEST 2010)
[all classes][hu.netmind.beankeeper.helper]

COVERAGE SUMMARY FOR SOURCE FILE [TransactionalMap.java]

nameclass, %method, %block, %line, %
TransactionalMap.java0%   (0/1)0%   (0/19)0%   (0/183)0%   (0/48)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class TransactionalMap0%   (0/1)0%   (0/19)0%   (0/183)0%   (0/48)
TransactionalMap (Store): void 0%   (0/1)0%   (0/23)0%   (0/7)
clear (): void 0%   (0/1)0%   (0/4)0%   (0/2)
close (): void 0%   (0/1)0%   (0/6)0%   (0/2)
containsKey (Object): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
containsValue (Object): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
entrySet (): Set 0%   (0/1)0%   (0/4)0%   (0/1)
equals (Object): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
get (Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
getReadMap (): Map 0%   (0/1)0%   (0/9)0%   (0/3)
getWriteMap (): Map 0%   (0/1)0%   (0/51)0%   (0/9)
handle (PersistenceEvent): void 0%   (0/1)0%   (0/30)0%   (0/11)
hashCode (): int 0%   (0/1)0%   (0/4)0%   (0/1)
isEmpty (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
keySet (): Set 0%   (0/1)0%   (0/4)0%   (0/1)
put (Object, Object): Object 0%   (0/1)0%   (0/6)0%   (0/1)
putAll (Map): void 0%   (0/1)0%   (0/5)0%   (0/2)
remove (Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
size (): int 0%   (0/1)0%   (0/4)0%   (0/1)
values (): Collection 0%   (0/1)0%   (0/4)0%   (0/1)

1/**
2 * Copyright (C) 2006 NetMind Consulting Bt.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19package hu.netmind.beankeeper.helper;
20 
21import hu.netmind.beankeeper.Store;
22import hu.netmind.beankeeper.transaction.Transaction;
23import hu.netmind.beankeeper.transaction.TransactionTracker;
24import hu.netmind.beankeeper.event.PersistenceEventListener;
25import hu.netmind.beankeeper.event.PersistenceEvent;
26import hu.netmind.beankeeper.transaction.event.TransactionEvent;
27import hu.netmind.beankeeper.transaction.event.TransactionCommittedEvent;
28import hu.netmind.beankeeper.transaction.event.TransactionRolledbackEvent;
29import java.util.Map;
30import java.util.Set;
31import java.util.Collection;
32import java.util.HashMap;
33import java.util.ConcurrentModificationException;
34import org.apache.log4j.Logger;
35 
36/**
37 * This map implementation takes transactions into account when
38 * getting and settings values. This means, that values set into
39 * the map are only visible to the same transaction which set them,
40 * until the commit, in which case the value becomes visible to all.
41 * If the transaction rolled back, the set values are simply dropped.
42 * Be sure to close this map if you don't use it.
43 * <br><i>Note: </i>This implementation is not thread-safe, and supports
44 * modifications from only one transaction at any given time.
45 * @author Brautigam Robert
46 * @version Revision: $Revision$
47 */
48public class TransactionalMap implements Map, PersistenceEventListener
49{
50   private Store store;
51   private Map globalMap;
52   private Map transactionMap;
53   private Transaction modifier;
54 
55   /**
56    * Construct a transactional map. This map listens for persistence
57    * events, and commits or rolls back internal operations according
58    * to transaction events.
59    */
60   public TransactionalMap(Store store)
61   {
62      globalMap = new HashMap();
63      transactionMap = new HashMap();
64      modifier = null; // No modifier
65      this.store=store;
66      // Note: this is not nice to do, registration should
67      // be outside constructor.
68      store.getEventDispatcher().registerListener(this);
69   }
70 
71   /**
72    * Get the map for the current transaction for 
73    * reading.
74    */
75   private Map getReadMap()
76   {
77      if ( modifier == null )
78         return globalMap;
79      return transactionMap;
80   }
81 
82   /**
83    * Get map for current transaction for writing.
84    */
85   private Map getWriteMap()
86   {
87      Transaction transaction = store.getTransactionTracker().getTransaction(TransactionTracker.TX_OPTIONAL);
88      if ( (transaction != modifier) && (modifier!=null) )
89         throw new ConcurrentModificationException("map is modified from two different transactions, current: "+
90               transaction+", but already under modification from: "+modifier);
91      if ( transaction == null )
92      {
93         // There is no transaction, so modify global map
94         return globalMap;
95      } else {
96         if ( modifier == null )
97         {
98            // Modification starts with this operations, so prepare
99            modifier = transaction;
100            transactionMap = new HashMap(globalMap);
101         }
102         return transactionMap;
103      }
104   }
105 
106   public void clear()
107   {
108      getWriteMap().clear();
109   }
110 
111   public boolean containsKey(Object key)
112   {
113      return getReadMap().containsKey(key);
114   }
115 
116   public boolean containsValue(Object value)
117   {
118      return getReadMap().containsValue(value);
119   }
120 
121   public Set entrySet()
122   {
123      return getReadMap().entrySet();
124   }
125 
126   public boolean equals(Object o)
127   {
128      return getReadMap().equals(o);
129   }
130 
131   public Object get(Object key)
132   {
133      return getReadMap().get(key);
134   }
135 
136   public int hashCode()
137   {
138      return getReadMap().hashCode();
139   }
140 
141   public boolean isEmpty()
142   {
143      return getReadMap().isEmpty();
144   }
145 
146   public Set keySet()
147   {
148      return getReadMap().keySet();
149   }
150 
151   public Object put(Object key, Object value)
152   {
153      return getWriteMap().put(key,value);
154   }
155 
156   public void putAll(Map m)
157   {
158      getWriteMap().putAll(m);
159   }
160 
161   public Object remove(Object key)
162   {
163      return getWriteMap().remove(key);
164   }
165 
166   public int size()
167   {
168      return getReadMap().size();
169   }
170 
171   public Collection values()
172   {
173      return getReadMap().values();
174   }
175 
176   /**
177    * Close this map, deregister from transaction listener.
178    */
179   public void close()
180   {
181      store.getEventDispatcher().unregisterListener(this);
182   }
183 
184   /**
185    * Listen for transaction events.
186    */
187   public void handle(PersistenceEvent event)
188   {
189      if ( ! (event instanceof TransactionEvent) )
190         return; // Quick exit
191      Transaction transaction = ((TransactionEvent) event).getTransaction();
192      if ( transaction != modifier )
193         return; // Not our transaction
194      if ( event instanceof TransactionCommittedEvent )
195      {
196         globalMap = transactionMap;
197         modifier=null;
198      }
199      if ( event instanceof TransactionRolledbackEvent )
200      {
201         modifier=null;
202      }
203   }
204 
205}
206 
207 
208 

[all classes][hu.netmind.beankeeper.helper]
EMMA 2.0.5312debian (C) Vladimir Roubtsov