This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3676 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 9d9651540d11e2cd72ac96e8ee0c652532a31003 Author: danhaywood <[email protected]> AuthorDate: Tue Mar 12 17:20:13 2024 +0000 CAUSEWAY-3676: reworks to use an SPI instead of annotation --- api/applib/src/main/java/module-info.java | 1 + .../apache/causeway/applib/annotation/Action.java | 13 ------ .../causeway/applib/annotation/Collection.java | 13 ------ .../causeway/applib/annotation/Parameter.java | 13 ------ .../causeway/applib/annotation/Property.java | 13 ------ .../services/ascii/AsciiIdentifierService.java | 20 +++++++++ core/metamodel/src/main/java/module-info.java | 1 - .../metamodel/context/HasMetaModelContext.java | 6 +++ .../core/metamodel/context/MetaModelContext.java | 2 + .../action/ActionAnnotationFacetFactory.java | 12 ------ .../ascii/AsciiFacetForActionAnnotation.java | 48 ---------------------- .../metamodel/facets/all/ascii/AsciiFacet.java | 29 ------------- .../facets/all/ascii/AsciiFacetAbstract.java | 48 ---------------------- .../CollectionAnnotationFacetFactory.java | 11 ----- .../ascii/AsciiFacetForCollectionAnnotation.java | 48 ---------------------- .../ascii/AsciiFacetForParameterAnnotation.java | 47 --------------------- .../parameter/ParameterAnnotationFacetFactory.java | 13 ------ .../ascii/AsciiFacetForPropertyAnnotation.java | 48 ---------------------- .../property/PropertyAnnotationFacetFactory.java | 12 ------ .../core/metamodel/spec/feature/ObjectFeature.java | 1 + .../specloader/specimpl/ObjectActionDefault.java | 5 +++ .../specimpl/ObjectActionParameterAbstract.java | 7 ++++ .../specloader/specimpl/ObjectMemberAbstract.java | 5 +++ viewers/graphql/adoc/modules/ROOT/pages/i18n.adoc | 27 +++++++++--- .../viewer/graphql/model/context/Context.java | 3 +- .../viewer/graphql/model/domain/TypeNames.java | 2 +- .../domain/common/query/ObjectFeatureUtils.java | 4 +- .../model/domain/simple/query/SimpleAction.java | 2 +- ...iiIdentifierServiceSupportingGraphqlViewer.java | 13 ++++++ .../viewer/test/domain/i18n/I18nCalculator.java | 4 +- 30 files changed, 87 insertions(+), 384 deletions(-) diff --git a/api/applib/src/main/java/module-info.java b/api/applib/src/main/java/module-info.java index ba3c1d6f38..bfd4bca708 100644 --- a/api/applib/src/main/java/module-info.java +++ b/api/applib/src/main/java/module-info.java @@ -154,5 +154,6 @@ module org.apache.causeway.applib { opens org.apache.causeway.applib.layout.links; opens org.apache.causeway.applib.layout.menubars.bootstrap; opens org.apache.causeway.applib.layout.menubars; + exports org.apache.causeway.applib.services.ascii; } diff --git a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java index 9795ecfaf4..6b100014a7 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java @@ -213,17 +213,4 @@ public @interface Action { String fileAccept() default ""; - /** - * Returns an alternative id for the action, using only ASCII characters. - * - * <p> - * Although Java itself allows the full UTF character set for identifiers, some integrations (such as GraphQL) - * have restrictions to only allow a more limited set of characters, in essence ASCII. - * This attribute allows a version of the action's Id using only the ASCII character set to be provided. - * </p> - * - * @return an alternative id for the action, using only ASCII characters. - */ - String asciiId() default ""; - } diff --git a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java index 01b9ae8089..5f8837dcb6 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java @@ -95,17 +95,4 @@ public @interface Collection { Class<?> typeOf() default void.class; // represents unspecified - /** - * Returns an alternative id for the collection, using only ASCII characters. - * - * <p> - * Although Java itself allows the full UTF character set for identifiers, some integrations (such as GraphQL) - * have restrictions to only allow a more limited set of characters, in essence ASCII. - * This attribute allows a version of the collection's Id using only the ASCII character set to be provided. - * </p> - * - * @return an alternative id for the collection, using only ASCII characters. - */ - String asciiId() default ""; - } diff --git a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java index 207fd6390b..d825be3d3e 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java @@ -142,17 +142,4 @@ public @interface Parameter { PrecedingParamsPolicy precedingParamsPolicy() default PrecedingParamsPolicy.AS_CONFIGURED; - /** - * Returns an alternative id for the parameter, using only ASCII characters. - * - * <p> - * Although Java itself allows the full UTF character set for identifiers, some integrations (such as GraphQL) - * have restrictions to only allow a more limited set of characters, in essence ASCII. - * This attribute allows a version of the parameter's Id using only the ASCII character set to be provided. - * </p> - * - * @return an alternative id for the parameter, using only ASCII characters. - */ - String asciiId() default ""; - } diff --git a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java index 432fa9f047..3e7df41f92 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java @@ -289,17 +289,4 @@ public @interface Property { */ String regexPatternReplacement() default "Doesn't match pattern"; - - /** - * Returns an alternative id for the property, using only ASCII characters. - * - * <p> - * Although Java itself allows the full UTF character set for identifiers, some integrations (such as GraphQL) - * have restrictions to only allow a more limited set of characters, in essence ASCII. - * This attribute allows a version of the property's Id using only the ASCII character set to be provided. - * </p> - * - * @return an alternative id for the property, using only ASCII characters. - */ - String asciiId() default ""; } diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/ascii/AsciiIdentifierService.java b/api/applib/src/main/java/org/apache/causeway/applib/services/ascii/AsciiIdentifierService.java new file mode 100644 index 0000000000..b39ae2219a --- /dev/null +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/ascii/AsciiIdentifierService.java @@ -0,0 +1,20 @@ +package org.apache.causeway.applib.services.ascii; + +/** + * Optional SPI to provide an equivalent identifier using only ASCII character set, for the specified feature + * (a property, collection, action or action parameter). + * + * <p> + * The GraphQL API (viewer) may require this SPI to be implemented if any of the features use non-ASCII characters, + * because feature Ids are used as GraphQL (field) names. + * </p> + * + * @see <a href="https://spec.graphql.org/October2021/#sec-Names">GraphQL specification</a>. + * + * @since 2.x {@index} + */ +public interface AsciiIdentifierService { + + String asciiIdFor(String featureId); + +} diff --git a/core/metamodel/src/main/java/module-info.java b/core/metamodel/src/main/java/module-info.java index f8b25dc9d0..e3f8907630 100644 --- a/core/metamodel/src/main/java/module-info.java +++ b/core/metamodel/src/main/java/module-info.java @@ -145,7 +145,6 @@ open module org.apache.causeway.core.metamodel { exports org.apache.causeway.core.metamodel.services.grid.spi; exports org.apache.causeway.core.metamodel.facets.object.layout; exports org.apache.causeway.core.metamodel.facets.all.hide; - exports org.apache.causeway.core.metamodel.facets.all.ascii; requires jakarta.activation; requires java.annotation; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/HasMetaModelContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/HasMetaModelContext.java index 3702cb62f9..9b6e17bf58 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/HasMetaModelContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/HasMetaModelContext.java @@ -22,6 +22,8 @@ import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Stream; +import org.apache.causeway.applib.services.ascii.AsciiIdentifierService; + import org.springframework.lang.Nullable; import org.apache.causeway.applib.locale.UserLocale; @@ -196,6 +198,10 @@ public interface HasMetaModelContext { return getMetaModelContext().getServiceRegistry().lookupService(MessageBroker.class); } + public default AsciiIdentifierService getAsciiIdentifierService() { + return getMetaModelContext().getServiceRegistry().lookupService(AsciiIdentifierService.class).orElse(featureId -> featureId); + } + default ManagedObject lookupServiceAdapterById(final String serviceId) { return getMetaModelContext().lookupServiceAdapterById(serviceId); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java index 6ec16c6dcf..f53092ed8a 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/context/MetaModelContext.java @@ -21,6 +21,8 @@ package org.apache.causeway.core.metamodel.context; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +import org.apache.causeway.applib.services.ascii.AsciiIdentifierService; + import org.springframework.lang.Nullable; import org.apache.causeway.commons.internal.assertions._Assert; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java index dde09ec048..c3b6272925 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java @@ -29,7 +29,6 @@ import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; -import org.apache.causeway.core.metamodel.facets.actions.action.ascii.AsciiFacetForActionAnnotation; import org.apache.causeway.core.metamodel.facets.actions.action.choicesfrom.ChoicesFromFacetForActionAnnotation; import org.apache.causeway.core.metamodel.facets.actions.action.explicit.ActionExplicitFacetForActionAnnotation; import org.apache.causeway.core.metamodel.facets.actions.action.invocation.ActionDomainEventFacet; @@ -74,7 +73,6 @@ extends FacetFactoryAbstract { processChoicesFrom(processMethodContext, actionIfAny); processFileAccept(processMethodContext, actionIfAny); - processAsciiName(processMethodContext, actionIfAny); } Optional<Action> actionIfAny(final ProcessMethodContext processMethodContext) { @@ -253,15 +251,5 @@ extends FacetFactoryAbstract { .create(actionIfAny, holder)); } - void processAsciiName(final ProcessMethodContext processMethodContext, final Optional<Action> actionIfAny) { - - val holder = processMethodContext.getFacetHolder(); - - // check for @Action(ascii=...) - addFacetIfPresent( - AsciiFacetForActionAnnotation - .create(actionIfAny, holder)); - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ascii/AsciiFacetForActionAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ascii/AsciiFacetForActionAnnotation.java deleted file mode 100644 index bb94ad1fd7..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ascii/AsciiFacetForActionAnnotation.java +++ /dev/null @@ -1,48 +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.facets.actions.action.ascii; - -import java.util.Optional; - -import org.apache.causeway.applib.annotation.Action; -import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.FacetedMethod; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract; - -public class AsciiFacetForActionAnnotation -extends AsciiFacetAbstract { - - public static Optional<AsciiFacet> create( - final Optional<Action> collectionIfAny, - final FacetedMethod facetHolder) { - - return collectionIfAny - .map(Action::asciiId) - .filter(_Strings::isNotEmpty) - .map(asciiId -> new AsciiFacetForActionAnnotation(asciiId, facetHolder)); - } - - private AsciiFacetForActionAnnotation( - final String value, final FacetHolder holder) { - super(value, holder); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacet.java deleted file mode 100644 index c3775bba00..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacet.java +++ /dev/null @@ -1,29 +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.facets.all.ascii; - -import org.apache.causeway.core.metamodel.facetapi.Facet; - -public interface AsciiFacet -extends - Facet { - - String asciiId(); - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacetAbstract.java deleted file mode 100644 index 41be0c0268..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacetAbstract.java +++ /dev/null @@ -1,48 +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.facets.all.ascii; - -import org.apache.causeway.core.metamodel.facetapi.FacetAbstract; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; - -/** - * @since 2.0 - */ -public abstract class AsciiFacetAbstract -extends FacetAbstract -implements AsciiFacet { - - private final String asciiId; - - public static final Class<AsciiFacet> type() { - return AsciiFacet.class; - } - - protected AsciiFacetAbstract( - final String asciiId, - final FacetHolder holder) { - super(type(), holder, Precedence.DEFAULT); - this.asciiId = asciiId; - } - - @Override - public String asciiId() { - return asciiId; - } -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java index b5ae00f2f3..08d8c629b4 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java @@ -32,7 +32,6 @@ import org.apache.causeway.core.metamodel.facets.FacetedMethod; import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; import org.apache.causeway.core.metamodel.facets.actions.contributing.ContributingFacetAbstract; import org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacetAbstract; -import org.apache.causeway.core.metamodel.facets.collections.collection.ascii.AsciiFacetForCollectionAnnotation; import org.apache.causeway.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacet; import org.apache.causeway.core.metamodel.facets.collections.collection.typeof.TypeOfFacetForCollectionAnnotation; import org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; @@ -61,7 +60,6 @@ extends FacetFactoryAbstract { processDomainEvent(processMethodContext, collectionIfAny); processTypeOf(processMethodContext, collectionIfAny); - processAsciiName(processMethodContext, collectionIfAny); } Optional<Collection> collectionIfAny(final ProcessMethodContext processMethodContext) { @@ -124,14 +122,5 @@ extends FacetFactoryAbstract { }); } - void processAsciiName(final ProcessMethodContext processMethodContext, final Optional<Collection> collectionIfAny) { - - val holder = processMethodContext.getFacetHolder(); - - // check for @Collection(asciiId=...) - addFacetIfPresent( - AsciiFacetForCollectionAnnotation - .create(collectionIfAny, holder)); - } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/ascii/AsciiFacetForCollectionAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/ascii/AsciiFacetForCollectionAnnotation.java deleted file mode 100644 index b2b9da8a41..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/ascii/AsciiFacetForCollectionAnnotation.java +++ /dev/null @@ -1,48 +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.facets.collections.collection.ascii; - -import java.util.Optional; - -import org.apache.causeway.applib.annotation.Collection; -import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.FacetedMethod; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract; - -public class AsciiFacetForCollectionAnnotation -extends AsciiFacetAbstract { - - public static Optional<AsciiFacet> create( - final Optional<Collection> collectionIfAny, - final FacetedMethod facetHolder) { - - return collectionIfAny - .map(Collection::asciiId) - .filter(_Strings::isNotEmpty) - .map(asciiId -> new AsciiFacetForCollectionAnnotation(asciiId, facetHolder)); - } - - private AsciiFacetForCollectionAnnotation( - final String value, final FacetHolder holder) { - super(value, holder); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/ascii/AsciiFacetForParameterAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/ascii/AsciiFacetForParameterAnnotation.java deleted file mode 100644 index c7d7f73d1f..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/ascii/AsciiFacetForParameterAnnotation.java +++ /dev/null @@ -1,47 +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.facets.param.ascii; - -import java.util.Optional; - -import org.apache.causeway.applib.annotation.Parameter; -import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract; - -public class AsciiFacetForParameterAnnotation -extends AsciiFacetAbstract { - - public static Optional<AsciiFacet> create( - final Optional<Parameter> collectionIfAny, - final FacetHolder facetHolder) { - - return collectionIfAny - .map(Parameter::asciiId) - .filter(_Strings::isNotEmpty) - .map(asciiId -> new AsciiFacetForParameterAnnotation(asciiId, facetHolder)); - } - - private AsciiFacetForParameterAnnotation( - final String value, final FacetHolder holder) { - super(value, holder); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java index 459a394ee6..d224e6f1f3 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java @@ -25,7 +25,6 @@ import org.apache.causeway.applib.annotation.Parameter; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; -import org.apache.causeway.core.metamodel.facets.param.ascii.AsciiFacetForParameterAnnotation; import org.apache.causeway.core.metamodel.facets.param.parameter.fileaccept.FileAcceptFacetForParameterAnnotation; import org.apache.causeway.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetForParameterAnnotation; import org.apache.causeway.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetInvertedByNullableAnnotationOnParameter; @@ -53,7 +52,6 @@ extends FacetFactoryAbstract { processParamsRegEx(processParameterContext); processParamsOptional(processParameterContext); processParamsFileAccept(processParameterContext); - processParamsAsciiId(processParameterContext); } // check for @Parameter(precedingParamsPolicy=...) @@ -134,16 +132,5 @@ extends FacetFactoryAbstract { .create(parameterIfAny, holder)); } - void processParamsAsciiId(final ProcessParameterContext processParameterContext) { - - val holder = processParameterContext.getFacetHolder(); - val parameterIfAny = processParameterContext.synthesizeOnParameter(Parameter.class); - - // check for @Parameter(asciiId=...) - addFacetIfPresent( - AsciiFacetForParameterAnnotation - .create(parameterIfAny, holder)); - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/ascii/AsciiFacetForPropertyAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/ascii/AsciiFacetForPropertyAnnotation.java deleted file mode 100644 index 9529053bdc..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/ascii/AsciiFacetForPropertyAnnotation.java +++ /dev/null @@ -1,48 +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.facets.properties.ascii; - -import java.util.Optional; - -import org.apache.causeway.applib.annotation.Property; -import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.FacetedMethod; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract; - -public class AsciiFacetForPropertyAnnotation -extends AsciiFacetAbstract { - - public static Optional<AsciiFacet> create( - final Optional<Property> collectionIfAny, - final FacetedMethod facetHolder) { - - return collectionIfAny - .map(Property::asciiId) - .filter(_Strings::isNotEmpty) - .map(asciiId -> new AsciiFacetForPropertyAnnotation(asciiId, facetHolder)); - } - - private AsciiFacetForPropertyAnnotation( - final String value, final FacetHolder holder) { - super(value, holder); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java index 9c9c395cfb..a83aace192 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java @@ -37,7 +37,6 @@ import org.apache.causeway.core.metamodel.facets.members.publish.command.Command import org.apache.causeway.core.metamodel.facets.members.publish.execution.ExecutionPublishingFacet; import org.apache.causeway.core.metamodel.facets.members.publish.execution.ExecutionPublishingFacetForPropertyAnnotation; import org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; -import org.apache.causeway.core.metamodel.facets.properties.ascii.AsciiFacetForPropertyAnnotation; import org.apache.causeway.core.metamodel.facets.properties.projection.ProjectingFacetFromPropertyAnnotation; import org.apache.causeway.core.metamodel.facets.properties.property.disabled.DisabledFacetForPropertyAnnotation; import org.apache.causeway.core.metamodel.facets.properties.property.entitychangepublishing.EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation; @@ -89,7 +88,6 @@ extends FacetFactoryAbstract { processOptional(processMethodContext, propertyIfAny); processRegEx(processMethodContext, propertyIfAny); processFileAccept(processMethodContext, propertyIfAny); - processAsciiName(processMethodContext, propertyIfAny); } Optional<Property> propertyIfAny(final ProcessMethodContext processMethodContext) { @@ -326,14 +324,4 @@ extends FacetFactoryAbstract { } - void processAsciiName(final ProcessMethodContext processMethodContext, final Optional<Property> propertyIfAny) { - - val holder = processMethodContext.getFacetHolder(); - - // check for @Property(asciiId=...) - addFacetIfPresent( - AsciiFacetForPropertyAnnotation - .create(propertyIfAny, holder)); - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectFeature.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectFeature.java index 939a4e0e74..d1cf61f080 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectFeature.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectFeature.java @@ -170,4 +170,5 @@ public interface ObjectFeature extends Specification { return !MandatoryFacet.isMandatory(this); } + String asciiId(); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionDefault.java index 40515a0a18..1462849174 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionDefault.java @@ -90,6 +90,11 @@ implements ObjectAction { return new ObjectActionDefault(facetedMethod.getFeatureIdentifier(), facetedMethod, true, false); } + @Override + public String asciiId() { + return getMetaModelContext().getAsciiIdentifierService().asciiIdFor(getId()); + } + /** * JUnit Support */ diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java index 74a5774ac2..afa404db87 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java @@ -103,6 +103,11 @@ implements return javaSourceParamName; } + @Override + public String asciiId() { + return getMetaModelContext().getAsciiIdentifierService().asciiIdFor(getId()); + } + @Override public final String getFriendlyName(final Supplier<ManagedObject> domainObjectProvider) { //as we don't support imperative naming for parameters yet .. @@ -382,6 +387,7 @@ implements return validResult.createConsent(); } + // -- CONTRACT @Override @@ -389,4 +395,5 @@ implements return String.format("ObjectActionParameter[id=%s]", getFeatureIdentifier()); } + } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java index 300ed8f46a..98220ba449 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java @@ -326,4 +326,9 @@ implements return getServiceRegistry().lookupServiceElseFail(CommandDtoFactory.class); } + @Override + public String asciiId() { + return getMetaModelContext().getAsciiIdentifierService().asciiIdFor(getId()); + } + } diff --git a/viewers/graphql/adoc/modules/ROOT/pages/i18n.adoc b/viewers/graphql/adoc/modules/ROOT/pages/i18n.adoc index 3559769d2a..ef31b47f03 100644 --- a/viewers/graphql/adoc/modules/ROOT/pages/i18n.adoc +++ b/viewers/graphql/adoc/modules/ROOT/pages/i18n.adoc @@ -3,12 +3,12 @@ :Notice: 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 ag [...] -The GraphQL Specification (link:https://spec.graphql.org/June2018/#sec-Names[]) requires that names of fields and types use only a subset of ASCII characters. +The GraphQL Specification (link:https://spec.graphql.org/October2021/#sec-Names[]) requires that names of fields and types use only a subset of ASCII characters. On the other hand the GraphQL viewer will infer these fields from the Java domain objects, which permits a wider range of characters. -To ensure that only permitted characters are used in the GraphQL model, use the xref:refguide:applib:index/annotation/Property.adoc#asciiId[@Property#asciiId], xref:refguide:applib:index/annotation/Collection.adoc#asciiId[@Collection#asciiId], xref:refguide:applib:index/annotation/Action.adoc#asciiId[@Action#asciiId] and xref:refguide:applib:index/annotation/Parameter.adoc#asciiId[@Parameter#asciiId]. +To ensure that only permitted characters are used in the GraphQL model, provide an implementation of the xref:refguide:applib:index/services/ascii/AsciiIdentifierService.adoc[AsciiIdentifierService]. -For example: +For example, suppose this class is part of the domain: [source,java] .I18nCalculator @@ -19,13 +19,28 @@ For example: @RequiredArgsConstructor(onConstructor_ = {@Inject}) public class I18nCalculator { - @Action(semantics = SemanticsOf.SAFE, asciiId = "concat") + @Action(semantics = SemanticsOf.SAFE) public String concät( - @Parameter(asciiId = "a1") String ä1, - @Parameter(asciiId = "a2") String ä2) { return ä1 + ä2; } } ---- + +As this service uses a non-ASCII character, `ä`, we need to provide a service to convert it: + +[source,java] +.AsciiIdentifierServiceSupportingGraphqlViewer +---- +@Service +public class AsciiIdentifierServiceSupportingGraphqlViewer + implements AsciiIdentifierService { + + public String asciiIdFor(String featureId) { + return featureId.replace("ä", "a"); + } +} +---- + +This implementation could be fairly easily be extended for other Latin languages, but non-Latin languages such as Kanji would obviously need a more sophisticated implementation. diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java index 9197026363..6b824e790d 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java @@ -31,6 +31,8 @@ import graphql.schema.GraphQLEnumType; import static graphql.schema.GraphQLEnumType.newEnum; import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition; +import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature; +import org.apache.causeway.core.metamodel.spec.feature.OneToOneActionParameter; import org.springframework.stereotype.Component; import org.apache.causeway.applib.id.HasLogicalType; @@ -121,5 +123,4 @@ public class Context { ) .build(); } - } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java index 7ea62fc73d..4fa5bf1e1f 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java @@ -64,7 +64,7 @@ public final class TypeNames { final ObjectSpecification owningType, final ObjectAction oa, final SchemaType schemaType) { - return objectTypeNameFor(owningType, schemaType) + "__" + ObjectFeatureUtils.asciiIdFor(oa) + "__gqlv_action"; + return objectTypeNameFor(owningType, schemaType) + "__" + oa.asciiId() + "__gqlv_action"; } public static String actionInvokeTypeNameFor( diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java index 6001d9fedf..c6f890a074 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java @@ -25,7 +25,6 @@ import java.util.stream.Collectors; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.commons.collections.Can; -import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -154,8 +153,7 @@ public class ObjectFeatureUtils { } public static String asciiIdFor(final ObjectFeature objectFeature) { - val asciiFacet = objectFeature.getFacet(AsciiFacet.class); - return asciiFacet != null ? asciiFacet.asciiId() : objectFeature.getId(); + return objectFeature.getId(); } private static ManagedObject adaptValue( diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java index ed65e8c24f..566c8d0734 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java @@ -284,7 +284,7 @@ public class SimpleAction final OneToOneActionParameter otoap, final TypeMapper.InputContext inputContext) { return GraphQLArgument.newArgument() - .name(ObjectFeatureUtils.asciiIdFor(otoap)) + .name(otoap.asciiId()) .type(context.typeMapper.inputTypeFor(otoap, inputContext, objectInteractor.getSchemaType())) .build(); } diff --git a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/AsciiIdentifierServiceSupportingGraphqlViewer.java b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/AsciiIdentifierServiceSupportingGraphqlViewer.java new file mode 100644 index 0000000000..0cb18bd068 --- /dev/null +++ b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/AsciiIdentifierServiceSupportingGraphqlViewer.java @@ -0,0 +1,13 @@ +package org.apache.causeway.viewer.graphql.viewer.test.domain.i18n; + +import org.apache.causeway.applib.services.ascii.AsciiIdentifierService; + +import org.springframework.stereotype.Service; + +@Service +public class AsciiIdentifierServiceSupportingGraphqlViewer implements AsciiIdentifierService { + @Override + public String asciiIdFor(String featureId) { + return featureId.replace("ä", "a"); + } +} diff --git a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/I18nCalculator.java b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/I18nCalculator.java index 4e4db46f22..f60aed3a5c 100644 --- a/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/I18nCalculator.java +++ b/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/domain/i18n/I18nCalculator.java @@ -19,11 +19,9 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor(onConstructor_ = {@Inject}) public class I18nCalculator { - @Action(semantics = SemanticsOf.SAFE, asciiId = "concat") + @Action(semantics = SemanticsOf.SAFE) public String concät( - @Parameter(asciiId = "a1") String ä1, - @Parameter(asciiId = "a2") String ä2) { return ä1 + ä2; }
