comparison src/org/dancres/blitz/remote/view/EntryViewFactory.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children d3ec5ebc3dba
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.remote.view;
2
3 import java.io.IOException;
4
5 import java.util.HashMap;
6
7 import java.util.logging.Logger;
8 import java.util.logging.Level;
9
10 import net.jini.id.Uuid;
11 import net.jini.id.UuidFactory;
12
13 import net.jini.config.ConfigurationException;
14
15 import net.jini.core.transaction.Transaction;
16 import net.jini.core.transaction.TransactionException;
17
18 import org.dancres.blitz.EntryView;
19 import org.dancres.blitz.SpaceImpl;
20
21 import org.dancres.blitz.mangler.MangledEntry;
22
23 import org.dancres.blitz.lease.LeaseReaper;
24 import org.dancres.blitz.lease.Reapable;
25 import org.dancres.blitz.lease.ReapFilter;
26
27 import org.dancres.blitz.util.Time;
28
29 import org.dancres.blitz.Logging;
30
31 import org.dancres.blitz.config.ConfigurationFactory;
32
33 /**
34 Manages and tracks current <code>EntryView</code> instances instantiated
35 from a <code>SpaceImpl</code> instance. In particular it assigns those
36 instances a unique id and handles leasing aspects.
37 */
38 public class EntryViewFactory implements Reapable {
39 private static Logger theLogger =
40 Logging.newLogger("org.dancres.blitz.remote.view.EntryViewFactory");
41
42 private static EntryViewFactory theFactory = new EntryViewFactory();
43
44 public static EntryViewFactory get() {
45 return theFactory;
46 }
47
48 private HashMap theActiveViews = new HashMap();
49
50 private LeaseReaper theReaper;
51
52 private boolean shouldUpdate;
53
54 private EntryViewFactory() {
55 try {
56 long myReapInterval =
57 ((Long) ConfigurationFactory.getEntry("viewReapInterval",
58 long.class,
59 new Long(30 * 60 * 1000))).longValue();
60 theReaper = new LeaseReaper("View", null, myReapInterval);
61
62 theReaper.add(this);
63
64 shouldUpdate = ((Boolean)
65 ConfigurationFactory.getEntry("updateContents",
66 boolean.class,
67 new Boolean(true))).booleanValue();
68
69 } catch (ConfigurationException aCE) {
70 theLogger.log(Level.SEVERE, "Failed to load config", aCE);
71 }
72 }
73
74 public ViewRegistration newView(MangledEntry[] aTemplates, Transaction aTxn,
75 boolean holdLocks, long aLeaseDuration,
76 long aLimit, SpaceImpl aSpace)
77 throws IOException, TransactionException {
78
79 // Hold locks should only stick for a non-null transaction, other
80 // wise we're just testing....
81
82 EntryView myView = aSpace.getView(aTemplates, aTxn, holdLocks,
83 shouldUpdate, aLimit);
84
85 EntryViewUID myUid = new EntryViewUID(UuidFactory.generate());
86
87 long myExpiry = Time.getAbsoluteTime(aLeaseDuration);
88
89 synchronized(this) {
90 theActiveViews.put(myUid, new ViewHolder(myView, myExpiry));
91 }
92
93 return new ViewRegistration(myUid, myExpiry);
94 }
95
96 public EntryView getView(EntryViewUID aUID) {
97
98 synchronized(this) {
99 ViewHolder myHolder = (ViewHolder) theActiveViews.get(aUID);
100
101 if ((myHolder == null) ||
102 (myHolder.hasExpired(System.currentTimeMillis()))) {
103
104 return null;
105 } else {
106 return myHolder.getView();
107 }
108 }
109 }
110
111 public EntryView delete(EntryViewUID aUID) {
112
113 synchronized(this) {
114 ViewHolder myHolder = (ViewHolder) theActiveViews.remove(aUID);
115
116 if (myHolder != null) {
117 myHolder.getView().close();
118 return myHolder.getView();
119 }
120
121 return null;
122 }
123 }
124
125 public void reap(ReapFilter aFilter) {
126 /*
127 No reap filters will be configured so we can ignore those - see
128 initialization in constructor
129 */
130 long myTime = System.currentTimeMillis();
131
132 Object[] myKeys;
133
134 synchronized(this) {
135 myKeys = theActiveViews.keySet().toArray();
136 }
137
138 for (int i = 0; i < myKeys.length; i++) {
139 ViewHolder myHolder =
140 (ViewHolder) theActiveViews.get(myKeys[i]);
141
142 if (myHolder.hasExpired(myTime)) {
143 delete((EntryViewUID) myKeys[i]);
144 }
145 }
146 }
147
148 /* ***********************************************************************
149 * Lease renewal/cancel
150 * ***********************************************************************/
151
152 boolean renew(EntryViewUID aUID, long anExpiry) {
153 synchronized(this) {
154 ViewHolder myHolder = (ViewHolder) theActiveViews.get(aUID);
155
156 if (myHolder != null) {
157 return myHolder.testAndSetExpiry(System.currentTimeMillis(),
158 anExpiry);
159 }
160
161 return false;
162 }
163 }
164
165 boolean cancel(EntryViewUID aUID) {
166 return (delete(aUID) != null);
167 }
168
169 class ViewHolder {
170 private long theExpiry;
171 private EntryView theView;
172
173 ViewHolder(EntryView aView, long anExpiry) {
174 theView = aView;
175 theExpiry = anExpiry;
176 }
177
178 boolean hasExpired(long aTime) {
179 return (theExpiry < aTime);
180 }
181
182 boolean testAndSetExpiry(long aTime, long anExpiry) {
183 if (theExpiry < aTime)
184 return false;
185
186 theExpiry = anExpiry;
187
188 return true;
189 }
190
191 EntryView getView() {
192 return theView;
193 }
194 }
195 }