Author: hlship Date: Sat Sep 25 00:26:03 2010 New Revision: 1001112 URL: http://svn.apache.org/viewvc?rev=1001112&view=rev Log: TAP5-1279: Importing a JavaScript library that is part of a stack should import the entire stack instead of the individual library (to take advantage of JavaScript aggregation)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackSourceImpl.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptStackSource.java tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java?rev=1001112&r1=1001111&r2=1001112&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java Sat Sep 25 00:26:03 2010 @@ -28,7 +28,6 @@ import org.apache.tapestry5.internal.ser import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; import org.apache.tapestry5.ioc.internal.util.InternalUtils; -import org.apache.tapestry5.ioc.services.Coercion; import org.apache.tapestry5.ioc.util.IdAllocator; import org.apache.tapestry5.json.JSONArray; import org.apache.tapestry5.json.JSONObject; @@ -66,14 +65,6 @@ public class JavaScriptSupportImpl imple private String focusFieldId; - private static final Coercion<Asset, String> toPath = new Coercion<Asset, String>() - { - public String coerce(Asset input) - { - return input.toClientURL(); - } - }; - public JavaScriptSupportImpl(DocumentLinker linker, JavaScriptStackSource javascriptStackSource, JavaScriptStackPathConstructor stackPathConstructor) { @@ -203,6 +194,7 @@ public class JavaScriptSupportImpl imple public void importJavaScriptLibrary(Asset asset) { assert asset != null; + importJavaScriptLibrary(asset.toClientURL()); } @@ -210,12 +202,49 @@ public class JavaScriptSupportImpl imple { addCoreStackIfNeeded(); + String stackName = findStackForLibrary(libraryURL); + + if (stackName != null) + { + importStack(stackName); + return; + } + if (otherLibraries.contains(libraryURL)) return; otherLibraries.add(libraryURL); } + private Map<String, String> libraryURLToStackName; + + /** + * Locates the name of the stack that includes the library URL. Returns the stack, + * or null if the library is free-standing. + */ + private String findStackForLibrary(String libraryURL) + { + return getLibraryURLToStackName().get(libraryURL); + } + + private Map<String, String> getLibraryURLToStackName() + { + if (libraryURLToStackName == null) + { + libraryURLToStackName = CollectionFactory.newMap(); + + for (String stackName : javascriptStackSource.getStackNames()) + { + for (Asset library : javascriptStackSource.getStack(stackName).getJavaScriptLibraries()) + { + libraryURLToStackName.put(library.toClientURL(), stackName); + } + } + } + + return libraryURLToStackName; + } + private void addCoreStackIfNeeded() { addAssetsFromStack(InternalConstants.CORE_STACK_NAME); Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackSourceImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackSourceImpl.java?rev=1001112&r1=1001111&r2=1001112&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackSourceImpl.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/JavaScriptStackSourceImpl.java Sat Sep 25 00:26:03 2010 @@ -14,8 +14,10 @@ package org.apache.tapestry5.internal.services.javascript; +import java.util.List; import java.util.Map; +import org.apache.tapestry5.func.F; import org.apache.tapestry5.ioc.util.AvailableValues; import org.apache.tapestry5.ioc.util.UnknownValueException; import org.apache.tapestry5.services.javascript.JavaScriptStack; @@ -41,4 +43,8 @@ public class JavaScriptStackSourceImpl i return stack; } + public List<String> getStackNames() + { + return F.flow(configuration.keySet()).sort().toList(); + } } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptStackSource.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptStackSource.java?rev=1001112&r1=1001111&r2=1001112&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptStackSource.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptStackSource.java Sat Sep 25 00:26:03 2010 @@ -14,6 +14,8 @@ package org.apache.tapestry5.services.javascript; +import java.util.List; + import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration; import org.apache.tapestry5.ioc.util.UnknownValueException; @@ -33,4 +35,11 @@ public interface JavaScriptStackSource * if no such stack */ JavaScriptStack getStack(String name); + + /** + * Returns the names of all stacks, in sorted order. + * + * @since 5.2.1 + */ + List<String> getStackNames(); } Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java?rev=1001112&r1=1001111&r2=1001112&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java Sat Sep 25 00:26:03 2010 @@ -20,10 +20,8 @@ import java.util.List; import org.apache.tapestry5.Asset; import org.apache.tapestry5.ComponentResources; -import org.apache.tapestry5.FieldFocusPriority; import org.apache.tapestry5.internal.InternalConstants; import org.apache.tapestry5.internal.services.DocumentLinker; -import org.apache.tapestry5.internal.services.RenderSupportImpl; import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor; import org.apache.tapestry5.internal.test.InternalBaseTestCase; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; @@ -111,18 +109,14 @@ public class JavaScriptSupportImplTest e { JavaScriptStack stack = mockJavaScriptStack(); - List<String> libraryPaths = Collections.emptyList(); - List<StylesheetLink> stylesheets = Collections.emptyList(); - List<String> stacks = libraryPaths; - expect(stackSource.getStack(InternalConstants.CORE_STACK_NAME)).andReturn(stack); expect(pathConstructor.constructPathsForJavaScriptStack(InternalConstants.CORE_STACK_NAME)).andReturn( - libraryPaths); - expect(stack.getStylesheets()).andReturn(stylesheets); + Collections.<String> emptyList()); + expect(stack.getStylesheets()).andReturn(Collections.<StylesheetLink> emptyList()); expect(stack.getInitialization()).andReturn(null); - expect(stack.getStacks()).andReturn(stacks); + expect(stack.getStacks()).andReturn(Collections.<String> emptyList()); } private void trainForCoreStack(DocumentLinker linker, JavaScriptStackSource stackSource, @@ -139,8 +133,7 @@ public class JavaScriptSupportImplTest e expect(stack.getInitialization()).andReturn("stackInit();"); - List<String> stacks = Collections.emptyList(); - expect(stack.getStacks()).andReturn(stacks); + expect(stack.getStacks()).andReturn(Collections.<String> emptyList()); linker.addScriptLink("stack1.js"); linker.addScriptLink("stack2.js"); @@ -189,6 +182,8 @@ public class JavaScriptSupportImplTest e JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor(); trainForEmptyCoreStack(linker, stackSource, pathConstructor); + trainForNoStackNames(stackSource); + Asset library = mockAsset("mylib.js"); linker.addScriptLink("mylib.js"); @@ -205,6 +200,51 @@ public class JavaScriptSupportImplTest e } @Test + public void import_library_from_stack_imports_the_stack() + { + DocumentLinker linker = mockDocumentLinker(); + JavaScriptStackSource stackSource = mockJavaScriptStackSource(); + JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor(); + trainForEmptyCoreStack(linker, stackSource, pathConstructor); + + Asset library1 = mockAsset("mylib1.js"); + Asset library2 = mockAsset("mylib2.js"); + + JavaScriptStack mystack = mockJavaScriptStack(); + + expect(stackSource.getStackNames()).andReturn(Arrays.asList("mystack")); + expect(stackSource.getStack("mystack")).andReturn(mystack).atLeastOnce(); + + expect(mystack.getStacks()).andReturn(Collections.<String> emptyList()); + expect(mystack.getJavaScriptLibraries()).andReturn(Arrays.asList(library1, library2)); + + expect(pathConstructor.constructPathsForJavaScriptStack("mystack")).andReturn( + Arrays.asList("stacks/mystack.js")); + expect(mystack.getStylesheets()).andReturn(Collections.<StylesheetLink> emptyList()); + + expect(mystack.getInitialization()).andReturn(null); + + linker.addScriptLink("stacks/mystack.js"); + + replay(); + + JavaScriptSupportImpl jss = new JavaScriptSupportImpl(linker, stackSource, pathConstructor); + + jss.importJavaScriptLibrary(library1); + + jss.commit(); + + verify(); + } + + private void trainForNoStackNames(JavaScriptStackSource stackSource) + { + // This is slightly odd, as it would normally return "core" at a minimum, but we test for that separately. + + expect(stackSource.getStackNames()).andReturn(Collections.<String> emptyList()); + } + + @Test public void import_stack() { DocumentLinker linker = mockDocumentLinker(); @@ -310,6 +350,8 @@ public class JavaScriptSupportImplTest e JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor(); trainForEmptyCoreStack(linker, stackSource, pathConstructor); + trainForNoStackNames(stackSource); + Asset library1 = mockAsset("mylib1.js"); Asset library2 = mockAsset("mylib2.js");