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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/master by this push:
     new 05ac1644d3 CAUSEWAY-3404: fixes mixin naming strategy
05ac1644d3 is described below

commit 05ac1644d3d636d5d1aea2549f6ec5e69da26bca
Author: Andi Huber <[email protected]>
AuthorDate: Thu May 11 18:20:28 2023 +0200

    CAUSEWAY-3404: fixes mixin naming strategy
---
 .../causeway/commons/internal/base/_Strings.java   | 59 +++++++++-------------
 .../internal/base/_Strings_NaturalName.java        |  5 +-
 .../commons/internal/base/StringsTest.java         | 32 ++++++++----
 .../core/metamodel/commons/StringExtensions.java   | 31 ------------
 .../specimpl/_MixedInMemberNamingStrategy.java     | 20 ++++----
 .../commons/StringUtils_NormalizedTest.java        | 54 --------------------
 .../specimpl/MixedInMemberNamingStrategyTest.java  |  8 +--
 7 files changed, 61 insertions(+), 148 deletions(-)

diff --git 
a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings.java 
b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings.java
index ad87ef7d21..38dfd8f92c 100644
--- 
a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings.java
+++ 
b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings.java
@@ -797,60 +797,49 @@ public final class _Strings {
     // -- UNARY OPERATOR COMPOSITION
 
     /**
-     * Monadic StringOperator that allows composition of unary string 
operators.
+     * Helper for composing of {@code UnaryOperator<String>}.
      */
-    public static final class StringOperator {
-
-        private final UnaryOperator<String> operator;
-
-        private StringOperator(final @NonNull UnaryOperator<String> operator) {
-            this.operator = operator;
-        }
-
-        public String apply(final String input) {
-            return operator.apply(input);
+    @FunctionalInterface
+    public static interface StringOperator extends UnaryOperator<String> {
+        default StringOperator compose(final UnaryOperator<String> andThen) {
+            return str->this.andThen(andThen).apply(str);
         }
-
-        public StringOperator andThen(final UnaryOperator<String> andThen) {
-            return new StringOperator(s->andThen.apply(operator.apply(s)));
+        /**
+         * Returns a unary operator that always returns its input argument.
+         */
+        static StringOperator identity() {
+            return s -> s;
         }
-
-    }
-
-    /**
-     * Returns a StringOperator that allows composition of unary string 
operators
-     */
-    public static StringOperator operator() {
-        return new StringOperator(UnaryOperator.identity());
     }
 
     // -- SPECIAL COMPOSITES
 
     // using naming convention asXxx...
 
-    public static final StringOperator asLowerDashed = operator()
-            .andThen(_Strings::lower)
-            .andThen(s->_Strings.condenseWhitespaces(s, "-"));
+    public static final StringOperator asLowerCase = _Strings::lower;
+
+    public static final StringOperator asLowerDashed = asLowerCase
+            .compose(s->_Strings.condenseWhitespaces(s, "-"));
 
-    public static final StringOperator asNormalized = operator()
-            .andThen(s->_Strings.condenseWhitespaces(s, " "));
+    public static final StringOperator asNormalized =
+            s->_Strings.condenseWhitespaces(s, " ");
 
-    public static final StringOperator asNaturalName = operator()
-            .andThen(s->_Strings_NaturalName.naturalName(s, true));
+    public static final StringOperator asNaturalName =
+            s->_Strings_NaturalName.naturalName(s, true);
 
     /**
      * Camel case is the practice of writing phrases without spaces or 
punctuation and with capitalized words.
      * The format indicates the first word starting with EITHER case,
      * then the following words having an initial uppercase letter.
      */
-    public static final StringOperator asCamelCase = operator()
-            .andThen(s->_Strings_CamelCase.camelCase(s, 
firstToken->firstToken));
+    public static final StringOperator asCamelCase =
+            s->_Strings_CamelCase.camelCase(s, firstToken->firstToken);
 
-    public static final StringOperator asCamelCaseDecapitalized = operator()
-            .andThen(s->_Strings_CamelCase.camelCase(s, 
firstToken->_Strings.decapitalize(firstToken)));
+    public static final StringOperator asCamelCaseDecapitalized =
+            s->_Strings_CamelCase.camelCase(s, 
firstToken->_Strings.decapitalize(firstToken));
 
-    public static final StringOperator asCamelCaseCapitalized = operator()
-            .andThen(s->_Strings_CamelCase.camelCase(s, 
firstToken->_Strings.capitalize(firstToken)));
+    public static final StringOperator asCamelCaseCapitalized =
+            s->_Strings_CamelCase.camelCase(s, 
firstToken->_Strings.capitalize(firstToken));
     public static final StringOperator asPascalCase = asCamelCaseCapitalized; 
// synonym
 
     public static final String asFileNameWithExtension(final @NonNull String 
fileName, final @NonNull String fileExtension) {
diff --git 
a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings_NaturalName.java
 
b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings_NaturalName.java
index 513c6e7d1b..e94aab5ca2 100644
--- 
a/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings_NaturalName.java
+++ 
b/commons/src/main/java/org/apache/causeway/commons/internal/base/_Strings_NaturalName.java
@@ -36,13 +36,10 @@ class _Strings_NaturalName {
      *
      * @param name
      * @param handleNestedClassNames whether to handle any nested class names, 
eg 'Foo$Bar'
-     * @return
-     *
      */
     String naturalName(@Nullable String name, final boolean 
handleNestedClassNames) {
 
-        if(name==null)
-            return null;
+        if(name==null) return null;
 
         if(handleNestedClassNames) {
             // handle any nested class names, eg 'Foo$Bar'
diff --git 
a/commons/src/test/java/org/apache/causeway/commons/internal/base/StringsTest.java
 
b/commons/src/test/java/org/apache/causeway/commons/internal/base/StringsTest.java
index dbfa2d0017..c9e6162335 100644
--- 
a/commons/src/test/java/org/apache/causeway/commons/internal/base/StringsTest.java
+++ 
b/commons/src/test/java/org/apache/causeway/commons/internal/base/StringsTest.java
@@ -29,6 +29,7 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 import org.apache.causeway.commons.internal._Constants;
 
@@ -256,21 +257,21 @@ class StringsTest {
     @Test
     void composeIdentityWithNull() throws Exception {
         assertThat(
-                _Strings.operator().apply(null),
+                _Strings.StringOperator.identity().apply(null),
                 nullValue());
     }
 
     @Test
     void composeIdentity() throws Exception {
         assertThat(
-                _Strings.operator().apply(" 12 aBc"),
+                _Strings.StringOperator.identity().apply(" 12 aBc"),
                 is(" 12 aBc"));
     }
 
     @Test
     void compose2WithNull() throws Exception {
         assertThat(
-                _Strings.operator()
+                _Strings.StringOperator.identity()
                 .andThen(_Strings::lower)
                 .apply(null),
                 nullValue());
@@ -279,7 +280,7 @@ class StringsTest {
     @Test
     void compose2() throws Exception {
         assertThat(
-                _Strings.operator()
+                _Strings.StringOperator.identity()
                 .andThen(_Strings::lower)
                 .apply(" 12 aBc"),
                 is(" 12 abc"));
@@ -288,7 +289,7 @@ class StringsTest {
     @Test
     void composeOperatorSequency_LastShouldWin() throws Exception {
         assertThat(
-                _Strings.operator()
+                _Strings.StringOperator.identity()
                 .andThen(_Strings::lower)
                 .andThen(_Strings::upper)
                 .apply(" 12 aBc"),
@@ -311,14 +312,25 @@ class StringsTest {
 
     @Test
     void asNormalized() throws Exception {
-        assertThat(
-                _Strings.asNormalized
-                .apply(" 12 a B         c"),
-                is(" 12 a B c"));
+        assertNull(asNormalized(null)); // null
+        assertThat(asNormalized(""), is("")); // empty string
+        assertThat(asNormalized("yada Foobar"), is("yada Foobar")); // 
alreadyNormalized
+        assertThat(asNormalized("Yada\tFoobar"), is("Yada Foobar")); // tab
+        assertThat(asNormalized("Yada\t Foobar"), is("Yada Foobar")); // tab 
and space
+        assertThat(asNormalized("Yada  foobar"), is("Yada foobar")); // two 
spaces
+        assertThat(asNormalized("Yada\nfoobar"), is("Yada foobar")); // new 
line
+        assertThat(asNormalized("Yada\n Foobar"), is("Yada Foobar")); // 
newline and space
+        assertThat(asNormalized("Yada\r\n Foobar"), is("Yada Foobar")); // 
windows newline
+        assertThat(asNormalized("Yada\r Foobar"), is("Yada Foobar")); // 
mac-os newline
+        assertThat(asNormalized("Yada\r \tFoo \n\tbar  Baz"), is("Yada Foo bar 
Baz")); // multiple
+        assertThat(asNormalized(" 12 a B         c"), is(" 12 a B c"));
+    }
+    private String asNormalized(final String string) {
+        return _Strings.asNormalized.apply(string);
     }
 
     @Test
-    void asNaturalName2() throws Exception {
+    void asNaturalName() throws Exception {
         assertThat(
                 _Strings.asNaturalName
                 .apply("NextAvailableDate"),
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/StringExtensions.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/StringExtensions.java
index fe0b3e8eb1..0a48d88d7a 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/StringExtensions.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/commons/StringExtensions.java
@@ -18,8 +18,6 @@
  */
 package org.apache.causeway.core.metamodel.commons;
 
-import org.springframework.lang.Nullable;
-
 import org.apache.causeway.applib.util.Enums;
 import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.base._Strings;
@@ -56,15 +54,6 @@ public final class StringExtensions {
         return extendee.substring(1);
     }
 
-    /**
-     * Condenses any whitespace to a single character
-     *
-     * @param extendee
-     */
-    public static String normalized(final @Nullable String extendee) {
-        return _Strings.asNormalized.apply(extendee);
-    }
-
     public static String removePrefix(final String extendee, final String 
prefix) {
         return extendee.startsWith(prefix)
                 ? extendee.substring(prefix.length())
@@ -139,24 +128,4 @@ public final class StringExtensions {
         return javaBaseName;
     }
 
-    public static String toCamelCase(final String extendee) {
-        final String nameLower = extendee.toLowerCase();
-        final StringBuilder buf = new StringBuilder();
-        boolean capitalizeNext = false;
-        for (int i = 0; i < nameLower.length(); i++) {
-            final char ch = nameLower.charAt(i);
-            if (ch == '_') {
-                capitalizeNext = true;
-            } else {
-                if (capitalizeNext) {
-                    buf.append(Character.toUpperCase(ch));
-                } else {
-                    buf.append(ch);
-                }
-                capitalizeNext = false;
-            }
-        }
-        return buf.toString();
-    }
-
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/_MixedInMemberNamingStrategy.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/_MixedInMemberNamingStrategy.java
index 74a8392a5e..f97a4a1d6a 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/_MixedInMemberNamingStrategy.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/_MixedInMemberNamingStrategy.java
@@ -33,11 +33,11 @@ class _MixedInMemberNamingStrategy {
      *              for mixin main methods
      */
     String mixinFriendlyName(final @NonNull ObjectActionDefault 
mixinActionAsRegular) {
-        return 
mixinFriendlyName(mixinActionAsRegular.getFeatureIdentifier().getClassNaturalName());
+        return mixinFriendlyName(mixinClassSimpleName(mixinActionAsRegular));
     }
 
     String mixinFriendlyName(final @NonNull String mixinClassSimpleName) {
-        return _Strings.capitalize(suffix(mixinClassSimpleName));
+        return 
_Strings.asCamelCase.andThen(_Strings.asNaturalName).apply(lastWord(mixinClassSimpleName));
     }
 
     /**
@@ -45,32 +45,32 @@ class _MixedInMemberNamingStrategy {
      *              for mixin main methods
      */
     String mixinMemberId(final @NonNull ObjectActionDefault 
mixinActionAsRegular) {
-        return 
mixinMemberId(mixinActionAsRegular.getFeatureIdentifier().getClassNaturalName());
+        return mixinMemberId(mixinClassSimpleName(mixinActionAsRegular));
     }
 
     String mixinMemberId(final @NonNull String mixinClassSimpleName) {
-        return 
_Strings.asCamelCaseDecapitalized.apply(compress(suffix(mixinClassSimpleName)));
+        return _Strings.decapitalize(lastWord(mixinClassSimpleName));
     }
 
     // -- HELPER
 
-    private static String compress(final String suffix) {
-        return suffix.replaceAll(" ", "");
+    private String mixinClassSimpleName(final ObjectActionDefault 
mixinActionAsRegular) {
+        return 
mixinActionAsRegular.getFeatureIdentifier().getLogicalType().getCorrespondingClass().getSimpleName();
     }
 
-    private static String suffix(final String mixinClassSimpleName) {
-        final String deriveFromUnderscore = derive(mixinClassSimpleName, "_");
+    private String lastWord(final String mixinClassSimpleName) {
+        final String deriveFromUnderscore = lastToken(mixinClassSimpleName, 
"_");
         if(!Objects.equals(mixinClassSimpleName, deriveFromUnderscore)) {
             return deriveFromUnderscore;
         }
-        final String deriveFromDollar = derive(mixinClassSimpleName, "$");
+        final String deriveFromDollar = lastToken(mixinClassSimpleName, "$");
         if(!Objects.equals(mixinClassSimpleName, deriveFromDollar)) {
             return deriveFromDollar;
         }
         return mixinClassSimpleName;
     }
 
-    private String derive(final String singularName, final String separator) {
+    private String lastToken(final String singularName, final String 
separator) {
         final int indexOfSeparator = singularName.lastIndexOf(separator);
         return occursNotAtEnd(singularName, indexOfSeparator)
                 ? singularName.substring(indexOfSeparator + 1)
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/commons/StringUtils_NormalizedTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/commons/StringUtils_NormalizedTest.java
deleted file mode 100644
index c3651919d3..0000000000
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/commons/StringUtils_NormalizedTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.core.metamodel.commons;
-
-import java.util.stream.Stream;
-
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-class StringUtils_NormalizedTest {
-
-    @ParameterizedTest
-    @MethodSource("data")
-    public void normalizesOk(final String input, final String expected) {
-        assertThat(StringExtensions.normalized(input), is(expected));
-    }
-
-    private static Stream<Arguments> data() {
-        return Stream.of(
-          Arguments.of(null, null), // null
-          Arguments.of("", ""), // empty string
-          Arguments.of("yada Foobar", "yada Foobar"), // alreadyNormalized
-          Arguments.of("Yada\tFoobar", "Yada Foobar"), // tab
-          Arguments.of("Yada\t Foobar", "Yada Foobar"), // tab and space
-          Arguments.of("Yada  foobar", "Yada foobar"), // two spaces
-          Arguments.of("Yada\nfoobar", "Yada foobar"), // new line
-          Arguments.of("Yada\n Foobar", "Yada Foobar"), // newline and space
-          Arguments.of("Yada\r\n Foobar", "Yada Foobar"), // windows newline
-          Arguments.of("Yada\r Foobar", "Yada Foobar"), // macos newline
-          Arguments.of("Yada\r \tFoo \n\tbar  Baz", "Yada Foo bar Baz") // 
multiple
-        );
-    }
-
-}
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/specloader/specimpl/MixedInMemberNamingStrategyTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/specloader/specimpl/MixedInMemberNamingStrategyTest.java
index 7bf7b74e97..fe35870003 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/specloader/specimpl/MixedInMemberNamingStrategyTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/specloader/specimpl/MixedInMemberNamingStrategyTest.java
@@ -30,10 +30,10 @@ class MixedInMemberNamingStrategyTest {
 
     @RequiredArgsConstructor
     enum Scenario {
-        SINGLE_UNDERSCORE("Customer_placeOrder", "placeOrder", "PlaceOrder"),
-        SINGLE_DOLLAR("Customer$placeOrder", "placeOrder", "PlaceOrder"),
-        EXACTLY_UNDERSCORE("_", "_", "_"),
-        ENDS_WITH_UNDERSCORE("abc_", "abc_", "Abc_"),
+        SINGLE_UNDERSCORE("Customer_placeOrder", "placeOrder", "Place Order"),
+        SINGLE_DOLLAR("Customer$placeOrder", "placeOrder", "Place Order"),
+        //EXACTLY_UNDERSCORE("_", "_", "_"), //TODO this should throw instead
+        ENDS_WITH_UNDERSCORE("abc_", "abc_", "Abc"),
         HAS_NO_UNDERSCORE("lock", "lock", "Lock"),
         CONTAINS_MORE_THAN_ONE_UNDERSCORE("ApplicationUser_default_lock", 
"lock", "Lock")
         ;

Reply via email to