1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.functor.example.kata.two;
18
19 import org.apache.commons.functor.Function;
20 import org.apache.commons.functor.Predicate;
21 import org.apache.commons.functor.Procedure;
22 import org.apache.commons.functor.core.Constant;
23 import org.apache.commons.functor.core.NoOp;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class EiffelStyleLoop implements Procedure {
46 public EiffelStyleLoop from(Procedure procedure) {
47 from = procedure;
48 return this;
49 }
50
51 public EiffelStyleLoop invariant(Predicate predicate) {
52 invariant = predicate;
53 return this;
54 }
55
56 public EiffelStyleLoop variant(Predicate predicate) {
57 variant = predicate;
58 return this;
59 }
60
61 @SuppressWarnings("unchecked")
62 public EiffelStyleLoop variant(final Function function) {
63 return variant(new Predicate() {
64 public boolean test() {
65 boolean result = true;
66 Comparable next = (Comparable)(function.evaluate());
67 if (null != last) {
68 result = last.compareTo(next) > 0;
69 }
70 last = next;
71 return result;
72 }
73 private Comparable last = null;
74 });
75 }
76
77 public EiffelStyleLoop until(Predicate predicate) {
78 until = predicate;
79 return this;
80 }
81
82 public EiffelStyleLoop loop(Procedure procedure) {
83 loop = procedure;
84 return this;
85 }
86
87 public void run() {
88 from.run();
89 assertTrue(invariant.test());
90 while(! until.test() ) {
91 loop.run();
92 assertTrue(variant.test());
93 assertTrue(invariant.test());
94 }
95
96
97
98
99
100
101
102
103
104
105 }
106
107 private void assertTrue(boolean value) {
108 if (!value) {
109 throw new IllegalStateException("Assertion failed");
110 }
111 }
112
113 private Procedure from = NoOp.instance();
114 private Predicate invariant = Constant.truePredicate();
115 private Predicate variant = Constant.truePredicate();
116 private Predicate until = Constant.falsePredicate();
117 private Procedure loop = NoOp.instance();
118
119 }