Mercurial > hg > blitz_condensed
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 } |