1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.graph.connector.federation;
25
26 import java.util.concurrent.CountDownLatch;
27 import net.jcip.annotations.NotThreadSafe;
28 import org.modeshape.graph.request.Request;
29
30
31
32
33
34 @NotThreadSafe
35 class FederatedRequest {
36 static final CountDownLatch CLOSED_LATCH = new CountDownLatch(0);
37
38 private final Request original;
39 private CountDownLatch forkLatch;
40 private int incompleteCount;
41 private ProjectedRequest first;
42
43 FederatedRequest( Request original ) {
44 this.original = original;
45 }
46
47 public Request original() {
48 return original;
49 }
50
51 public final FederatedRequest add( Request request,
52 boolean isSameLocationAsOriginal,
53 boolean isComplete,
54 Projection projection,
55 Projection secondProjection ) {
56 assert forkLatch == null;
57 if (!isComplete) ++incompleteCount;
58 if (first == null) {
59 if (isSameLocationAsOriginal) {
60 first = new MirrorRequest(request, isComplete, projection, secondProjection);
61 } else {
62 first = new ProjectedRequest(request, isComplete, projection, secondProjection);
63 }
64 } else {
65 first.addNext(request, isComplete, projection);
66 }
67 return this;
68 }
69
70 public final FederatedRequest add( Request request,
71 boolean isSameLocationAsOriginal,
72 boolean isComplete,
73 Projection projection ) {
74 return add(request, isSameLocationAsOriginal, isComplete, projection, null);
75 }
76
77 public void freeze() {
78 if (forkLatch == null) {
79 forkLatch = incompleteCount > 0 ? new CountDownLatch(incompleteCount) : CLOSED_LATCH;
80 }
81 }
82
83 public ProjectedRequest getFirstProjectedRequest() {
84 return first;
85 }
86
87 public boolean hasIncompleteRequests() {
88 return incompleteCount != 0;
89 }
90
91 public CountDownLatch getLatch() {
92 freeze();
93 return forkLatch;
94 }
95
96 public void await() throws InterruptedException {
97 if (forkLatch != null) forkLatch.await();
98 }
99
100
101
102
103
104
105 @Override
106 public String toString() {
107 StringBuilder sb = new StringBuilder();
108 sb.append("Federated request: ").append(original).append("\n");
109 ProjectedRequest projected = first;
110 while (projected != null) {
111 sb.append(" - ").append(projected).append("\n");
112 projected = projected.next();
113 }
114 return sb.toString();
115 }
116
117 class ProjectedRequest {
118 private final Projection projection;
119 private final Projection projection2;
120 private final Request request;
121 private final boolean isComplete;
122 private ProjectedRequest next;
123
124 protected ProjectedRequest( Request request,
125 boolean isComplete,
126 Projection projection,
127 Projection secondProjection ) {
128 this.projection = projection;
129 this.request = request;
130 this.isComplete = isComplete;
131 this.projection2 = secondProjection;
132 }
133
134 public final Projection getProjection() {
135 return projection;
136 }
137
138 public final Projection getSecondProjection() {
139 return projection2;
140 }
141
142 public final Request getRequest() {
143 return request;
144 }
145
146 public final boolean isComplete() {
147 return isComplete;
148 }
149
150 public boolean isSameLocation() {
151 return false;
152 }
153
154 public final ProjectedRequest next() {
155 return next;
156 }
157
158 public final boolean hasNext() {
159 return next != null;
160 }
161
162 protected final ProjectedRequest addNext( Request request,
163 boolean isComplete,
164 Projection projection,
165 Projection secondProjection ) {
166 ProjectedRequest last = this;
167 while (last.next != null) {
168 last = last.next;
169 }
170 last.next = new ProjectedRequest(request, isComplete, projection, secondProjection);
171 return last.next;
172 }
173
174 protected final ProjectedRequest addNext( Request request,
175 boolean isComplete,
176 Projection projection ) {
177 return addNext(request, isComplete, projection, null);
178 }
179
180
181
182
183
184
185 @Override
186 public String toString() {
187 StringBuilder sb = new StringBuilder();
188 sb.append("Projects to: ");
189 sb.append(request);
190 if (projection != null) {
191 sb.append(" using ");
192 sb.append(projection);
193 if (projection2 != null) {
194 sb.append(" and ");
195 sb.append(projection2);
196 }
197 }
198 if (isComplete) {
199 sb.append(" (complete)");
200 }
201 return sb.toString();
202 }
203 }
204
205 class MirrorRequest extends ProjectedRequest {
206 protected MirrorRequest( Request request,
207 boolean isComplete,
208 Projection projection,
209 Projection secondProjection ) {
210 super(request, isComplete, projection, secondProjection);
211 }
212
213 @Override
214 public boolean isSameLocation() {
215 return true;
216 }
217 }
218
219 }