You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2014/07/01 00:48:30 UTC

git commit: TAP5-2083: Failing to load asset / stylesheet with @Import annotation in subclassed component

Repository: tapestry-5
Updated Branches:
  refs/heads/master 3b8fe942b -> 64ef39cf2


TAP5-2083: Failing to load asset / stylesheet with @Import annotation in subclassed component

Fixes use of @Import and @Inject @Path in a base class vs. a subclass (as long as the assets are
stored in META-INF/assets).


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/64ef39cf
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/64ef39cf
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/64ef39cf

Branch: refs/heads/master
Commit: 64ef39cf2a2eacf94f70487a704254cc34733116
Parents: 3b8fe94
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Jun 30 15:48:16 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Jun 30 15:48:27 2014 -0700

----------------------------------------------------------------------
 54_RELEASE_NOTES.md                                |   6 ++++++
 .../internal/bindings/AssetBindingFactory.java     |   4 +---
 .../internal/services/AssetInjectionProvider.java  |   8 +++++---
 .../internal/services/AssetSourceImpl.java         |   6 ++----
 .../tapestry5/internal/transform/ImportWorker.java |  14 +++++++-------
 .../org/apache/tapestry5/services/AssetSource.java |  14 +++++++++++---
 .../integration/app1/AtImportTests.groovy          |   9 ++++++++-
 .../integration/app1/pages/LogoSubclass.java       |   7 +++++++
 .../integration/locallib/alpha/pages/Logo.groovy   |  13 +++++++++++++
 .../tapestry5/integration/app1/pages/Index.java    |   1 +
 .../META-INF/assets/lib/alpha/feature.jpg          | Bin 0 -> 25956 bytes
 .../META-INF/assets/lib/alpha/show-logo.js         |   1 +
 .../integration/locallib/alpha/pages/Logo.tml      |  12 ++++++++++++
 13 files changed, 74 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/54_RELEASE_NOTES.md
----------------------------------------------------------------------
diff --git a/54_RELEASE_NOTES.md b/54_RELEASE_NOTES.md
index eda173b..4c80c5d 100644
--- a/54_RELEASE_NOTES.md
+++ b/54_RELEASE_NOTES.md
@@ -71,6 +71,12 @@ Tapestry 5.4 introduces a new module, tapestry-webresources, which provides supp
 CoffeeScript into JavaScript, Less into CSS, and for minimizing CSS and JavaScript.
 All processing takes place at runtime.
 
+Tapestry now properly handles the case for a base class referencing assets that is subclassed into a
+different library (or subclasses from a library to the application). As long as the new location, under
+`META-INF/assets`, is used, then Tapestry will locate the base class asset inside the subfolder
+corresponding the the base class' library. In prior releases, the resolution was against the
+subclass' library, which would fail.
+
 ## FormGroup Mixin
 
 This new mixin for Field components adds the outer `<div class="form-group">` and `<label>` elements for a Field

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBindingFactory.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBindingFactory.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBindingFactory.java
index df5207f..c0f532e 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBindingFactory.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBindingFactory.java
@@ -1,5 +1,3 @@
-// Copyright 2007, 2008, 2009 The Apache Software Foundation
-//
 // 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
@@ -43,7 +41,7 @@ public class AssetBindingFactory implements BindingFactory
         // sub-class gets instantiated, because relative path for the asset should be relative to the
         // base class, but will instead by relative to the subclass.
 
-        Asset asset = source.getComponentAsset(container, expression);
+        Asset asset = source.getComponentAsset(container, expression, container.getComponentModel().getLibraryName());
 
         return new AssetBinding(location, description, asset);
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetInjectionProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetInjectionProvider.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetInjectionProvider.java
index 2dd0742..d429da0 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetInjectionProvider.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetInjectionProvider.java
@@ -1,5 +1,3 @@
-// Copyright 2007, 2008, 2010, 2011 The Apache Software Foundation
-//
 // 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
@@ -49,6 +47,7 @@ public class AssetInjectionProvider implements InjectionProvider2
         }
 
         final String assetPath = path.value();
+        final String libraryName = componentModel.getLibraryName();
 
         ComputedValue<Asset> computedAsset = new ComputedValue<Asset>()
         {
@@ -56,7 +55,10 @@ public class AssetInjectionProvider implements InjectionProvider2
             {
                 ComponentResources resources = context.get(ComponentResources.class);
 
-                return assetSource.getComponentAsset(resources, assetPath);
+                // Note how this works: the resources represents the actual instantiated class, and the libraryName
+                // comes from the componentModel, potentially, the componentModel of a base class (which may have
+                // a different library name than the subclass).
+                return assetSource.getComponentAsset(resources, assetPath, libraryName);
             }
         };
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
index 140b32b..42e339b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
@@ -1,5 +1,3 @@
-// Copyright 2006-2014 The Apache Software Foundation
-//
 // 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
@@ -143,7 +141,7 @@ public class AssetSourceImpl extends LockSupport implements AssetSource
         return getUnlocalizedAsset(symbolSource.expandSymbols(path));
     }
 
-    public Asset getComponentAsset(final ComponentResources resources, final String path)
+    public Asset getComponentAsset(final ComponentResources resources, final String path, final String libraryName)
     {
         assert resources != null;
 
@@ -207,7 +205,7 @@ public class AssetSourceImpl extends LockSupport implements AssetSource
                         // represented in the URL.
 
                         // Ends with trailing slash:
-                        String metaRoot = "META-INF/assets/" + toPathPrefix(resources.getComponentModel().getLibraryName());
+                        String metaRoot = "META-INF/assets/" + toPathPrefix(libraryName);
 
                         String trimmedRestOfPath = restOfPath.startsWith("/") ? restOfPath.substring(1) : restOfPath;
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ImportWorker.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ImportWorker.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ImportWorker.java
index debd1e4..17bddc4 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ImportWorker.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ImportWorker.java
@@ -1,5 +1,3 @@
-// Copyright 2010-2012 The Apache Software Foundation
-//
 // 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
@@ -114,6 +112,8 @@ public class ImportWorker implements ComponentClassTransformWorker2
     {
         importStacks(method, annotation.stack());
 
+        String libraryName = model.getLibraryName();
+
         importLibraries(componentClass, model, method, annotation.library());
 
         importStylesheets(componentClass, model, method, annotation.stylesheet());
@@ -227,7 +227,7 @@ public class ImportWorker implements ComponentClassTransformWorker2
         PlasticField assetListField = componentClass.introduceField(Asset[].class,
                 "importedAssets_" + method.getDescription().methodName);
 
-        initializeAssetsFromPaths(expandedPaths, assetListField);
+        initializeAssetsFromPaths(expandedPaths, assetListField, model.getLibraryName());
 
         addMethodAssetOperationAdvice(method, assetListField.getHandle(), operation);
     }
@@ -237,7 +237,7 @@ public class ImportWorker implements ComponentClassTransformWorker2
         return F.flow(paths).map(expandSymbols).toArray(String.class);
     }
 
-    private void initializeAssetsFromPaths(final String[] expandedPaths, PlasticField assetsField)
+    private void initializeAssetsFromPaths(final String[] expandedPaths, PlasticField assetsField, final String libraryName)
     {
         assetsField.injectComputed(new ComputedValue<Asset[]>()
         {
@@ -245,18 +245,18 @@ public class ImportWorker implements ComponentClassTransformWorker2
             {
                 ComponentResources resources = context.get(ComponentResources.class);
 
-                return convertPathsToAssetArray(resources, expandedPaths);
+                return convertPathsToAssetArray(resources, expandedPaths, libraryName);
             }
         });
     }
 
-    private Asset[] convertPathsToAssetArray(final ComponentResources resources, String[] assetPaths)
+    private Asset[] convertPathsToAssetArray(final ComponentResources resources, String[] assetPaths, final String libraryName)
     {
         return F.flow(assetPaths).map(new Mapper<String, Asset>()
         {
             public Asset map(String assetPath)
             {
-                return assetSource.getComponentAsset(resources, assetPath);
+                return assetSource.getComponentAsset(resources, assetPath, libraryName);
             }
         }).toArray(Asset.class);
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetSource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetSource.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetSource.java
index d28711e..111b2f9 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetSource.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetSource.java
@@ -1,5 +1,3 @@
-// Copyright 2006-2013 The Apache Software Foundation
-//
 // 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
@@ -131,6 +129,12 @@ public interface AssetSource
      * This is the preferred location in 5.4, with compatibility for 5.3 that allows assets to be stored on the classpath
      * alongside Java classes and server-only resources such as templates and message catalogs.
      *
+     * <p/>
+     * When resolving a resource in a component that is subclass, the point of injection is the class which contains
+     * the injecting annotation (e.g., {@link org.apache.tapestry5.ioc.annotations.Inject} with {@link org.apache.tapestry5.annotations.Path},
+     * or {@link org.apache.tapestry5.annotations.Import}). In other words, the library name for the library containing the class,
+     * rather than the library name of the instantiated subclass (which can be different).
+     *
      * @param resources
      *         resources, used to identify starting location of asset (if path does not include a asset prefix).
      * @param path
@@ -138,10 +142,14 @@ public interface AssetSource
      *         component's library asset folder (the 5.4 and beyond way), or the to the component's Java class file (the 5.3 and earlier
      *         way, still supported until at least 5.5).
      *         Symbols in the path are {@linkplain org.apache.tapestry5.ioc.services.SymbolSource#expandSymbols(String) expanded}.
+     * @param libraryName
+     *          The name of the library containing the component, as per {@link org.apache.tapestry5.model.ComponentModel#getLibraryName()}.
+     *          For a subclass, the libraryName must reflect the name of the library for the parent class that forms the basis of
+     *          injection.
      * @return the Asset
      * @throws RuntimeException
      *         if Asset can not be found
      * @since 5.4
      */
-    Asset getComponentAsset(ComponentResources resources, String path);
+    Asset getComponentAsset(ComponentResources resources, String path, final String libraryName);
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AtImportTests.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AtImportTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AtImportTests.groovy
index 8199f8e..8810110 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AtImportTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/AtImportTests.groovy
@@ -17,7 +17,7 @@ class AtImportTests extends GroovyTapestryCoreTestCase
         
         final String locatorTemplate = "//link[contains(@href, 'via-import.css')]/preceding-sibling::link[contains(@href, '%s.css')]"
         
-        open("/AtImportWithoutStackButWithStylesheet")
+        open "/AtImportWithoutStackButWithStylesheet"
         
         assert isElementPresent(String.format(locatorTemplate, "bootstrap"))
         assert isElementPresent(String.format(locatorTemplate, "tapestry"))
@@ -27,4 +27,11 @@ class AtImportTests extends GroovyTapestryCoreTestCase
         
     }
 
+    @Test
+    void import_and_asset_injection_in_base_class_finds_resources_there() {
+        openLinks "Base class Assets in sub-classes"
+
+        assertText "//h1", "Alpha Library: Logo Demo"
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/pages/LogoSubclass.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/pages/LogoSubclass.java b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/pages/LogoSubclass.java
new file mode 100644
index 0000000..96e3345
--- /dev/null
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/pages/LogoSubclass.java
@@ -0,0 +1,7 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.integration.locallib.alpha.pages.Logo;
+
+public class LogoSubclass extends Logo
+{
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.groovy
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.groovy
new file mode 100644
index 0000000..9f4e9ba
--- /dev/null
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.groovy
@@ -0,0 +1,13 @@
+package org.apache.tapestry5.integration.locallib.alpha.pages
+
+import org.apache.tapestry5.Asset
+import org.apache.tapestry5.annotations.Import
+import org.apache.tapestry5.annotations.Path
+import org.apache.tapestry5.ioc.annotations.Inject
+
+@Import(library="show-logo.js")
+class Logo {
+
+    @Inject @Path("feature.jpg")
+    Asset featureImage;
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
index 2d9876c..42a4ffa 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
@@ -56,6 +56,7 @@ public class Index
 
     private static final List<Item> ITEMS = CollectionFactory
             .newList(
+                    new Item("LogoSubclass", "Base class Assets in sub-classes", "Assets are resolved for the parent class if that's where the annotations are."),
 
                     new Item("MissingRequiredARP", "Missing Query Parameter for @ActivationRequestParameter", "Activating a page with a required @ActivationRequestParameter, but no matching query parameter, is an error."),
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/feature.jpg
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/feature.jpg b/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/feature.jpg
new file mode 100644
index 0000000..6775c47
Binary files /dev/null and b/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/feature.jpg differ

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/show-logo.js
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/show-logo.js b/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/show-logo.js
new file mode 100644
index 0000000..b174e0f
--- /dev/null
+++ b/tapestry-core/src/test/resources/META-INF/assets/lib/alpha/show-logo.js
@@ -0,0 +1 @@
+document.getElementById("t5logo").setAttribute("style", null);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/64ef39cf/tapestry-core/src/test/resources/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.tml
new file mode 100644
index 0000000..93ca922
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/locallib/alpha/pages/Logo.tml
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+
+    <h1>Alpha Library: Logo Demo</h1>
+
+    <img id="t5logo" style="display:none;" src="${asset:tapestry.png}"/>
+
+    <br/>
+
+    <img src="${featureImage}"/>
+
+</html>
+