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>
+