1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.jini.core.constraint;
20
21 import java.io.IOException;
22 import java.io.InvalidObjectException;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectStreamField;
25 import java.io.Serializable;
26 import java.util.Collection;
27 import java.util.Set;
28 import org.apache.river.api.io.AtomicSerial;
29 import org.apache.river.api.io.AtomicSerial.GetArg;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 @AtomicSerial
49 public final class InvocationConstraints implements Serializable {
50 private static final long serialVersionUID = -3363161199079334224L;
51
52
53
54
55
56 private static final ObjectStreamField[] serialPersistentFields = {
57 new ObjectStreamField("reqs", InvocationConstraint[].class, true),
58 new ObjectStreamField("prefs", InvocationConstraint[].class, true)
59 };
60
61
62 private static final InvocationConstraint[] empty =
63 new InvocationConstraint[0];
64
65
66
67
68 private static final int REL_REQS = 1;
69
70
71
72 private static final int REL_PREFS = 2;
73
74
75
76
77 public static final InvocationConstraints EMPTY =
78 new InvocationConstraints((InvocationConstraint) null, null);
79
80
81
82
83 private InvocationConstraint[] reqs;
84
85
86
87 private InvocationConstraint[] prefs;
88
89
90
91
92
93 private transient int rel = 0;
94
95
96
97
98
99
100
101
102 public InvocationConstraints(GetArg arg) throws IOException{
103 this(arg.get("reqs", null, InvocationConstraint[].class),
104 arg.get("prefs", null, InvocationConstraint[].class),
105 true
106 );
107 }
108
109
110
111
112
113
114
115
116 private InvocationConstraints(InvocationConstraint[] reqs,
117 InvocationConstraint[] prefs,
118 boolean serial) throws InvalidObjectException
119 {
120 this(check(reqs, prefs),
121 verify(reqs),
122 verify(prefs)
123 );
124 }
125
126 private static boolean check(InvocationConstraint[] reqs,
127 InvocationConstraint[] prefs) throws InvalidObjectException
128 {
129 for (int i = prefs.length; --i >= 0; ) {
130 if (Constraint.contains(reqs, reqs.length, prefs[i])) {
131 throw new InvalidObjectException(
132 "cannot create constraint with redundant elements");
133 }
134 }
135 return true;
136 }
137
138
139
140
141
142
143
144 private InvocationConstraints(boolean serial,
145 InvocationConstraint[] reqs,
146 InvocationConstraint[] prefs)
147 {
148 this.reqs = reqs;
149 this.prefs = prefs;
150 setRelative(reqs, REL_REQS);
151 setRelative(prefs, REL_REQS);
152 }
153
154
155
156
157
158
159
160
161
162
163
164 public InvocationConstraints(InvocationConstraint req,
165 InvocationConstraint pref)
166 {
167 if (req != null) {
168 reqs = new InvocationConstraint[]{req};
169 }
170 if (pref != null) {
171 prefs = new InvocationConstraint[]{pref};
172 }
173 reduce();
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 public InvocationConstraints(InvocationConstraint[] reqs,
193 InvocationConstraint[] prefs)
194 {
195 if (reqs != null) {
196 this.reqs = (InvocationConstraint[]) reqs.clone();
197 }
198 if (prefs != null) {
199 this.prefs = (InvocationConstraint[]) prefs.clone();
200 }
201 reduce();
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 public InvocationConstraints(Collection<InvocationConstraint> reqs, Collection<InvocationConstraint> prefs) {
223 try {
224 if (reqs != null) {
225 this.reqs = reqs.toArray(new InvocationConstraint[reqs.size()]);
226 }
227 if (prefs != null) {
228 this.prefs = prefs.toArray(
229 new InvocationConstraint[prefs.size()]);
230 }
231 } catch (ArrayStoreException e) {
232 throw new IllegalArgumentException(
233 "element of collection is not an InvocationConstraint");
234 }
235 reduce();
236 }
237
238
239
240
241
242
243
244
245
246
247 private InvocationConstraints(InvocationConstraint[] reqs,
248 int reqidx,
249 InvocationConstraint[] prefs,
250 int prefidx,
251 int rel)
252 {
253 this.reqs = reqs;
254 this.prefs = prefs;
255 reduce(reqidx, prefidx);
256 this.rel = rel;
257 }
258
259
260
261
262
263 private void reduce() {
264 if (reqs == null) {
265 reqs = empty;
266 }
267 if (prefs == null) {
268 prefs = empty;
269 }
270 reduce(0, 0);
271 setRelative(reqs, REL_REQS);
272 setRelative(prefs, REL_PREFS);
273 }
274
275
276
277
278
279
280
281
282 private void reduce(int reqidx, int prefidx) {
283 for (int i = reqidx; i < reqs.length; i++) {
284 InvocationConstraint req = reqs[i];
285 if (req == null) {
286 throw new NullPointerException("elements cannot be null");
287 } else if (!Constraint.contains(reqs, reqidx, req)) {
288 reqs[reqidx++] = req;
289 }
290 }
291 reqs = (InvocationConstraint[]) Constraint.trim(reqs, reqidx);
292 for (int i = prefidx; i < prefs.length; i++) {
293 InvocationConstraint pref = prefs[i];
294 if (pref == null) {
295 throw new NullPointerException("elements cannot be null");
296 } else if (!Constraint.contains(prefs, prefidx, pref) &&
297 !Constraint.contains(reqs, reqs.length, pref))
298 {
299 prefs[prefidx++] = pref;
300 }
301 }
302 prefs = (InvocationConstraint[]) Constraint.trim(prefs, prefidx);
303 }
304
305
306
307
308
309
310 private static boolean relative(InvocationConstraint c) {
311 return (c instanceof RelativeTimeConstraint &&
312 (!(c instanceof ConstraintAlternatives) ||
313 ((ConstraintAlternatives) c).relative()));
314 }
315
316
317
318
319
320 private void setRelative(InvocationConstraint[] constraints, int flag) {
321 for (int i = constraints.length; --i >= 0; ) {
322 if (relative(constraints[i])) {
323 rel |= flag;
324 return;
325 }
326 }
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343 public static InvocationConstraints combine(
344 InvocationConstraints constraints1,
345 InvocationConstraints constraints2)
346 {
347 if (constraints1 == null || constraints1.isEmpty()) {
348 return constraints2 == null ? EMPTY : constraints2;
349 } else if (constraints2 == null || constraints2.isEmpty()) {
350 return constraints1;
351 } else if (constraints2.reqs.length > constraints1.reqs.length) {
352 InvocationConstraints tmp = constraints1;
353 constraints1 = constraints2;
354 constraints2 = tmp;
355 }
356 int prefidx;
357 InvocationConstraint[] reqs;
358 if (constraints2.reqs.length > 0) {
359 reqs = concat(constraints1.reqs, constraints2.reqs);
360 prefidx = 0;
361 } else {
362 reqs = constraints1.reqs;
363 prefidx = constraints1.prefs.length;
364 }
365 InvocationConstraint[] prefs;
366 if (constraints1.prefs.length > 0 || constraints2.prefs.length > 0) {
367 prefs = concat(constraints1.prefs, constraints2.prefs);
368 } else {
369 prefs = empty;
370 }
371 return new InvocationConstraints(reqs, constraints1.reqs.length,
372 prefs, prefidx,
373 constraints1.rel | constraints2.rel);
374 }
375
376
377
378
379 private static InvocationConstraint[] concat(InvocationConstraint[] arr1,
380 InvocationConstraint[] arr2)
381 {
382 InvocationConstraint[] res =
383 new InvocationConstraint[arr1.length + arr2.length];
384 System.arraycopy(arr1, 0, res, 0, arr1.length);
385 System.arraycopy(arr2, 0, res, arr1.length, arr2.length);
386 return res;
387 }
388
389
390
391
392 private static InvocationConstraint[] makeAbsolute(
393 InvocationConstraint[] arr,
394 long baseTime)
395 {
396 InvocationConstraint[] narr = new InvocationConstraint[arr.length];
397 for (int i = arr.length; --i >= 0; ) {
398 InvocationConstraint c = arr[i];
399 if (c instanceof RelativeTimeConstraint) {
400 c = ((RelativeTimeConstraint) c).makeAbsolute(baseTime);
401 }
402 narr[i] = c;
403 }
404 return narr;
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 public InvocationConstraints makeAbsolute(long baseTime) {
427 if (rel == 0) {
428 return this;
429 }
430 InvocationConstraint[] nreqs;
431 int reqidx;
432 if ((rel & REL_REQS) != 0) {
433 nreqs = makeAbsolute(reqs, baseTime);
434 reqidx = 0;
435 } else {
436 nreqs = reqs;
437 reqidx = reqs.length;
438 }
439 InvocationConstraint[] nprefs;
440 if ((rel & REL_PREFS) != 0) {
441 nprefs = makeAbsolute(prefs, baseTime);
442 } else {
443 nprefs = (InvocationConstraint[]) prefs.clone();
444 }
445 return new InvocationConstraints(nreqs, reqidx, nprefs, 0, 0);
446 }
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464 public InvocationConstraints makeAbsolute() {
465 if (rel == 0) {
466 return this;
467 }
468 return makeAbsolute(System.currentTimeMillis());
469 }
470
471
472
473
474
475
476
477
478 public Set<InvocationConstraint> requirements() {
479 return new ArraySet<InvocationConstraint>(reqs);
480 }
481
482
483
484
485
486
487
488
489 public Set<InvocationConstraint> preferences() {
490 return new ArraySet<InvocationConstraint>(prefs);
491 }
492
493
494
495
496
497
498
499
500 public boolean isEmpty() {
501 return reqs.length == 0 && prefs.length == 0;
502 }
503
504
505
506
507 public int hashCode() {
508 return Constraint.hash(reqs) + Constraint.hash(prefs);
509 }
510
511
512
513
514
515
516
517 public boolean equals(Object obj) {
518 if (this == obj) {
519 return true;
520 } else if (!(obj instanceof InvocationConstraints)) {
521 return false;
522 }
523 InvocationConstraints sc = (InvocationConstraints)obj;
524 return (Constraint.equal(reqs, sc.reqs) &&
525 Constraint.equal(prefs, sc.prefs));
526 }
527
528
529
530
531 public String toString() {
532 return ("InvocationConstraints[reqs: " + Constraint.toString(reqs) +
533 ", prefs: " + Constraint.toString(prefs) + "]");
534 }
535
536
537
538
539
540
541
542
543
544
545
546
547
548 private void readObject(ObjectInputStream s)
549 throws IOException, ClassNotFoundException
550 {
551 s.defaultReadObject();
552 verify(reqs);
553 verify(prefs);
554 for (int i = prefs.length; --i >= 0; ) {
555 if (Constraint.contains(reqs, reqs.length, prefs[i])) {
556 throw new InvalidObjectException(
557 "cannot create constraint with redundant elements");
558 }
559 }
560 setRelative(reqs, REL_REQS);
561 setRelative(prefs, REL_REQS);
562 }
563
564
565
566
567
568 private static InvocationConstraint[] verify(InvocationConstraint[] constraints)
569 throws InvalidObjectException
570 {
571 if (constraints == null) {
572 throw new InvalidObjectException("array cannot be null");
573 }
574 for (int i = constraints.length; --i >= 0; ) {
575 InvocationConstraint c = constraints[i];
576 if (c == null) {
577 throw new InvalidObjectException("elements cannot be null");
578 } else if (Constraint.contains(constraints, i, c)) {
579 throw new InvalidObjectException(
580 "cannot create constraint with redundant elements");
581 }
582 }
583 return constraints;
584 }
585 }