Author: gagan
Date: Wed Mar  9 18:49:24 2011
New Revision: 1079931

URL: http://svn.apache.org/viewvc?rev=1079931&view=rev
Log:
Patch by pulkitgoyal2000 | Issue 3734041: Concatenated URLs should not exceed 
GET URL size limit | http://codereview.appspot.com/3734041/

Modified:
    shindig/trunk/java/common/conf/shindig.properties
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ConcatUriManager.java
    
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java
    
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManagerTest.java

Modified: shindig/trunk/java/common/conf/shindig.properties
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/conf/shindig.properties?rev=1079931&r1=1079930&r2=1079931&view=diff
==============================================================================
--- shindig/trunk/java/common/conf/shindig.properties (original)
+++ shindig/trunk/java/common/conf/shindig.properties Wed Mar  9 18:49:24 2011
@@ -165,4 +165,7 @@ vanillaCajaParser.needsDebugData=true
 org.apache.shindig.auth.oauth2-require-ssl=false
 
 # Set gadget param in proxied uri as authority if this is true
-org.apache.shindig.gadgets.uri.setAuthorityAsGadgetParam=false
\ No newline at end of file
+org.apache.shindig.gadgets.uri.setAuthorityAsGadgetParam=false
+
+# Maximum Get Url size limit
+org.apache.shindig.gadgets.uri.urlMaxLength=2048

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java?rev=1079931&r1=1079930&r2=1079931&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ConcatVisitor.java
 Wed Mar  9 18:49:24 2011
@@ -184,12 +184,14 @@ public class ConcatVisitor implements Do
       List<Element> sourceBatch = elemBatchIt.next();
       List<Uri> sourceUris = uriBatchIt.next();
 
-      // Regardless what happens, inject a copy of the first node,
-      // with new (concat) URI, immediately ahead of the first elem.
+      // Regardless what happens, inject as many copies of the first node
+      // as needed, with new (concat) URI, immediately ahead of the first elem.
       Element firstElem = sourceBatch.get(0);
-      Element elemConcat = (Element)firstElem.cloneNode(true);
-      elemConcat.setAttribute(type.getSrcAttrib(), 
concatUri.getUri().toString());
-      firstElem.getParentNode().insertBefore(elemConcat, firstElem);
+      for (Uri uri : concatUri.getUris()) {
+        Element elemConcat = (Element)firstElem.cloneNode(true);
+        elemConcat.setAttribute(type.getSrcAttrib(), uri.toString());
+        firstElem.getParentNode().insertBefore(elemConcat, firstElem);
+      }
 
       // Now for all Elements, either A) remove them or B) replace each
       // with a <script> node with snippet of code configuring/evaluating

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ConcatUriManager.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ConcatUriManager.java?rev=1079931&r1=1079930&r2=1079931&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ConcatUriManager.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/ConcatUriManager.java
 Wed Mar  9 18:49:24 2011
@@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.gadgets.Gadget;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -83,7 +84,7 @@ public interface ConcatUriManager {
       return null;
     }
   }
-  
+
   /**
    * Generate Uris that concatenate all given resources together.
    * @param batches List of batches to concatenate
@@ -104,18 +105,18 @@ public interface ConcatUriManager {
    * in their correct original position.
    */
   public static class ConcatData {
-    private final Uri uri;
+    private final List<Uri> uris;
     private final Map<Uri, String> snippets;
-    
-    public ConcatData(Uri uri, Map<Uri, String> snippets) {
-      this.uri = uri;
+
+    public ConcatData(List<Uri> uris, Map<Uri, String> snippets) {
+      this.uris = Collections.unmodifiableList(uris);
       this.snippets = snippets;
     }
-    
-    public Uri getUri() {
-      return uri;
+
+    public List<Uri> getUris() {
+      return uris;
     }
-    
+
     public String getSnippet(Uri orig) {
       return snippets == null || !snippets.containsKey(orig) ?
           null : snippets.get(orig);
@@ -173,7 +174,7 @@ public interface ConcatUriManager {
     public String getSplitParam() {
       return splitParam;
     }
-    
+
     public static List<ConcatUri> fromList(Gadget gadget, List<List<Uri>> 
batches, Type type) {
       List<ConcatUri> ctx = Lists.newArrayListWithCapacity(batches.size());
       for (List<Uri> batch : batches) {

Modified: 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java?rev=1079931&r1=1079930&r2=1079931&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManager.java
 Wed Mar  9 18:49:24 2011
@@ -54,6 +54,9 @@ public class DefaultConcatUriManager imp
   private final ContainerConfig config;
   private final Versioner versioner;
   private boolean strictParsing;
+  private static int DEFAULT_URL_MAX_LENGTH = 2048;
+  private int urlMaxLength = DEFAULT_URL_MAX_LENGTH;
+  private static final float URL_LENGTH_BUFFER_MARGIN = .8f;
 
   @Inject
   public DefaultConcatUriManager(ContainerConfig config, @Nullable Versioner 
versioner) {
@@ -67,6 +70,16 @@ public class DefaultConcatUriManager imp
     this.strictParsing = useStrict;
   }
 
+  @Inject(optional = true)
+  public void setUrlMaxLength(
+      @Named("org.apache.shindig.gadgets.uri.urlMaxLength") int urlMaxLength) {
+    this.urlMaxLength = urlMaxLength;
+  }
+
+  public int getUrlMaxLength() {
+    return this.urlMaxLength;
+  }
+
   public List<ConcatData> make(List<ConcatUri> resourceUris,
       boolean isAdjacent) {
     List<ConcatData> concatUris = 
Lists.newArrayListWithCapacity(resourceUris.size());
@@ -78,27 +91,14 @@ public class DefaultConcatUriManager imp
     ConcatUri exemplar = resourceUris.get(0);
     String container = exemplar.getContainer();
 
-    List<String> versions = null;
-    List<List<Uri>> batches = 
Lists.newArrayListWithCapacity(resourceUris.size());
-    for (ConcatUri ctx : resourceUris) {
-      batches.add(ctx.getBatch());
-    }
-
-    if (versioner != null) {
-      versions = versioner.version(batches, container);
-    }
-
-    Iterator<String> versionIt = versions != null ? versions.iterator() : null;
     for (ConcatUri ctx : resourceUris) {
-      String version = versionIt != null ? versionIt.next() : null;
-      concatUris.add(
-          makeConcatUri(ctx, isAdjacent, version));
+      concatUris.add(makeConcatUri(ctx, isAdjacent, container));
     }
 
     return concatUris;
   }
 
-  private ConcatData makeConcatUri(ConcatUri ctx, boolean isAdjacent, String 
version) {
+  private ConcatData makeConcatUri(ConcatUri ctx, boolean isAdjacent, String 
container) {
     // TODO: Consider per-bundle isAdjacent plus first-bundle direct evaluation
 
     if (!isAdjacent && ctx.getType() != Type.JS) {
@@ -107,34 +107,108 @@ public class DefaultConcatUriManager imp
       throw new UnsupportedOperationException("Split concatenation only 
supported for JS");
     }
 
-    UriBuilder uriBuilder = ctx.makeQueryParams(null, version);
-
     String concatHost = getReqVal(ctx.getContainer(), CONCAT_HOST_PARAM);
     String concatPath = getReqVal(ctx.getContainer(), CONCAT_PATH_PARAM);
-    uriBuilder.setAuthority(concatHost);
-    uriBuilder.setPath(concatPath);
 
-    uriBuilder.addQueryParameter(Param.TYPE.getKey(), ctx.getType().getType());
     List<Uri> resourceUris = ctx.getBatch();
     Map<Uri, String> snippets = 
Maps.newHashMapWithExpectedSize(resourceUris.size());
-
+    
     String splitParam = config.getString(ctx.getContainer(), 
CONCAT_JS_SPLIT_PARAM);
+
     boolean doSplit = false;
     if (!isAdjacent && splitParam != null && 
!"false".equalsIgnoreCase(splitParam)) {
-      uriBuilder.addQueryParameter(Param.JSON.getKey(), splitParam);
       doSplit = true;
     }
 
+    UriBuilder uriBuilder = makeUriBuilder(ctx, concatHost, concatPath);
+
+    // Allowed Max Url length is .80 times of actual max length. So, Split will
+    // happen whenever Concat url length crosses this value. Here, buffer also 
assumes
+    // version length.
+    int injectedMaxUrlLength = (int) (this.getUrlMaxLength() * 
URL_LENGTH_BUFFER_MARGIN);
+
+    // batchUris holds uris for the current batch of uris being concatenated.
+    List<Uri> batchUris = Lists.newArrayList();
+
+    // uris holds the concatenated uris formed from batches which satisfy the 
+    // GET URL limit constraint.
+    List<Uri> uris = Lists.newArrayList();
+
     Integer i = Integer.valueOf(START_INDEX);
     for (Uri resource : resourceUris) {
       uriBuilder.addQueryParameter(i.toString(), resource.toString());
+      if (uriBuilder.toString().length() > injectedMaxUrlLength) {
+        uriBuilder.removeQueryParameter(i.toString());
+
+        addVersionAndSplitParam(uriBuilder, splitParam, doSplit, batchUris, 
container);
+        uris.add(uriBuilder.toUri());
+
+        uriBuilder = makeUriBuilder(ctx, concatHost, concatPath);
+        batchUris = Lists.newArrayList();
+        i = Integer.valueOf(START_INDEX);
+        uriBuilder.addQueryParameter(i.toString(), resource.toString());
+      }
       i++;
-      if (doSplit) {
+      batchUris.add(resource);
+    }
+
+    if (batchUris != null && uriBuilder != ctx.makeQueryParams(null, null)) {
+      addVersionAndSplitParam(uriBuilder, splitParam, doSplit, batchUris, 
container);
+      uris.add(uriBuilder.toUri());
+    }
+
+    if (doSplit) {
+      snippets = createSnippets(uris);
+    }
+   return new ConcatData(uris, snippets);
+  }
+
+  private void addVersionAndSplitParam(UriBuilder uriBuilder, String 
splitParam, boolean doSplit,
+                                       List<Uri> batchUris, String container) {
+    // HashCode is used to differentiate splitParam paramter across ConcatUris
+    // within single page/url. This value is appended to the splitParam value 
which
+    // is recieved from config container.
+    int hashCode = uriBuilder.hashCode();
+    if (doSplit) {
+      uriBuilder.addQueryParameter(Param.JSON.getKey(),
+          (splitParam + String.valueOf(Math.abs(hashCode))));
+    }
+    
+    if (versioner != null) {
+      List<String> versions = null;
+      List<List<Uri>> batches = Lists.newArrayList();
+      batches.add(batchUris);
+      versions = versioner.version(batches, container);
+      if (versions != null && versions.size() == 1) {
+        String version = versions.get(0);
+        if (version != null) {
+          uriBuilder.addQueryParameter(Param.VERSION.getKey(), version);
+        }
+      }
+    }
+  }
+
+  private Map<Uri, String> createSnippets(List<Uri> uris) {
+    Map<Uri, String> snippets = Maps.newHashMap();
+    for (Uri uri : uris) {
+      Integer i = Integer.valueOf(START_INDEX);
+      String splitParam = uri.getQueryParameter(Param.JSON.getKey());
+      String resourceUri = null;
+      while ((resourceUri = uri.getQueryParameter(i.toString())) != null) {
+        Uri resource = Uri.parse(resourceUri);
         snippets.put(resource, getJsSnippet(splitParam, resource));
+        i++;
       }
     }
+    return snippets;
+  }
 
-    return new ConcatData(uriBuilder.toUri(), snippets);
+  private UriBuilder makeUriBuilder(ConcatUri ctx, String authority, String 
path) {
+    UriBuilder uriBuilder = ctx.makeQueryParams(null, null);
+    uriBuilder.setAuthority(authority);
+    uriBuilder.setPath(path);
+    uriBuilder.addQueryParameter(Param.TYPE.getKey(), ctx.getType().getType());
+    return uriBuilder;
   }
 
   static String getJsSnippet(String splitParam, Uri resource) {
@@ -202,8 +276,6 @@ public class DefaultConcatUriManager imp
         status = versioner.validate(uris, container, version);
       }
     }
-
     return new ConcatUri(status, uris, splitParam, type, uri);
   }
-
 }

Modified: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java?rev=1079931&r1=1079930&r2=1079931&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ConcatVisitorTest.java
 Wed Mar  9 18:49:24 2011
@@ -908,7 +908,7 @@ public class ConcatVisitorTest extends D
           }
           uriBuilder.addQueryParameter("SPLIT", "1");
         }
-        results.add(new ConcatData(uriBuilder.toUri(), snippets));
+        results.add(new ConcatData(Lists.newArrayList(uriBuilder.toUri()), 
snippets));
       }
       return results;
     }

Modified: 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManagerTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManagerTest.java?rev=1079931&r1=1079930&r2=1079931&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManagerTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/uri/DefaultConcatUriManagerTest.java
 Wed Mar  9 18:49:24 2011
@@ -26,9 +26,11 @@ import static org.easymock.EasyMock.isA;
 import static org.easymock.EasyMock.replay;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import com.google.common.collect.ImmutableList;
 import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.RandomStringUtils;
 import org.apache.shindig.config.ContainerConfig;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.gadgets.Gadget;
@@ -38,7 +40,7 @@ import org.apache.shindig.gadgets.uri.Ur
 import org.junit.Test;
 
 import java.util.List;
-import java.util.NoSuchElementException;
+import java.util.HashMap;
 
 public class DefaultConcatUriManagerTest extends UriManagerTestBase {
   private static final Uri RESOURCE_1 = 
Uri.parse("http://example.com/one.dat";);
@@ -70,11 +72,6 @@ public class DefaultConcatUriManagerTest
     checkValidatedBatchAdjacent(ConcatUriManager.Type.CSS);
   }
 
-  @Test(expected = NoSuchElementException.class)
-  public void typeCssBatchInsufficientVersions() throws Exception {
-    checkBatchInsufficientVersions(ConcatUriManager.Type.CSS);
-  }
-
   @Test(expected = RuntimeException.class)
   public void typeCssMissingHostConfig() throws Exception {
     checkMissingHostConfig(ConcatUriManager.Type.CSS);
@@ -117,41 +114,43 @@ public class DefaultConcatUriManagerTest
     String path = "/concat/path";
     ConcatUriManager.Type type = ConcatUriManager.Type.JS;
     String splitParam = "token";
-    String[] versions = new String[] { "version1", "v2", "v3" };
+    String[] versions = new String[] { "version1" };
     ConcatUriManager.Versioner versioner = makeVersioner(null, versions);
     DefaultConcatUriManager manager = makeManager(host, path, splitParam, 
versioner);
     List<List<Uri>> resourceUris =
         ImmutableList.of(RESOURCES_ONE, RESOURCES_TWO, RESOURCES_ONE);
-
+    HashMap<String, String> jsonParams = new HashMap<String, String>();
     List<ConcatData> concatUris =
         manager.make(fromList(gadget, resourceUris, type), false);
     assertEquals(3, concatUris.size());
 
     for (int i = 0; i < 3; ++i) {
       ConcatData uri = concatUris.get(i);
-      assertEquals(DefaultConcatUriManager.getJsSnippet(splitParam, 
RESOURCE_1),
+      assertEquals(1, uri.getUris().size());
+      String json = uri.getUris().get(0).getQueryParameter(
+          (Param.JSON.toString().toLowerCase()));
+      assertTrue(json.startsWith(splitParam));
+      String currentUri = uri.getUris().get(0).toString();
+      if (jsonParams.keySet().contains(currentUri)) {
+        assertEquals(jsonParams.get(currentUri), json);
+      } else {
+        jsonParams.put(currentUri, json);
+      }
+
+      assertEquals(DefaultConcatUriManager.getJsSnippet(json, RESOURCE_1),
           uri.getSnippet(RESOURCE_1));
-      assertEquals(DefaultConcatUriManager.getJsSnippet(splitParam, 
RESOURCE_2),
+      assertEquals(DefaultConcatUriManager.getJsSnippet(json, RESOURCE_2),
           uri.getSnippet(RESOURCE_2));
       assertNull(uri.getSnippet(RESOURCE_3_NOSCHEMA));
-      assertEquals(DefaultConcatUriManager.getJsSnippet(splitParam, 
RESOURCE_3_HTTP),
+      assertEquals(DefaultConcatUriManager.getJsSnippet(json, RESOURCE_3_HTTP),
           uri.getSnippet(RESOURCE_3_HTTP));
-      assertNull(uri.getUri().getScheme());
-      assertEquals(host, uri.getUri().getAuthority());
-      assertEquals(path, uri.getUri().getPath());
-      assertEquals(10, uri.getUri().getQueryParameters().size());
-      assertEquals(CONTAINER, 
uri.getUri().getQueryParameter(Param.CONTAINER.getKey()));
-      assertEquals(SPEC_URI.toString(), 
uri.getUri().getQueryParameter(Param.GADGET.getKey()));
-      assertEquals(type.getType(), 
uri.getUri().getQueryParameter(Param.TYPE.getKey()));
-      assertEquals("0", uri.getUri().getQueryParameter(Param.DEBUG.getKey()));
-      assertEquals("0", 
uri.getUri().getQueryParameter(Param.NO_CACHE.getKey()));
-      assertEquals(type.getType(), 
uri.getUri().getQueryParameter(Param.TYPE.getKey()));
+      checkBasicUriParameters(uri.getUris().get(0), host, path, 10, type, "0", 
"0", versions[0]);
       List<Uri> resList = (i % 2 == 0) ? RESOURCES_ONE : RESOURCES_TWO;
-      assertEquals(resList.get(0).toString(), 
uri.getUri().getQueryParameter("1"));
-      assertEquals(resList.get(1).toString(), 
uri.getUri().getQueryParameter("2"));
-      assertEquals(resList.get(2).toString(), 
uri.getUri().getQueryParameter("3"));
-      assertEquals(versions[i], 
uri.getUri().getQueryParameter(Param.VERSION.getKey()));
+      assertEquals(resList.get(0).toString(), 
uri.getUris().get(0).getQueryParameter("1"));
+      assertEquals(resList.get(1).toString(), 
uri.getUris().get(0).getQueryParameter("2"));
+      assertEquals(resList.get(2).toString(), 
uri.getUris().get(0).getQueryParameter("3"));
     }
+    assertEquals(2, jsonParams.size());
   }
 
   @Test
@@ -159,18 +158,6 @@ public class DefaultConcatUriManagerTest
     checkValidatedBatchAdjacent(ConcatUriManager.Type.JS);
   }
 
-  @Test(expected=NoSuchElementException.class)
-  public void typeJsBatchInsufficientVersions() throws Exception {
-    Gadget gadget = mockGadget(true, true);
-    String host = "bar.com";
-    String path = "/other/path";
-    String[] versions = new String[] { "v1" };  // Only one for three 
resources.
-    ConcatUriManager.Versioner versioner = makeVersioner(null, versions);
-    DefaultConcatUriManager manager = makeManager(host, path, "token", 
versioner);
-    List<List<Uri>> resourceUris = ImmutableList.of(RESOURCES_ONE, 
RESOURCES_ONE);
-    manager.make(fromList(gadget, resourceUris, ConcatUriManager.Type.JS), 
true);
-  }
-
   @Test(expected = RuntimeException.class)
   public void typeJsMissingHostConfig() throws Exception {
     Gadget gadget = mockGadget(false, false);
@@ -194,7 +181,8 @@ public class DefaultConcatUriManagerTest
     List<List<Uri>> resourceUris = 
ImmutableList.<List<Uri>>of(ImmutableList.of(RESOURCE_1));
     List<ConcatData> concatUris = manager.make(fromList(gadget, resourceUris, 
ConcatUriManager.Type.JS), false);
     assertEquals(1, concatUris.size());
-    
assertNull(concatUris.get(0).getUri().getQueryParameter(Param.JSON.getKey()));
+    assertEquals(1, concatUris.get(0).getUris().size());
+    
assertNull(concatUris.get(0).getUris().get(0).getQueryParameter(Param.JSON.getKey()));
   }
 
   @Test
@@ -311,6 +299,124 @@ public class DefaultConcatUriManagerTest
     checkValidateUri(UriStatus.INVALID_VERSION, ConcatUriManager.Type.JS, 
true);
   }
 
+  @Test
+  public void dontConcatMultipleResourceBeyoundUrlLimitSplitBatched() throws 
Exception {
+    Gadget gadget = mockGadget(true, true);
+    String host = "bar.com";
+    String path = "/other/path";
+    ConcatUriManager.Type type = ConcatUriManager.Type.JS;
+
+    String[] versions = new String[] { "v1" };
+    ConcatUriManager.Versioner versioner = makeVersioner(null, versions);
+    DefaultConcatUriManager manager = makeManager(host, path, "token", 
versioner);
+
+    Uri urlA = Uri.parse(generateUrl(manager.getUrlMaxLength() / 4));
+    Uri urlB = Uri.parse(generateUrl(manager.getUrlMaxLength() / 4));
+    Uri urlC = Uri.parse(generateUrl(manager.getUrlMaxLength() / 2));
+
+    List<Uri> urlList = ImmutableList.of(urlA, urlB, urlC);
+    List<List<Uri>> resourceUris = ImmutableList.of(urlList);
+    List<ConcatData> concatUris =
+        manager.make(fromList(gadget, resourceUris, type), false);
+
+    assertEquals(2, concatUris.get(0).getUris().size());
+
+    String jsonFirst = concatUris.get(0).getUris().get(0).getQueryParameter(
+        (Param.JSON.toString().toLowerCase()));
+    checkBasicUriParameters(concatUris.get(0).getUris().get(0), host, path, 9, 
type,
+        "1", "1", versions[0]);
+    assertEquals(urlA.toString(), 
concatUris.get(0).getUris().get(0).getQueryParameter("1"));
+    assertEquals(DefaultConcatUriManager.getJsSnippet(jsonFirst, urlA),
+        concatUris.get(0).getSnippet(urlA));
+    assertEquals(urlB.toString(), 
concatUris.get(0).getUris().get(0).getQueryParameter("2"));
+    assertEquals(DefaultConcatUriManager.getJsSnippet(jsonFirst, urlB),
+        concatUris.get(0).getSnippet(urlB));
+    assertNull(concatUris.get(0).getUris().get(0).getQueryParameter("3"));
+
+    String jsonSecond = concatUris.get(0).getUris().get(1).getQueryParameter(
+            (Param.JSON.toString().toLowerCase()));
+    checkBasicUriParameters(concatUris.get(0).getUris().get(1), host, path, 8, 
type,
+        "1", "1", versions[0]);
+    assertEquals(urlC.toString(), 
concatUris.get(0).getUris().get(1).getQueryParameter("1"));
+    assertEquals(DefaultConcatUriManager.getJsSnippet(jsonSecond, urlC),
+        concatUris.get(0).getSnippet(urlC));
+    assertNull(concatUris.get(0).getUris().get(1).getQueryParameter("2"));
+
+  }
+
+  @Test
+  public void dontConcatMultipleResourceBeyoundUrlLimitAdjacentBatched() 
throws Exception {
+    Gadget gadget = mockGadget(true, true);
+    String host = "bar.com";
+    String path = "/other/path";
+    ConcatUriManager.Type type = ConcatUriManager.Type.JS;
+
+    String[] versions = new String[] { "v1" };
+    ConcatUriManager.Versioner versioner = makeVersioner(null, versions);
+    DefaultConcatUriManager manager = makeManager(host, path, null, versioner);
+
+    Uri urlA = Uri.parse(generateUrl(manager.getUrlMaxLength() / 4));
+    Uri urlB = Uri.parse(generateUrl(manager.getUrlMaxLength() / 4));
+    Uri urlC = Uri.parse(generateUrl(manager.getUrlMaxLength() / 2));
+
+    List<Uri> urlList = ImmutableList.of(urlA, urlB, urlC);
+    List<List<Uri>> resourceUris = ImmutableList.of(urlList);
+    List<ConcatData> concatUris =
+        manager.make(fromList(gadget, resourceUris, type), true);
+
+    assertEquals(2, concatUris.get(0).getUris().size());
+
+    checkBasicUriParameters(concatUris.get(0).getUris().get(0), host, path, 8, 
type,
+        "1", "1", versions[0]);
+    assertEquals(urlA.toString(), 
concatUris.get(0).getUris().get(0).getQueryParameter("1"));
+    assertNull(concatUris.get(0).getSnippet(urlA));
+    assertEquals(urlB.toString(), 
concatUris.get(0).getUris().get(0).getQueryParameter("2"));
+    assertNull(concatUris.get(0).getSnippet(urlB));
+    assertNull(concatUris.get(0).getUris().get(0).getQueryParameter("3"));
+
+    checkBasicUriParameters(concatUris.get(0).getUris().get(1), host, path, 7, 
type,
+        "1", "1", versions[0]);
+    assertEquals(urlC.toString(), 
concatUris.get(0).getUris().get(1).getQueryParameter("1"));
+    assertNull(concatUris.get(0).getSnippet(urlC));
+    assertNull(concatUris.get(0).getUris().get(1).getQueryParameter("2"));
+  }
+
+  /**
+   * Contains Uri Basic Assert Checks
+   */
+  private void checkBasicUriParameters(Uri uri,
+                                       String host,
+                                       String path,
+                                       int queryParameterSize,
+                                       ConcatUriManager.Type type,
+                                       String debug,
+                                       String noCache) {
+    assertNull(uri.getScheme());
+    assertEquals(host, uri.getAuthority());
+    assertEquals(path, uri.getPath());
+    assertEquals(queryParameterSize, uri.getQueryParameters().size());
+    assertEquals(CONTAINER, uri.getQueryParameter(Param.CONTAINER.getKey()));
+    assertEquals(SPEC_URI.toString(), 
uri.getQueryParameter(Param.GADGET.getKey()));
+    assertEquals(type.getType(), uri.getQueryParameter(Param.TYPE.getKey()));
+    assertEquals(debug, uri.getQueryParameter(Param.DEBUG.getKey()));
+    assertEquals(noCache, uri.getQueryParameter(Param.NO_CACHE.getKey()));
+  }
+
+  /**
+   * Contains Uri Basic Assert Checks
+   */
+  private void checkBasicUriParameters(Uri uri,
+                                       String host,
+                                       String path,
+                                       int queryParameterSize,
+                                       ConcatUriManager.Type type,
+                                       String debug,
+                                       String noCache,
+                                       String version) {
+    checkBasicUriParameters(uri, host, path, queryParameterSize, type, debug, 
noCache);
+    assertEquals(version, uri.getQueryParameter(Param.VERSION.getKey()));
+  }
+
   private void checkUnversionedUri(ConcatUriManager.Type type, boolean 
hasSplit) {
     // Returns VALID_VERSIONED, but no version is present.
     ConcatUriManager.Versioner versioner = 
makeVersioner(UriStatus.VALID_VERSIONED);
@@ -369,18 +475,11 @@ public class DefaultConcatUriManagerTest
     assertNull(uri.getSnippet(RESOURCE_1));
     assertNull(uri.getSnippet(RESOURCE_2));
     assertNull(uri.getSnippet(RESOURCE_3_NOSCHEMA));
-    assertNull(uri.getUri().getScheme());
-    assertEquals(host, uri.getUri().getAuthority());
-    assertEquals(path, uri.getUri().getPath());
-    assertEquals(8, uri.getUri().getQueryParameters().size());
-    assertEquals(CONTAINER, 
uri.getUri().getQueryParameter(Param.CONTAINER.getKey()));
-    assertEquals(SPEC_URI.toString(), 
uri.getUri().getQueryParameter(Param.GADGET.getKey()));
-    assertEquals("0", uri.getUri().getQueryParameter(Param.DEBUG.getKey()));
-    assertEquals("0", uri.getUri().getQueryParameter(Param.NO_CACHE.getKey()));
-    assertEquals(type.getType(), 
uri.getUri().getQueryParameter(Param.TYPE.getKey()));
-    assertEquals(RESOURCES_ONE.get(0).toString(), 
uri.getUri().getQueryParameter("1"));
-    assertEquals(RESOURCES_ONE.get(1).toString(), 
uri.getUri().getQueryParameter("2"));
-    assertEquals(RESOURCES_ONE.get(2).toString(), 
uri.getUri().getQueryParameter("3"));
+    assertEquals(1, uri.getUris().size());
+    checkBasicUriParameters(uri.getUris().get(0), host, path, 8, type, "0", 
"0");
+    assertEquals(RESOURCES_ONE.get(0).toString(), 
uri.getUris().get(0).getQueryParameter("1"));
+    assertEquals(RESOURCES_ONE.get(1).toString(), 
uri.getUris().get(0).getQueryParameter("2"));
+    assertEquals(RESOURCES_ONE.get(2).toString(), 
uri.getUris().get(0).getQueryParameter("3"));
   }
 
   private void checkAltParams(ConcatUriManager.Type type) throws Exception {
@@ -400,27 +499,18 @@ public class DefaultConcatUriManagerTest
     assertNull(uri.getSnippet(RESOURCE_1));
     assertNull(uri.getSnippet(RESOURCE_2));
     assertNull(uri.getSnippet(RESOURCE_3_NOSCHEMA));
-    assertNull(uri.getUri().getScheme());
-    assertEquals(host, uri.getUri().getAuthority());
-    assertEquals(path, uri.getUri().getPath());
-    assertEquals(9, uri.getUri().getQueryParameters().size());
-    assertEquals(CONTAINER, 
uri.getUri().getQueryParameter(Param.CONTAINER.getKey()));
-    assertEquals(SPEC_URI.toString(), 
uri.getUri().getQueryParameter(Param.GADGET.getKey()));
-    assertEquals("1", uri.getUri().getQueryParameter(Param.DEBUG.getKey()));
-    assertEquals("1", uri.getUri().getQueryParameter(Param.NO_CACHE.getKey()));
-    assertEquals(type.getType(),
-        uri.getUri().getQueryParameter(Param.TYPE.getKey()));
-    assertEquals(RESOURCES_ONE.get(0).toString(), 
uri.getUri().getQueryParameter("1"));
-    assertEquals(RESOURCES_ONE.get(1).toString(), 
uri.getUri().getQueryParameter("2"));
-    assertEquals(RESOURCES_ONE.get(2).toString(), 
uri.getUri().getQueryParameter("3"));
-    assertEquals(version, 
uri.getUri().getQueryParameter(Param.VERSION.getKey()));
+    assertEquals(1, uri.getUris().size());
+    checkBasicUriParameters(uri.getUris().get(0), host, path, 9, type, "1", 
"1", version);
+    assertEquals(RESOURCES_ONE.get(0).toString(), 
uri.getUris().get(0).getQueryParameter("1"));
+    assertEquals(RESOURCES_ONE.get(1).toString(), 
uri.getUris().get(0).getQueryParameter("2"));
+    assertEquals(RESOURCES_ONE.get(2).toString(), 
uri.getUris().get(0).getQueryParameter("3"));
   }
 
   private void checkBatchAdjacent(ConcatUriManager.Type type) throws Exception 
{
     Gadget gadget = mockGadget(true, true);
     String host = "bar.com";
     String path = "/other/path";
-    String[] versions = new String[] { "version1", "v2", "v3" };
+    String[] versions = new String[] { "version1"};
     ConcatUriManager.Versioner versioner = makeVersioner(null, versions);
     DefaultConcatUriManager manager = makeManager(host, path, "token", 
versioner);
     List<List<Uri>> resourceUris =
@@ -435,20 +525,12 @@ public class DefaultConcatUriManagerTest
       assertNull(uri.getSnippet(RESOURCE_1));
       assertNull(uri.getSnippet(RESOURCE_2));
       assertNull(uri.getSnippet(RESOURCE_3_NOSCHEMA));
-      assertNull(uri.getUri().getScheme());
-      assertEquals(host, uri.getUri().getAuthority());
-      assertEquals(path, uri.getUri().getPath());
-      assertEquals(9, uri.getUri().getQueryParameters().size());
-      assertEquals(CONTAINER, 
uri.getUri().getQueryParameter(Param.CONTAINER.getKey()));
-      assertEquals(SPEC_URI.toString(), 
uri.getUri().getQueryParameter(Param.GADGET.getKey()));
-      assertEquals("1", uri.getUri().getQueryParameter(Param.DEBUG.getKey()));
-      assertEquals("1", 
uri.getUri().getQueryParameter(Param.NO_CACHE.getKey()));
-      assertEquals(type.getType(), 
uri.getUri().getQueryParameter(Param.TYPE.getKey()));
+      assertEquals(1, uri.getUris().size());
+      checkBasicUriParameters(uri.getUris().get(0), host, path, 9, type, "1", 
"1", versions[0]);
       List<Uri> resList = (i % 2 == 0) ? RESOURCES_ONE : RESOURCES_TWO;
-      assertEquals(resList.get(0).toString(), 
uri.getUri().getQueryParameter("1"));
-      assertEquals(resList.get(1).toString(), 
uri.getUri().getQueryParameter("2"));
-      assertEquals(resList.get(2).toString(), 
uri.getUri().getQueryParameter("3"));
-      assertEquals(versions[i], 
uri.getUri().getQueryParameter(Param.VERSION.getKey()));
+      assertEquals(resList.get(0).toString(), 
uri.getUris().get(0).getQueryParameter("1"));
+      assertEquals(resList.get(1).toString(), 
uri.getUris().get(0).getQueryParameter("2"));
+      assertEquals(resList.get(2).toString(), 
uri.getUris().get(0).getQueryParameter("3"));
     }
   }
 
@@ -458,7 +540,7 @@ public class DefaultConcatUriManagerTest
     Gadget gadget = mockGadget(true, true);
     String host = "bar.com";
     String path = "/other/path";
-    String[] versions = new String[] { "version1", "v2", "v3" };
+    String[] versions = new String[] { "version1"};
     ConcatUriManager.Versioner versioner = 
makeVersioner(UriStatus.VALID_VERSIONED, versions);
     DefaultConcatUriManager manager = makeManager(host, path, "token", 
versioner);
     List<List<Uri>> resourceUris =
@@ -470,7 +552,7 @@ public class DefaultConcatUriManagerTest
 
     for (int i = 0; i < 3; ++i) {
       ConcatUriManager.ConcatUri validated =
-          manager.process(concatUris.get(i).getUri());
+          manager.process(concatUris.get(i).getUris().get(0));
       assertEquals(UriStatus.VALID_VERSIONED, validated.getStatus());
       List<Uri> resList = (i % 2 == 0) ? RESOURCES_ONE : RESOURCES_TWO;
       assertEquals(resList, validated.getBatch());
@@ -478,17 +560,10 @@ public class DefaultConcatUriManagerTest
     }
   }
 
-  private void checkBatchInsufficientVersions(ConcatUriManager.Type type) 
throws Exception {
-    Gadget gadget = mockGadget(true, true);
-    String host = "bar.com";
-    String path = "/other/path";
-    String[] versions = new String[] { "v1" };  // Only one for three 
resources.
-    ConcatUriManager.Versioner versioner = makeVersioner(null, versions);
-    DefaultConcatUriManager manager = makeManager(host, path, "token", 
versioner);
-    List<List<Uri>> resourceUris = ImmutableList.of(RESOURCES_ONE, 
RESOURCES_ONE);
-    manager.make(fromList(gadget, resourceUris, type), true);
+  private String generateUrl(int length) {
+    return "http://www.url.com/"; + RandomStringUtils.randomAlphanumeric(length 
- 22) + ".js";
   }
-
+  
   private void checkMissingHostConfig(ConcatUriManager.Type type) throws 
Exception {
     Gadget gadget = mockGadget(false, false);
     DefaultConcatUriManager manager = makeManager(null, "/foo", "token", null);


Reply via email to