You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2023/09/22 11:14:09 UTC

[causeway] branch CAUSEWAY-3599 updated: CAUSEWAY-3599: adds support for additional conventions

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

danhaywood pushed a commit to branch CAUSEWAY-3599
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/CAUSEWAY-3599 by this push:
     new 418fe3c0e7 CAUSEWAY-3599: adds support for additional conventions
418fe3c0e7 is described below

commit 418fe3c0e71787c12e02d16a06549ffeeb551dee
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Fri Sep 22 12:14:06 2023 +0100

    CAUSEWAY-3599: adds support for additional conventions
---
 .../TableColumnOrderServiceUsingTxtFile.java       | 94 +++++++++++++++++-----
 .../tablecol/Customer#_.Order4.columnOrder.txt     |  5 ++
 .../Customer#_.Order5.columnOrder.fallback.txt     |  5 ++
 .../TableColumnOrderServiceUsingTxtFile_Test.java  | 30 +++++++
 4 files changed, 114 insertions(+), 20 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile.java
index bba6e44cef..eba1607ebf 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile.java
@@ -25,6 +25,8 @@ import java.util.Optional;
 import javax.annotation.Priority;
 import javax.inject.Named;
 
+import org.apache.causeway.applib.annotation.CollectionLayout;
+
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
@@ -40,28 +42,52 @@ import lombok.extern.log4j.Log4j2;
 
 /**
  * Provides a simple mechanism to order the columns of both parented and standalone collections by reading a flat
- * file containing the list of the properties in the desired order, one propertyId per line.
+ * file containing the list of the associations (usually properties, but collections are also supported), in the
+ * desired order, one associationId per line.
  *
  * <p>
- * The files are located relative to the class itself.  For parented collections, the file is named
- * <i>ParentClassName#collectionId.columnOrder.txt</i>, while for standalone collections, the file is named
- * <i>ClassName.columnOrder.txt</i>.
- * </p>
+ * The files are located relative to the class itself.  A number of conventions are supported:
+ *
+ * <ul>
+ *     <li>
+ *         for parented collections:
+ *         <ul>
+ *             <li> <code>ParentClassName#collectionId.columnOrder.txt</code> </li>
+ *             <li> <code>ParentClassName#collectionId.columnOrder.fallback.txt</code> </li>
+ *             <li> <code>ParentClassName#_.ElementTypeClassName.columnOrder.txt</code>
+ *             <p>
+ *                 (where '_' is a wildcard for any collection of the element type
+ *             </p>
+ *             </li>
+ *             <li> <code>ParentClassName#_.ElementTypeClassName.columnOrder.fallback.txt</code></li>
+ *             <li> <code>ElementTypeClassName.columnOrder.txt</code></li>
+ *             <li> <code>ElementTypeClassName.columnOrder.fallback.txt</code></li>
+ *         </ul>
+ *     </li>
+ *     <li>
+ *         for standalone collections:
+ *         <ul>
+ *             <li> <code>DomainTypeClassName.columnOrder.txt</code></li>
+ *             <li> <code>DomainTypeClassName.columnOrder.fallback.txt</code></li>
+ *         </ul>
+ *     </li>
+ * </ul>
  *
  * <p>
- * Any properties omitted from the file will not be shown as columns of the table.  The propertyId must also
+ * Any associations omitted from the file will not be shown as columns of the table.  The associationId must also
  * be an exact match, so can be ignored by commenting out, eg with &quot;#&quot;.
  * </p>
  *
  * <p>
- *     Also note that properties that have been explicitly hidden from tables using
- *     {@link PropertyLayout#hidden() @PropertyLayout#hidden} are never shown, irrespective of whether they are listed
- *     in the files.  You may therefore prefer to <i>not</i> hide properties with annotations, and then rely solely
- *     on these external <i>columnOrder.txt</i> files.  This has the further benefit that files can be modified at
- *     runtime and will be automatically picked up without requiring a restart of the application.
+ *     Also note that association that have been explicitly hidden from tables using
+ *     {@link PropertyLayout#hidden() @PropertyLayout#hidden} or {@link CollectionLayout#hidden()} are never shown,
+ *     irrespective of whether they are listed in the files.  You may therefore prefer to <i>not</i> hide properties
+ *     with annotations, and then rely solely on these external <i>columnOrder.txt</i> files.  This has the further
+ *     benefit that files can be modified at runtime and will be automatically picked up without requiring a restart
+ *     of the application.
  * </p>
  *
- * @since 1.x {@index}
+ * @since 2.x {@index}
  */
 @Service
 @Named(CausewayModuleCoreMetamodel.NAMESPACE + ".TableColumnOrderServiceUsingTxtFile")
@@ -71,11 +97,26 @@ import lombok.extern.log4j.Log4j2;
 public class TableColumnOrderServiceUsingTxtFile implements TableColumnOrderService {
 
     /**
-     * Reads association Ids of the collection from a file named <i>ClassName#collectionId.columnOrder.txt</i> relative
-     * to the class itself; if there is no such file then falls back to <i>CollectionType.columnOrder.txt</i>.
+     * Reads association Ids of the parented collection from a file.
+     *
+     * <p>
+     * The search algorithm is:
+     * <ul>
+     *     <li> <code>ParentClassName#collectionId.columnOrder.txt</code> </li>
+     *     <li> <code>ParentClassName#collectionId.columnOrder.fallback.txt</code> </li>
+     *     <li> <code>ParentClassName#_.ElementTypeClassName.columnOrder.txt</code>
+     *     <p>
+     *         (where '_' is a wildcard for any collection of the element type
+     *     </p>
+     *     </li>
+     *     <li> <code>ParentClassName#_.ElementTypeClassName.columnOrder.fallback.txt</code></li>
+     *     <li> <code>ElementTypeClassName.columnOrder.txt</code></li>
+     *     <li> <code>ElementTypeClassName.columnOrder.fallback.txt</code></li>
+     * </ul>
+     * </p>
      *
      * <p>
-     * Additional files can be provided by overriding {@link #addResourceNames(Class, String, List)}.
+         * Additional files can be provided by overriding {@link #addResourceNames(Class, String, Class, List)}
      * </p>
      */
     @Override
@@ -86,15 +127,18 @@ public class TableColumnOrderServiceUsingTxtFile implements TableColumnOrderServ
             final List<String> associationIds) {
 
         val domainClass = domainObject.getClass();
-        val resourceNames = buildResourceNames(domainClass, collectionId);
+        val resourceNames = buildResourceNames(domainClass, collectionId, elementType);
         addResourceNames(elementType, resourceNames);   // fallback to reading the element type's own .txt file.
         val contentsIfAny = tryLoad(domainClass, resourceNames);
         return contentsMatching(contentsIfAny, associationIds);
     }
 
-    private List<String> buildResourceNames(final Class<?> domainClass, final String collectionId) {
+    private List<String> buildResourceNames(
+            final Class<?> domainClass,
+            final String collectionId,
+            final Class<?> elementType) {
         val resourceNames = new ArrayList<String>();
-        addResourceNames(domainClass, collectionId, resourceNames);
+        addResourceNames(domainClass, collectionId, elementType, resourceNames);
         return resourceNames;
     }
 
@@ -112,9 +156,12 @@ public class TableColumnOrderServiceUsingTxtFile implements TableColumnOrderServ
     protected void addResourceNames(
             final Class<?> domainClass,
             final String collectionId,
+            final Class<?> elementType,
             final List<String> addTo) {
         addTo.add(String.format("%s#%s.columnOrder.txt", domainClass.getSimpleName(), collectionId));
         addTo.add(String.format("%s#%s.columnOrder.fallback.txt", domainClass.getSimpleName(), collectionId));
+        addTo.add(String.format("%s#_.%s.columnOrder.txt", domainClass.getSimpleName(), elementType.getSimpleName()));
+        addTo.add(String.format("%s#_.%s.columnOrder.fallback.txt", domainClass.getSimpleName(), elementType.getSimpleName()));
     }
 
     private static Optional<String> tryLoad(final Class<?> domainClass, final List<String> resourceNames) {
@@ -136,8 +183,15 @@ public class TableColumnOrderServiceUsingTxtFile implements TableColumnOrderServ
     }
 
     /**
-     * Reads propertyIds of the standalone collection from a file named <i>ClassName.columnOrder.txt</i>, relative
-     * to the class itself.
+     * Reads associationIds of a standalone collection from a file.
+     *
+     * <p>
+     * The search algorithm is:
+     * <ul>
+     *     <li> <code>DomainTypeClassName.columnOrder.txt</code></li>
+     *     <li> <code>DomainTypeClassName.columnOrder.fallback.txt</code></li>
+     * </ul>
+     * </p>
      *
      * <p>
      * Additional files can be provided by overriding {@link #addResourceNames(Class, List)}.
diff --git a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/Customer#_.Order4.columnOrder.txt b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/Customer#_.Order4.columnOrder.txt
new file mode 100644
index 0000000000..969d8614ba
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/Customer#_.Order4.columnOrder.txt
@@ -0,0 +1,5 @@
+orderNum
+#orderAmount
+orderDate
+orderStatus
+nonsense
\ No newline at end of file
diff --git a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/Customer#_.Order5.columnOrder.fallback.txt b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/Customer#_.Order5.columnOrder.fallback.txt
new file mode 100644
index 0000000000..969d8614ba
--- /dev/null
+++ b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/Customer#_.Order5.columnOrder.fallback.txt
@@ -0,0 +1,5 @@
+orderNum
+#orderAmount
+orderDate
+orderStatus
+nonsense
\ No newline at end of file
diff --git a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile_Test.java b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile_Test.java
index 5e42bcd950..f5b7265242 100644
--- a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile_Test.java
+++ b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/services/tablecol/TableColumnOrderServiceUsingTxtFile_Test.java
@@ -66,6 +66,32 @@ class TableColumnOrderServiceUsingTxtFile_Test {
             assertThat(ordered).containsExactly("orderNum", "orderDate", "orderStatus");
         }
 
+        /**
+         * should read from Customer#_.Order4.columnOrder.txt
+         */
+        @Test
+        void fallback_to_wildcard_type() {
+            // when
+            val ordered = service.orderParented(new Customer(), "otherOrders", Order4.class,
+                    Arrays.asList("orderNum", "orderStatus", "orderDate", "orderAmount"));
+
+            // then
+            assertThat(ordered).containsExactly("orderNum", "orderDate", "orderStatus");
+        }
+
+        /**
+         * should read from Customer#_.Order5.columnOrder.fallback.txt
+         */
+        @Test
+        void fallback_to_wildcard_fallback_type() {
+            // when
+            val ordered = service.orderParented(new Customer(), "otherOrders", Order5.class,
+                    Arrays.asList("orderNum", "orderStatus", "orderDate", "orderAmount"));
+
+            // then
+            assertThat(ordered).containsExactly("orderNum", "orderDate", "orderStatus");
+        }
+
         /**
          * should read from Order.columnOrder.txt
          */
@@ -132,5 +158,9 @@ class Order2 {
 }
 class Order3 {
 }
+class Order4 {
+}
+class Order5 {
+}
 class Customer {
 }