You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2024/12/08 22:05:01 UTC

(tapestry-5) branch javax-import-class-hierarchy created (now 0913b067c)

This is an automated email from the ASF dual-hosted git repository.

thiagohp pushed a change to branch javax-import-class-hierarchy
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git


      at 0913b067c TAP5-2800: @Import doesn't import stylesheets when it imports libraries

This branch includes the following new commits:

     new 983dddc38 Tests for @Import(stylesheet) in class hierarchies
     new 0913b067c TAP5-2800: @Import doesn't import stylesheets when it imports libraries

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(tapestry-5) 02/02: TAP5-2800: @Import doesn't import stylesheets when it imports libraries

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thiagohp pushed a commit to branch javax-import-class-hierarchy
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git

commit 0913b067cf2a2764ec15855f775e3919c6a89ef5
Author: Thiago H. de Paula Figueiredo <th...@arsmachina.com.br>
AuthorDate: Sun Dec 8 19:04:52 2024 -0300

    TAP5-2800: @Import doesn't import stylesheets when it imports libraries
    
    Also TAP5-2742
---
 .../tapestry5/internal/transform/ImportWorker.java | 28 ++++++++++++----------
 1 file changed, 15 insertions(+), 13 deletions(-)

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 70bbe4464..36130ddaf 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
@@ -58,6 +58,11 @@ public class ImportWorker implements ComponentClassTransformWorker2
     private final boolean multipleClassLoaders;
     
     private final PropertyValueProviderWorker propertyValueProviderWorker;
+    
+    private static enum ImportType 
+    {
+        LIBRARY, STYLESHEET
+    }
 
     private final Worker<Asset> importLibrary = new Worker<Asset>()
     {
@@ -235,18 +240,18 @@ public class ImportWorker implements ComponentClassTransformWorker2
     private void importLibraries(PlasticClass plasticClass, MutableComponentModel model, PlasticMethod method,
                                  String[] paths, Set<FieldInfo> fieldInfos)
     {
-        decorateMethodWithOperation(plasticClass, model, method, paths, importLibrary, fieldInfos);
+        decorateMethodWithOperation(plasticClass, model, method, paths, importLibrary, fieldInfos, ImportType.LIBRARY);
     }
 
     private void importStylesheets(PlasticClass plasticClass, MutableComponentModel model, PlasticMethod method,
                                    String[] paths, Set<FieldInfo> fieldInfos)
     {
-        decorateMethodWithOperation(plasticClass, model, method, paths, importStylesheet, fieldInfos);
+        decorateMethodWithOperation(plasticClass, model, method, paths, importStylesheet, fieldInfos, ImportType.STYLESHEET);
     }
 
     private void decorateMethodWithOperation(PlasticClass componentClass, MutableComponentModel model,
                                              PlasticMethod method, String[] paths, Worker<Asset> operation,
-                                             Set<FieldInfo> fieldInfos)
+                                             Set<FieldInfo> fieldInfos, ImportType importType)
     {
         if (paths.length == 0)
         {
@@ -255,7 +260,7 @@ public class ImportWorker implements ComponentClassTransformWorker2
 
         String[] expandedPaths = expandPaths(paths);
 
-        final String fieldName = getFieldName(method);
+        final String fieldName = getFieldName(method, importType);
         PlasticField assetListField = componentClass.introduceField(Asset[].class, fieldName);
         
         if (multipleClassLoaders)
@@ -266,10 +271,10 @@ public class ImportWorker implements ComponentClassTransformWorker2
 
         initializeAssetsFromPaths(expandedPaths, assetListField, model.getLibraryName());
 
-        addMethodAssetOperationAdvice(method, assetListField.getHandle(), operation);
+        addMethodAssetOperationAdvice(method, assetListField.getHandle(), operation, importType);
     }
 
-    private String getFieldName(PlasticMethod method) 
+    private String getFieldName(PlasticMethod method, ImportType importType) 
     {
         final StringBuilder builder = new StringBuilder(FIELD_PREFIX);
         builder.append(method.getDescription().methodName);
@@ -277,6 +282,8 @@ public class ImportWorker implements ComponentClassTransformWorker2
         {
             builder.append("_");
             builder.append(method.getPlasticClass().getClassName().replace('.', '_'));
+            builder.append("_");
+            builder.append(importType.name().toLowerCase());
         }
         return builder.toString();
     }
@@ -311,10 +318,10 @@ public class ImportWorker implements ComponentClassTransformWorker2
     }
 
     private void addMethodAssetOperationAdvice(PlasticMethod method, final FieldHandle access,
-                                               final Worker<Asset> operation)
+                                               final Worker<Asset> operation, ImportType importType)
     {
         final String className = method.getPlasticClass().getClassName();
-        final String fieldName = getFieldName(method);
+        final String fieldName = getFieldName(method, importType);
         method.addAdvice(new MethodAdvice()
         {
             public void advise(MethodInvocation invocation)
@@ -341,9 +348,4 @@ public class ImportWorker implements ComponentClassTransformWorker2
         });
     }
     
-    public static interface ImportWorkerDataProvider 
-    {
-        Asset[] get(int fieldNameHashcode);
-    }
-    
 }


(tapestry-5) 01/02: Tests for @Import(stylesheet) in class hierarchies

Posted by th...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

thiagohp pushed a commit to branch javax-import-class-hierarchy
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git

commit 983dddc38e83c06189b6e0c7a857cf8a180c4fb6
Author: Thiago H. de Paula Figueiredo <th...@arsmachina.com.br>
AuthorDate: Sun Nov 24 20:53:27 2024 -0300

    Tests for @Import(stylesheet) in class hierarchies
---
 .../services/ComponentDependencyRegistryImpl.java  | 17 +++++++++++-----
 .../internal/services/PageSourceImpl.java          | 20 ++++++++++---------
 tapestry-core/src/test/app1/css/PageWrapper.css    |  5 +++++
 .../src/test/app1/css/TrainingDocPage.css          |  5 +++++
 .../src/test/app1/css/TrainingWrapper.css          |  5 +++++
 tapestry-core/src/test/app1/css/via-import2.css    |  5 +++++
 tapestry-core/src/test/app1/css/via-import3.css    |  5 +++++
 .../src/test/app1/imports/MessageCatalogue.tml     |  5 +++++
 .../app1/base/imports/ComponentBase.java           |  4 ++++
 .../app1/base/imports/ComponentCommonBase.java     |  4 ++++
 .../integration/app1/base/imports/PageWrapper.java |  7 +++++++
 .../app1/base/imports/TrainingDocPage.java         |  8 ++++++++
 .../app1/components/SubclassWithImport.java        |  2 +-
 .../app1/components/SuperSuperclassWithImport.java |  8 ++++++++
 .../app1/components/SuperclassWithImport.java      |  2 +-
 .../app1/components/SuperclassWithoutImport.java   |  5 +++++
 .../app1/pages/imports/MessageCatalogue.java       |  6 ++++++
 .../app1/pages/imports/TrainingWrapper.java        |  8 ++++++++
 .../java/t5/webresources/base/ComponentBase.java   |  4 ++++
 .../t5/webresources/base/ComponentCommonBase.java  | 16 +++++++++++++++
 .../java/t5/webresources/base/PageWrapper.java     |  7 +++++++
 .../java/t5/webresources/base/TrainingDocPage.java |  9 +++++++++
 .../t5/webresources/pages/MessageCatalogue.java    |  6 ++++++
 .../t5/webresources/pages/TrainingWrapper.java     |  9 +++++++++
 .../resources/META-INF/assets/PageWrapper.less     |  5 +++++
 .../resources/META-INF/assets/TrainingDocPage.less |  5 +++++
 .../resources/META-INF/assets/TrainingWrapper.less |  5 +++++
 .../t5/webresources/pages/MessageCatalogue.tml     | 23 ++++++++++++++++++++++
 28 files changed, 194 insertions(+), 16 deletions(-)

diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
index 24c0b2a89..4d83efd35 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
@@ -707,16 +707,23 @@ public class ComponentDependencyRegistryImpl implements ComponentDependencyRegis
             for (String resource : resources) 
             {
                 
-                final Set<String> dependents = getDependents(resource);
-                for (String furtherDependent : dependents) 
+                // Avoid resource invalidations
+                if (!resource.contains(":"))
                 {
-                    if (!resources.contains(furtherDependent) && !furtherDependents.contains(furtherDependent))
+                
+                    final Set<String> dependents = getDependents(resource);
+                    for (String furtherDependent : dependents) 
                     {
-                        furtherDependents.add(furtherDependent);
+                        if (!resources.contains(furtherDependent) && !furtherDependents.contains(furtherDependent))
+                        {
+                            furtherDependents.add(furtherDependent);
+                        }
                     }
+                    
+                    clear(resource);
+                    
                 }
                 
-                clear(resource);
                 
             }
         }
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
index c4633cc29..0fc4c5262 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
@@ -185,15 +185,17 @@ public class PageSourceImpl implements PageSource
             if (multipleClassLoaders)
             {
                 
-                if (canonicalPageName.equals(CURRENT_PAGE.get()))
-                {
-                    throw new IllegalStateException("Infinite method loop detected. Bailing out.");
-                }
-                else
-                {
-                    CURRENT_PAGE.set(canonicalPageName);
-                }
-            
+//                final String currentPage = CURRENT_PAGE.get();
+//                if (canonicalPageName.equals(currentPage))
+//                {
+//                    logger.warn("Infinite method loop detected. Bailing out.");
+//                    return null;
+//                }
+//                else
+//                {
+//                    CURRENT_PAGE.set(canonicalPageName);
+//                }
+//            
                 // Avoiding problems in PlasticClassPool.createTransformation()
                 // when the class being loaded has a page superclass
                 final List<String> pageDependencies = getPageDependencies(className);
diff --git a/tapestry-core/src/test/app1/css/PageWrapper.css b/tapestry-core/src/test/app1/css/PageWrapper.css
new file mode 100644
index 000000000..e78bb6bd2
--- /dev/null
+++ b/tapestry-core/src/test/app1/css/PageWrapper.css
@@ -0,0 +1,5 @@
+DIV.via-import2
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-core/src/test/app1/css/TrainingDocPage.css b/tapestry-core/src/test/app1/css/TrainingDocPage.css
new file mode 100644
index 000000000..e78bb6bd2
--- /dev/null
+++ b/tapestry-core/src/test/app1/css/TrainingDocPage.css
@@ -0,0 +1,5 @@
+DIV.via-import2
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-core/src/test/app1/css/TrainingWrapper.css b/tapestry-core/src/test/app1/css/TrainingWrapper.css
new file mode 100644
index 000000000..e78bb6bd2
--- /dev/null
+++ b/tapestry-core/src/test/app1/css/TrainingWrapper.css
@@ -0,0 +1,5 @@
+DIV.via-import2
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-core/src/test/app1/css/via-import2.css b/tapestry-core/src/test/app1/css/via-import2.css
new file mode 100644
index 000000000..e78bb6bd2
--- /dev/null
+++ b/tapestry-core/src/test/app1/css/via-import2.css
@@ -0,0 +1,5 @@
+DIV.via-import2
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-core/src/test/app1/css/via-import3.css b/tapestry-core/src/test/app1/css/via-import3.css
new file mode 100644
index 000000000..27610d676
--- /dev/null
+++ b/tapestry-core/src/test/app1/css/via-import3.css
@@ -0,0 +1,5 @@
+DIV.via-import3
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-core/src/test/app1/imports/MessageCatalogue.tml b/tapestry-core/src/test/app1/imports/MessageCatalogue.tml
new file mode 100644
index 000000000..2fa120492
--- /dev/null
+++ b/tapestry-core/src/test/app1/imports/MessageCatalogue.tml
@@ -0,0 +1,5 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Message catalogue</h1>
+
+</html>
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/ComponentBase.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/ComponentBase.java
new file mode 100644
index 000000000..90d4678c3
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/ComponentBase.java
@@ -0,0 +1,4 @@
+package org.apache.tapestry5.integration.app1.base.imports;
+
+public abstract class ComponentBase {
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/ComponentCommonBase.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/ComponentCommonBase.java
new file mode 100644
index 000000000..f134213a7
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/ComponentCommonBase.java
@@ -0,0 +1,4 @@
+package org.apache.tapestry5.integration.app1.base.imports;
+
+public abstract class ComponentCommonBase extends ComponentBase {
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/PageWrapper.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/PageWrapper.java
new file mode 100644
index 000000000..1a9fdbf2a
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/PageWrapper.java
@@ -0,0 +1,7 @@
+package org.apache.tapestry5.integration.app1.base.imports;
+
+import org.apache.tapestry5.annotations.Import;
+
+@Import(stylesheet = "context:css/PageWrapper.css")
+public abstract class PageWrapper extends ComponentCommonBase {
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/TrainingDocPage.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/TrainingDocPage.java
new file mode 100644
index 000000000..82aea4fea
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/imports/TrainingDocPage.java
@@ -0,0 +1,8 @@
+package org.apache.tapestry5.integration.app1.base.imports;
+
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.integration.app1.pages.imports.TrainingWrapper;
+
+@Import(stylesheet = "context:css/TrainingDocPage.css")
+public abstract class TrainingDocPage extends TrainingWrapper {
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithImport.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithImport.java
index 286afb0d5..f5f8f5bd9 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithImport.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithImport.java
@@ -8,7 +8,7 @@ import org.apache.tapestry5.annotations.Persist;
 import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.corelib.components.Zone;
 
-@Import(stylesheet = "context:css/ie-only.css")
+@Import(stylesheet = {"context:css/ie-only.css", "context:css/via-import2.css"})
 public class SubclassWithImport extends SuperclassWithImport {
     
     @Property int getIntCallCount;
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperSuperclassWithImport.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperSuperclassWithImport.java
new file mode 100644
index 000000000..996dec2c7
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperSuperclassWithImport.java
@@ -0,0 +1,8 @@
+package org.apache.tapestry5.integration.app1.components;
+
+import org.apache.tapestry5.annotations.Import;
+
+@Import(stylesheet = "context:css/via-import3.css")
+public class SuperSuperclassWithImport {
+    
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithImport.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithImport.java
index a03c1cde3..777549caa 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithImport.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithImport.java
@@ -6,7 +6,7 @@ import org.apache.tapestry5.annotations.Import;
 import org.apache.tapestry5.annotations.Persist;
 
 @Import(stylesheet = "context:css/via-import.css")
-public class SuperclassWithImport {
+public class SuperclassWithImport extends SuperclassWithoutImport {
     
     // Just to test CachedWorker with a watch expression 
     @Persist
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithoutImport.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithoutImport.java
new file mode 100644
index 000000000..658bfe680
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithoutImport.java
@@ -0,0 +1,5 @@
+package org.apache.tapestry5.integration.app1.components;
+
+public class SuperclassWithoutImport extends SuperSuperclassWithImport {
+
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/imports/MessageCatalogue.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/imports/MessageCatalogue.java
new file mode 100644
index 000000000..e501fb522
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/imports/MessageCatalogue.java
@@ -0,0 +1,6 @@
+package org.apache.tapestry5.integration.app1.pages.imports;
+
+import org.apache.tapestry5.integration.app1.base.imports.TrainingDocPage;
+
+public class MessageCatalogue extends TrainingDocPage {
+}
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/imports/TrainingWrapper.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/imports/TrainingWrapper.java
new file mode 100644
index 000000000..847a9a893
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/imports/TrainingWrapper.java
@@ -0,0 +1,8 @@
+package org.apache.tapestry5.integration.app1.pages.imports;
+
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.integration.app1.base.imports.PageWrapper;
+
+@Import(stylesheet = "context:css/TrainingWrapper.css")
+public class TrainingWrapper extends PageWrapper {
+}
diff --git a/tapestry-webresources/src/test/java/t5/webresources/base/ComponentBase.java b/tapestry-webresources/src/test/java/t5/webresources/base/ComponentBase.java
new file mode 100644
index 000000000..daf81a5e6
--- /dev/null
+++ b/tapestry-webresources/src/test/java/t5/webresources/base/ComponentBase.java
@@ -0,0 +1,4 @@
+package t5.webresources.base;
+
+public abstract class ComponentBase {
+}
diff --git a/tapestry-webresources/src/test/java/t5/webresources/base/ComponentCommonBase.java b/tapestry-webresources/src/test/java/t5/webresources/base/ComponentCommonBase.java
new file mode 100644
index 000000000..4023087da
--- /dev/null
+++ b/tapestry-webresources/src/test/java/t5/webresources/base/ComponentCommonBase.java
@@ -0,0 +1,16 @@
+package t5.webresources.base;
+
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.dom.Element;
+
+public abstract class ComponentCommonBase extends ComponentBase {
+    
+//    void afterRender(MarkupWriter writer)
+//    {
+//        final Element body = writer.getDocument().getRootElement();
+//        final Element p = body.element("p", "id", "hi");
+//        p.text("Hi! AAAAAAAAAAAAAAA");
+//        p.moveToBottom(body);
+//    }
+    
+}
diff --git a/tapestry-webresources/src/test/java/t5/webresources/base/PageWrapper.java b/tapestry-webresources/src/test/java/t5/webresources/base/PageWrapper.java
new file mode 100644
index 000000000..2d60317b2
--- /dev/null
+++ b/tapestry-webresources/src/test/java/t5/webresources/base/PageWrapper.java
@@ -0,0 +1,7 @@
+package t5.webresources.base;
+
+import org.apache.tapestry5.annotations.Import;
+
+@Import(stylesheet = "classpath:/META-INF/assets/PageWrapper.less")
+public abstract class PageWrapper extends ComponentCommonBase {
+}
diff --git a/tapestry-webresources/src/test/java/t5/webresources/base/TrainingDocPage.java b/tapestry-webresources/src/test/java/t5/webresources/base/TrainingDocPage.java
new file mode 100644
index 000000000..c5ee88920
--- /dev/null
+++ b/tapestry-webresources/src/test/java/t5/webresources/base/TrainingDocPage.java
@@ -0,0 +1,9 @@
+package t5.webresources.base;
+
+import org.apache.tapestry5.annotations.Import;
+
+import t5.webresources.pages.TrainingWrapper;
+
+@Import(stylesheet = "classpath:/META-INF/assets/TrainingDocPage.less")
+public abstract class TrainingDocPage extends TrainingWrapper {
+}
diff --git a/tapestry-webresources/src/test/java/t5/webresources/pages/MessageCatalogue.java b/tapestry-webresources/src/test/java/t5/webresources/pages/MessageCatalogue.java
new file mode 100644
index 000000000..a0e4b7e53
--- /dev/null
+++ b/tapestry-webresources/src/test/java/t5/webresources/pages/MessageCatalogue.java
@@ -0,0 +1,6 @@
+package t5.webresources.pages;
+
+import t5.webresources.base.TrainingDocPage;
+
+public class MessageCatalogue extends TrainingDocPage {
+}
diff --git a/tapestry-webresources/src/test/java/t5/webresources/pages/TrainingWrapper.java b/tapestry-webresources/src/test/java/t5/webresources/pages/TrainingWrapper.java
new file mode 100644
index 000000000..295306e13
--- /dev/null
+++ b/tapestry-webresources/src/test/java/t5/webresources/pages/TrainingWrapper.java
@@ -0,0 +1,9 @@
+package t5.webresources.pages;
+
+import org.apache.tapestry5.annotations.Import;
+
+import t5.webresources.base.PageWrapper;
+
+@Import(stylesheet = "classpath:/META-INF/assets/TrainingWrapper.less")
+public class TrainingWrapper extends PageWrapper {
+}
diff --git a/tapestry-webresources/src/test/resources/META-INF/assets/PageWrapper.less b/tapestry-webresources/src/test/resources/META-INF/assets/PageWrapper.less
new file mode 100644
index 000000000..f417b2c50
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/META-INF/assets/PageWrapper.less
@@ -0,0 +1,5 @@
+div.page-wrapper
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-webresources/src/test/resources/META-INF/assets/TrainingDocPage.less b/tapestry-webresources/src/test/resources/META-INF/assets/TrainingDocPage.less
new file mode 100644
index 000000000..6c310b689
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/META-INF/assets/TrainingDocPage.less
@@ -0,0 +1,5 @@
+div.training-doc-page
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-webresources/src/test/resources/META-INF/assets/TrainingWrapper.less b/tapestry-webresources/src/test/resources/META-INF/assets/TrainingWrapper.less
new file mode 100644
index 000000000..5f5620d1c
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/META-INF/assets/TrainingWrapper.less
@@ -0,0 +1,5 @@
+div.training-wrapper
+{
+  color: red;
+}  
+  
\ No newline at end of file
diff --git a/tapestry-webresources/src/test/resources/t5/webresources/pages/MessageCatalogue.tml b/tapestry-webresources/src/test/resources/t5/webresources/pages/MessageCatalogue.tml
new file mode 100644
index 000000000..8e4e6bc39
--- /dev/null
+++ b/tapestry-webresources/src/test/resources/t5/webresources/pages/MessageCatalogue.tml
@@ -0,0 +1,23 @@
+<t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+
+    <p>This page is used to demonstrate Less that uses @Import.</p>
+
+	<div class="page-wrapper">
+		<p>
+			This should be red (page wrapper)
+		</p>
+	</div>
+
+	<div class="training-doc-page">
+		<p>
+			This should be red (training doc page)
+		</p>
+	</div>
+	
+	<div class="training-wrapper">
+		<p>
+			This should be red (training wrapper).
+		</p>
+	</div>
+
+</t:layout>