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")
;