comparison src/org/dancres/blitz/remote/BlitzProxy.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
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.remote;
2
3 import java.io.Serializable;
4 import java.io.ObjectInputStream;
5 import java.io.IOException;
6
7 import java.rmi.RemoteException;
8 import java.rmi.MarshalledObject;
9
10 import java.util.Collections;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15
16 import net.jini.space.JavaSpace;
17 import net.jini.space.JavaSpace05;
18
19 import net.jini.core.entry.Entry;
20 import net.jini.core.entry.UnusableEntryException;
21
22 import net.jini.core.transaction.Transaction;
23 import net.jini.core.transaction.TransactionException;
24
25 import net.jini.core.event.EventRegistration;
26 import net.jini.core.event.RemoteEventListener;
27
28 import net.jini.core.lease.Lease;
29
30 import net.jini.entry.UnusableEntriesException;
31
32 import net.jini.lookup.entry.ServiceInfo;
33 import net.jini.lookup.entry.Name;
34
35 import com.sun.jini.lookup.entry.BasicServiceType;
36
37 import net.jini.admin.Administrable;
38
39 import net.jini.id.Uuid;
40 import net.jini.id.ReferentUuid;
41 import net.jini.id.ReferentUuids;
42
43 import org.dancres.blitz.mangler.EntryMangler;
44 import org.dancres.blitz.mangler.MangledEntry;
45
46 import org.dancres.blitz.VersionInfo;
47 import org.dancres.blitz.remote.nio.FastSpace;
48
49 /**
50 The Blitz front-end proxy responsible for implementing the JavaSpace
51 interface.
52 */
53 class BlitzProxy implements Serializable, JavaSpace, JavaSpace05,
54 Administrable, ReferentUuid {
55
56 FastSpace theFast;
57 BlitzServer theStub;
58 Uuid theUuid;
59
60 BlitzProxy(BlitzServer aServer, Uuid aUuid) {
61 theStub = aServer;
62 theUuid = aUuid;
63 }
64
65 void enableFastIO(FastSpace aSpace) {
66 theFast = aSpace;
67 }
68
69 synchronized FastSpace getFastChannel() {
70 if (theFast != null) {
71 if (! theFast.isInited()) {
72 try {
73 theFast.init();
74 } catch (IOException anIOE) {
75 throw new Error("Panic: fast io didn't init", anIOE);
76 }
77 }
78 }
79
80 return theFast;
81 }
82
83 public Uuid getReferentUuid() {
84 return theUuid;
85 }
86
87 private EntryMangler getMangler() {
88 return EntryMangler.getMangler();
89 }
90
91 private MangledEntry packEntry(Entry anEntry, boolean isWrite) {
92 if ((isWrite) && (anEntry == null))
93 throw new IllegalArgumentException("You cannot write a null Entry");
94
95 if (anEntry == null)
96 return MangledEntry.NULL_TEMPLATE;
97 // Is it a snapshot?
98 else if (anEntry instanceof MangledEntry)
99 return (MangledEntry) anEntry;
100 else
101 return getMangler().mangle(anEntry, false);
102 }
103
104 public Lease write(Entry entry, Transaction txn, long lease)
105 throws TransactionException, RemoteException {
106
107 LeaseImpl myLease;
108
109 if (getFastChannel() != null)
110 myLease = getFastChannel().write(packEntry(entry, true), txn, lease);
111 else
112 myLease = theStub.write(packEntry(entry, true), txn, lease);
113
114 myLease.setLandlord(theStub, theUuid);
115 return myLease;
116 }
117
118 public Entry read(Entry tmpl, Transaction txn, long timeout)
119 throws UnusableEntryException, TransactionException,
120 InterruptedException, RemoteException {
121
122 MangledEntry myResult;
123
124 if (getFastChannel() != null)
125 myResult = getFastChannel().read(packEntry(tmpl, false), txn, timeout);
126 else
127 myResult = theStub.read(packEntry(tmpl, false), txn, timeout);
128
129 return (myResult != null) ?
130 getMangler().unMangle(myResult) : null;
131 }
132
133 public Entry readIfExists(Entry tmpl, Transaction txn, long timeout)
134 throws UnusableEntryException, TransactionException,
135 InterruptedException, RemoteException {
136
137 MangledEntry myResult;
138
139 if (getFastChannel() != null)
140 myResult = getFastChannel().readIfExists(packEntry(tmpl, false), txn, timeout);
141 else
142 myResult = theStub.readIfExists(packEntry(tmpl, false), txn, timeout);
143
144 return (myResult != null) ?
145 getMangler().unMangle(myResult) : null;
146 }
147
148 public Entry take(Entry tmpl, Transaction txn, long timeout)
149 throws UnusableEntryException, TransactionException,
150 InterruptedException, RemoteException {
151
152 MangledEntry myResult;
153
154 if (getFastChannel() != null)
155 myResult = getFastChannel().take(packEntry(tmpl, false), txn, timeout);
156 else
157 myResult = theStub.take(packEntry(tmpl, false), txn, timeout);
158
159 return (myResult != null) ?
160 getMangler().unMangle(myResult) : null;
161 }
162
163 public Entry takeIfExists(Entry tmpl, Transaction txn, long timeout)
164 throws UnusableEntryException, TransactionException,
165 InterruptedException, RemoteException {
166
167 MangledEntry myResult;
168
169 if (getFastChannel() != null)
170 myResult = getFastChannel().takeIfExists(packEntry(tmpl, false), txn, timeout);
171 else
172 myResult = theStub.takeIfExists(packEntry(tmpl, false), txn, timeout);
173
174 return (myResult != null) ?
175 getMangler().unMangle(myResult) : null;
176 }
177
178 public EventRegistration
179 notify(Entry tmpl, Transaction txn, RemoteEventListener listener,
180 long lease, MarshalledObject handback)
181 throws TransactionException, RemoteException {
182
183 return theStub.notify(packEntry(tmpl, false), txn, listener, lease,
184 handback);
185 }
186
187 public Entry snapshot(Entry e) throws RemoteException {
188 if (e instanceof MangledEntry)
189 return e;
190 else
191 return getMangler().mangle(e, true);
192 }
193
194 public Object getAdmin() throws RemoteException {
195 return theStub.getAdmin();
196 }
197
198 /* *******************************************************************
199 * JavaSpace05
200 * *******************************************************************/
201
202 public List write(List anEntries, Transaction aTxn, List aLeaseTimes)
203 throws RemoteException, TransactionException {
204
205 if ((anEntries.size() == 0) || (aLeaseTimes.size() == 0))
206 throw new IllegalArgumentException("Empty lists are not allowed!");
207
208 if (anEntries.size() != aLeaseTimes.size())
209 throw new IllegalArgumentException("Entry list different size from lease list");
210
211 ArrayList myMangledEntries = new ArrayList();
212
213 for (int i = 0; i < anEntries.size(); i++) {
214 Entry myEntry = (Entry) anEntries.get(i);
215 Long myLeaseTime = (Long) aLeaseTimes.get(i);
216
217 if (myEntry == null)
218 throw new NullPointerException("Whoops, null Entry in list");
219 if (myLeaseTime.longValue() <= 0)
220 throw new IllegalArgumentException("Non-positive lease times are not allowed");
221
222 myMangledEntries.add(packEntry(myEntry, true));
223 }
224
225 List myLeases = theStub.write(myMangledEntries, aTxn, aLeaseTimes);
226
227 Iterator myFixups = myLeases.iterator();
228
229 while (myFixups.hasNext()) {
230 LeaseImpl myLease = (LeaseImpl) myFixups.next();
231 myLease.setLandlord(theStub, theUuid);
232 }
233
234 return Collections.unmodifiableList(myLeases);
235 }
236
237 public Collection take(Collection aTemplates, Transaction aTxn,
238 long aWaitTime, long aLimit)
239 throws RemoteException, TransactionException, UnusableEntriesException {
240
241 if (aLimit <= 0)
242 throw new IllegalArgumentException("Limit needs to be a positive number");
243
244 if (aTemplates.size() == 0)
245 throw new IllegalArgumentException("Templates must be non-zero length");
246
247 MangledEntry[] myPackedTemplates = new MangledEntry[aTemplates.size()];
248 Iterator myTemplates = aTemplates.iterator();
249
250 int myIndex = 0;
251
252 while(myTemplates.hasNext()) {
253 Entry myEntry = (Entry) myTemplates.next();
254 myPackedTemplates[myIndex++] = packEntry(myEntry, false);
255 }
256
257 List myMatches = theStub.take(myPackedTemplates, aTxn, aWaitTime,
258 aLimit);
259
260
261 Iterator myMangledEntrys = myMatches.iterator();
262
263 List myExceptions = new ArrayList();
264 List myEntrys = new ArrayList();
265
266 while (myMangledEntrys.hasNext()) {
267 MangledEntry myEntry = (MangledEntry) myMangledEntrys.next();
268
269 try {
270 Entry myUnpacked = getMangler().unMangle(myEntry);
271 myEntrys.add(myUnpacked);
272 } catch (Exception anE) {
273 myExceptions.add(anE);
274 }
275 }
276
277 if (myExceptions.size() == 0)
278 return Collections.unmodifiableList(myEntrys);
279 else
280 throw new UnusableEntriesException("Couldn't unpack all Entrys",
281 myEntrys, myExceptions);
282 }
283
284 public EventRegistration
285 registerForAvailabilityEvent(Collection aTemplates, Transaction aTxn,
286 boolean visibilityOnly,
287 RemoteEventListener aListener,
288 long aLeaseTime,
289 MarshalledObject aHandback)
290 throws RemoteException, TransactionException {
291
292 MangledEntry[] myPackedTemplates = new MangledEntry[aTemplates.size()];
293 Iterator myTemplates = aTemplates.iterator();
294
295 int myIndex = 0;
296
297 while(myTemplates.hasNext()) {
298 Entry myEntry = (Entry) myTemplates.next();
299 myPackedTemplates[myIndex++] = packEntry(myEntry, false);
300 }
301
302 return theStub.registerForVisibility(myPackedTemplates, aTxn,
303 aListener, aLeaseTime, aHandback,
304 visibilityOnly);
305 }
306
307 public net.jini.space.MatchSet contents(Collection aTemplates,
308 Transaction aTxn,
309 long aLeaseTime,
310 long aLimit)
311 throws RemoteException, TransactionException {
312
313 if (aTemplates.size() == 0)
314 throw new IllegalArgumentException("No template entry's");
315
316 if (aLeaseTime == 0)
317 throw new IllegalArgumentException("Single bulk read via zero length lease time is no longer spec'd");
318
319 MangledEntry[] myMangledTemplates = new MangledEntry[aTemplates.size()];
320
321 Iterator myTemplates = aTemplates.iterator();
322
323 int myIndex = 0;
324
325 while (myTemplates.hasNext()) {
326 myMangledTemplates[myIndex++] =
327 packEntry((Entry) myTemplates.next(), false);
328 }
329
330 ViewResult myResult = theStub.newView(myMangledTemplates, aTxn,
331 aLeaseTime, true, aLimit, MatchSetImpl.CHUNK_SIZE);
332
333 return new MatchSetImpl(theStub, myResult.getLease(), aLimit,
334 myResult.getInitialBatch());
335 }
336
337 /* *******************************************************************
338 * End of JavaSpace05
339 * ******************************************************************/
340
341 public boolean equals(Object anObject) {
342 return ReferentUuids.compare(this, anObject);
343 }
344
345 public int hashCode() {
346 return theUuid.hashCode();
347 }
348
349 /**
350 As we put these default attributes on the proxy when we register it
351 and we need to include them in the dependencies, it makes sense to
352 have a method on this class to return those attributes. Thus, we
353 ensure the dependencies are accounted for and they're in the place
354 that is most closely related to them (the proxy to which they'll
355 be attached).
356 */
357 static Entry[] getDefaultAttrs(String aName) {
358 Entry myInfo =
359 new ServiceInfo(VersionInfo.PRODUCT_NAME,
360 VersionInfo.EMAIL_CONTACT,
361 VersionInfo.SUPPLIER_NAME,
362 VersionInfo.VERSION, "", "");
363
364 Entry myType = new BasicServiceType("JavaSpace/JavaSpace05");
365
366 if (aName != null) {
367 return new Entry[]{myInfo, myType, new Name(aName)};
368 } else {
369 return new Entry[]{myInfo, myType};
370 }
371 }
372 }