View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * Unless otherwise indicated, all code in ModeShape is licensed
10   * to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   * 
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
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   * A wrapper for a request submitted to the federated repository, and the corresponding source-specific {@link ProjectedRequest
32   * projected requests}.
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      * {@inheritDoc}
102      * 
103      * @see java.lang.Object#toString()
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          * {@inheritDoc}
182          * 
183          * @see java.lang.Object#toString()
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 }