/*
 * Copyright 2013, The gwtquery team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.query.client.plugins.deferred;

import java.util.Set;

import javax.validation.ConstraintViolation;

import com.google.gwt.query.client.plugins.deferred.Deferred.DeferredPromiseImpl;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

/**
 * Utility class used to create promises for RequestFactory services.
 * <pre>
 *    Request<SessionProxy> req1 = loginFact.api().login(null, null);
 *    Request<UserProxy> req2 = srvFact.api().getCurrentUser();
 *    
 *    Promise requestingAll = Deferred.when(new PromiseRF(req1), new PromiseRF(req2);
 *    
 *    requestingAll.done(new Function() {
 *        public void f() {
 *          SessionProxy session = arguments(0, 0);
 *          UserProxy user = arguments(1, 0);
 *        }
 *      })
 *      .fail(new Function() {
 *        public void f() {
 *          ServerFailure failure = arguments(0);
 *        }
 *      }); 
 * </pre>
 */
public class PromiseRF extends DeferredPromiseImpl {
  public <T> PromiseRF(com.google.web.bindery.requestfactory.shared.Request<T> request) {
    request.fire(new Receiver<T>() {
      public void onConstraintViolation(Set<ConstraintViolation<?>> violations) {
        dfd.reject(new ServerFailure("ConstraintViolation"), violations);
      }

      public void onFailure(ServerFailure error) {
        dfd.reject(error);
      }

      public void onSuccess(T response) {
        dfd.resolve(response);
      }
    });
  }
}

@@ -641,16 +641,67 @@
 erred;%0A%0A
+import java.util.ArrayList;%0Aimport java.util.List;%0A
 import j
@@ -905,16 +905,145 @@
 ceiver;%0A
+import com.google.web.bindery.requestfactory.shared.Request;%0Aimport com.google.web.bindery.requestfactory.shared.RequestContext;%0A
 import c
@@ -1322,24 +1322,80 @@
 r();%0A *    %0A
+ *    // We can use %60when%60 to append different requests%0A
  *    Promis
@@ -1468,16 +1468,138 @@
 (req2);%0A
+ *    // Or we can use just one promise for multiple RF requests%0A *    Promise requestingAll = new PromiseRF(req1, req2);%0A
  *    %0A 
@@ -1996,81 +1996,496 @@
 %0A  p
-ublic %3CT%3E PromiseRF(com.google.web.bindery.requestfactory.shared.
+rivate int total = 0;%0A  private List%3CObject%3E responses = new ArrayList%3CObject%3E();%0A  private List%3CRequestContext%3E contexts = new ArrayList%3CRequestContext%3E();%0A  %0A  /**%0A   * Fire a RF Request.%0A   */%0A  public %3CT%3E PromiseRF(Request%3CT%3E request) %7B%0A    this(new Request%3C?%3E%5B%5D %7Brequest%7D);%0A  %7D%0A%0A  /**%0A   * Fire multiple RF Requests.%0A   *%0A   * Unlike RequestContext.append which only supports compatible requests,%0A   * we can append any kind of requestContexts here.%0A   */%0A  public PromiseRF(
 Request%3C
 T%3E r
@@ -2476,34 +2476,36 @@
 eRF(Request%3C
-T%3E
+?%3E%5B%5D
  request
 ) %7B%0A    requ
@@ -2492,24 +2492,25 @@
  request
+s
 ) %7B%0A    
 request.
@@ -2505,20 +2505,78 @@
     
-request.fire
+for (Request%3C?%3E request : requests) %7B%0A      total ++;%0A      request.to
 (new
@@ -2589,15 +2589,22 @@
 ver%3C
-T
+Object
 %3E() %7B%0A
+  
     
@@ -2681,32 +2681,34 @@
 ions) %7B%0A        
+  
 dfd.reject(new S
@@ -2755,35 +2755,38 @@
 lations);%0A      
-%7D%0A%0A
+  %7D%0A  
       public voi
@@ -2820,32 +2820,34 @@
 rror) %7B%0A        
+  
 dfd.reject(error
@@ -2859,17 +2859,20 @@
     
+  
 %7D%0A
-%0A
+ 
       
+ 
 publ
@@ -2889,17 +2889,22 @@
 Success(
-T
+Object
  respons
@@ -2920,46 +2920,552 @@
     
-dfd.resolve(response);%0A      %7D%0A    %7D);
+  responses.add(response);%0A          // Resolve only when all requests have been received%0A          if (responses.size() == total) %7B%0A            dfd.resolve(responses.toArray(new Object%5Bresponses.size()%5D));%0A          %7D%0A        %7D%0A      %7D);%0A      if (!contexts.contains(request.getRequestContext())) %7B%0A        contexts.add(request.getRequestContext());%0A      %7D%0A    %7D%0A%0A    // We fire each context instead of appending them so as we can deal%0A    // with different request factories.%0A    for (RequestContext ctx : contexts) %7B%0A      ctx.fire();%0A    %7D
 %0A  %7D

Support for multiple request in RF Promise helper