From 7b204b17046459295406c1dac3929fee210f0772 Mon Sep 17 00:00:00 2001 From: nirbhay mishra Date: Sun, 20 Nov 2022 18:24:35 +0530 Subject: [PATCH 1/2] Handle Unicode in Project Generation This commit replaces characters with accents with their US-ascii counterpart. See gh-1345 --- ...ltProjectRequestToDescriptionConverter.java | 18 ++++++++++++++---- ...ationControllerArchiveIntegrationTests.java | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java b/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java index 32056130..078239b2 100644 --- a/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java +++ b/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java @@ -16,6 +16,7 @@ package io.spring.initializr.web.project; +import java.text.Normalizer; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -34,6 +35,7 @@ import io.spring.initializr.metadata.Type; import io.spring.initializr.metadata.support.MetadataBuildItemMapper; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * A default {@link ProjectRequestToDescriptionConverter} implementation that uses the @@ -44,6 +46,7 @@ import org.springframework.util.Assert; * @author Madhura Bhave * @author HaiTao Zhang * @author Stephane Nicoll + * @author Nirbhay Mishra */ public class DefaultProjectRequestToDescriptionConverter implements ProjectRequestToDescriptionConverter { @@ -82,14 +85,14 @@ public class DefaultProjectRequestToDescriptionConverter validateDependencyRange(platformVersion, resolvedDependencies); description.setApplicationName(request.getApplicationName()); - description.setArtifactId(request.getArtifactId()); + description.setArtifactId(cleanInputValue(request.getArtifactId())); description.setBaseDirectory(request.getBaseDir()); description.setBuildSystem(getBuildSystem(request, metadata)); description.setDescription(request.getDescription()); - description.setGroupId(request.getGroupId()); + description.setGroupId(cleanInputValue(request.getGroupId())); description.setLanguage(Language.forId(request.getLanguage(), request.getJavaVersion())); - description.setName(request.getName()); - description.setPackageName(request.getPackageName()); + description.setName(cleanInputValue(request.getName())); + description.setPackageName(cleanInputValue(request.getPackageName())); description.setPackaging(Packaging.forId(request.getPackaging())); description.setPlatformVersion(platformVersion); description.setVersion(request.getVersion()); @@ -188,4 +191,11 @@ public class DefaultProjectRequestToDescriptionConverter }).collect(Collectors.toList()); } + private String cleanInputValue(String inputString) { + if (StringUtils.hasText(inputString)) { + return Normalizer.normalize(inputString, Normalizer.Form.NFKD).replaceAll("\\p{M}", ""); + } + return inputString; + } + } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java index aee39762..2d4be961 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java @@ -36,4 +36,10 @@ public class ProjectGenerationControllerArchiveIntegrationTests extends Abstract assertDefaultProject(project.resolveModule("demo trial")); } + @Test + void projectNameWithAccentRemoved() { + ProjectStructure project = downloadZip("/starter.zip?artifactId=demo&baseDir=demo trial&name=Demö"); + assertDefaultProject(project.resolveModule("demo trial")); + } + } From ade3b0af9e213f8c5599346a4cf5055996bffc28 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 24 Nov 2022 11:24:40 +0100 Subject: [PATCH 2/2] Polish "Handle Unicode in Project Generation" See gh-1345 --- ...tProjectRequestToDescriptionConverter.java | 17 ++++++---- ...tionControllerArchiveIntegrationTests.java | 6 ---- ...ectRequestToDescriptionConverterTests.java | 32 +++++++++++++++++++ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java b/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java index 078239b2..6e4c0533 100644 --- a/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java +++ b/initializr-web/src/main/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverter.java @@ -100,6 +100,16 @@ public class DefaultProjectRequestToDescriptionConverter MetadataBuildItemMapper.toDependency(dependency))); } + /** + * Clean input value to rely on US-ascii character as much as possible. + * @param value the input value to clean + * @return a value that can be used as part of an identifier + */ + protected String cleanInputValue(String value) { + return StringUtils.hasText(value) ? Normalizer.normalize(value, Normalizer.Form.NFKD).replaceAll("\\p{M}", "") + : value; + } + private void validate(ProjectRequest request, InitializrMetadata metadata) { validatePlatformVersion(request, metadata); validateType(request.getType(), metadata); @@ -191,11 +201,4 @@ public class DefaultProjectRequestToDescriptionConverter }).collect(Collectors.toList()); } - private String cleanInputValue(String inputString) { - if (StringUtils.hasText(inputString)) { - return Normalizer.normalize(inputString, Normalizer.Form.NFKD).replaceAll("\\p{M}", ""); - } - return inputString; - } - } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java index 2d4be961..aee39762 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/ProjectGenerationControllerArchiveIntegrationTests.java @@ -36,10 +36,4 @@ public class ProjectGenerationControllerArchiveIntegrationTests extends Abstract assertDefaultProject(project.resolveModule("demo trial")); } - @Test - void projectNameWithAccentRemoved() { - ProjectStructure project = downloadZip("/starter.zip?artifactId=demo&baseDir=demo trial&name=Demö"); - assertDefaultProject(project.resolveModule("demo trial")); - } - } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverterTests.java b/initializr-web/src/test/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverterTests.java index f942013d..4444ccb8 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverterTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/project/DefaultProjectRequestToDescriptionConverterTests.java @@ -47,6 +47,38 @@ class DefaultProjectRequestToDescriptionConverterTests { private final DefaultProjectRequestToDescriptionConverter converter = new DefaultProjectRequestToDescriptionConverter(); + @Test + void convertWhenArtifactIdHasAccentCleanValue() { + ProjectRequest request = createProjectRequest(); + request.setArtifactId("tëst-âpp"); + ProjectDescription description = this.converter.convert(request, this.metadata); + assertThat(description.getArtifactId()).isEqualTo("test-app"); + } + + @Test + void convertWhenGroupIdHasAccentCleanValue() { + ProjectRequest request = createProjectRequest(); + request.setGroupId("com.êxample.äpp"); + ProjectDescription description = this.converter.convert(request, this.metadata); + assertThat(description.getGroupId()).isEqualTo("com.example.app"); + } + + @Test + void convertWhenNameHasAccentCleanValue() { + ProjectRequest request = createProjectRequest(); + request.setName("My Demö"); + ProjectDescription description = this.converter.convert(request, this.metadata); + assertThat(description.getName()).isEqualTo("My Demo"); + } + + @Test + void convertWhenPackageNameHasAccentCleanValue() { + ProjectRequest request = createProjectRequest(); + request.setPackageName("com.êxample.äpp"); + ProjectDescription description = this.converter.convert(request, this.metadata); + assertThat(description.getPackageName()).isEqualTo("com.example.app"); + } + @Test void convertWhenTypeIsInvalidShouldThrowException() { ProjectRequest request = createProjectRequest();