diff --git a/initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy b/initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy index 5807c511..008d6f36 100644 --- a/initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy +++ b/initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy @@ -92,8 +92,7 @@ class CommandLineHelpGenerator { defaults[it.key] = it.value } } - defaults['applicationName'] = ProjectRequest.generateApplicationName(metadata.defaults.name, - ProjectRequest.DEFAULT_APPLICATION_NAME) + defaults['applicationName'] = metadata.generateApplicationName(metadata.defaults.name) defaults['baseDir'] = 'no base dir' defaults['dependencies'] = 'none' diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy b/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy index 4271e393..1df6b411 100644 --- a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy +++ b/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy @@ -102,6 +102,34 @@ class InitializrMetadata { "$defaults.bootVersion/spring-boot-cli-$defaults.bootVersion-bin.$extension" } + /** + * Generate a suitable application mame based on the specified name. If no suitable + * application name can be generated from the specified {@code name}, the + * {@link Env#fallbackApplicationName} is used instead. + *

No suitable application name can be generated if the name is {@code null} or + * if it contains an invalid character for a class identifier. + * @see Env#fallbackApplicationName + * @see Env#invalidApplicationNames + */ + String generateApplicationName(String name) { + if (!name) { + return env.fallbackApplicationName + } + String text = splitCamelCase(name.trim()) + String result = text.replaceAll("(_|-| |:)+([A-Za-z0-9])", { Object[] it -> + it[2].toUpperCase() + }) + if (!result.endsWith('Application')) { + result += 'Application' + } + String candidate = result.capitalize(); + if (hasInvalidChar(candidate) || env.invalidApplicationNames.contains(candidate)) { + return env.fallbackApplicationName + } else { + return candidate + } + } + /** * Initializes a {@link ProjectRequest} instance with the defaults * defined in this instance. @@ -223,6 +251,27 @@ class InitializrMetadata { } } + private static String splitCamelCase(String text) { + text.split('(? 1) { + for (int i = 1; i < text.length(); i++) { + if (!Character.isJavaIdentifierPart(text.charAt(i))) { + return true + } + } + } + return false + } + static class DependencyGroup { String name @@ -359,6 +408,17 @@ class InitializrMetadata { String springBootMetadataUrl = 'https://spring.io/project_metadata/spring-boot' + /** + * The application name to use if none could be generated. + */ + String fallbackApplicationName = 'Application' + + /** + * The list of invalid application names. If such name is chosen or generated, + * the {@link #fallbackApplicationName} should be used instead. + */ + List invalidApplicationNames = ['SpringApplication', 'SpringBootApplication'] + boolean forceSsl = true void validate() { diff --git a/initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy b/initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy index 737b5321..101b20c4 100644 --- a/initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy +++ b/initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,11 +35,6 @@ class ProjectRequest { */ static final DEFAULT_STARTER = 'root_starter' - /** - * The default name of the application class. - */ - static final String DEFAULT_APPLICATION_NAME = 'Application' - List style = [] List dependencies = [] String name @@ -110,7 +105,7 @@ class ProjectRequest { } if (!applicationName) { - this.applicationName = generateApplicationName(this.name, DEFAULT_APPLICATION_NAME) + this.applicationName = metadata.generateApplicationName(this.name) } afterResolution(metadata) @@ -155,51 +150,4 @@ class ProjectRequest { facets.contains(facet) } - /** - * Generate a suitable application mame based on the specified name. If no suitable - * application name can be generated from the specified {@code name}, the - * {@code defaultApplicationName} is used instead. - *

No suitable application name can be generated if the name is {@code null} or - * if it contains an invalid character for a class identifier. - */ - static String generateApplicationName(String name, String defaultApplicationName) { - if (!name) { - return defaultApplicationName - } - String text = splitCamelCase(name.trim()) - String result = text.replaceAll("(_|-| |:)+([A-Za-z0-9])", { Object[] it -> - it[2].toUpperCase() - }) - if (!result.endsWith('Application')) { - result += 'Application' - } - String candidate = result.capitalize(); - if (hasInvalidChar(candidate)) { - return defaultApplicationName - } else { - return candidate - } - } - - private static String splitCamelCase(String text) { - text.split('(? 1) { - for (int i = 1; i < text.length(); i++) { - if (!Character.isJavaIdentifierPart(text.charAt(i))) { - return true - } - } - } - return false - } - } diff --git a/initializr/src/test/groovy/io/spring/initializr/InitializrMetadataTests.groovy b/initializr/src/test/groovy/io/spring/initializr/InitializrMetadataTests.groovy index 932d8472..9deef4ee 100644 --- a/initializr/src/test/groovy/io/spring/initializr/InitializrMetadataTests.groovy +++ b/initializr/src/test/groovy/io/spring/initializr/InitializrMetadataTests.groovy @@ -230,6 +230,81 @@ class InitializrMetadataTests { assertEquals 'two', InitializrMetadata.getDefault(elements) } + @Test + void generateApplicationNameSimple() { + assertEquals 'DemoApplication', this.metadata.generateApplicationName('demo') + } + + @Test + void generateApplicationNameSimpleApplication() { + assertEquals 'DemoApplication', this.metadata.generateApplicationName('demoApplication') + } + + @Test + void generateApplicationNameSimpleCamelCase() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('myDemo') + } + + @Test + void generateApplicationNameSimpleUnderscore() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('my_demo') + } + + @Test + void generateApplicationNameSimpleColon() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('my:demo') + } + + @Test + void generateApplicationNameSimpleSpace() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('my demo') + } + + @Test + void generateApplicationNamSsimpleDash() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('my-demo') + } + + @Test + void generateApplicationNameUpperCaseUnderscore() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('MY_DEMO') + } + + @Test + void generateApplicationNameUpperCaseDash() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName('MY-DEMO') + } + + @Test + void generateApplicationNameMultiSpaces() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName(' my demo ') + } + + @Test + void generateApplicationNameMultiSpacesUpperCase() { + assertEquals 'MyDemoApplication', this.metadata.generateApplicationName(' MY DEMO ') + } + + @Test + void generateApplicationNameInvalidStartCharacter() { + assertEquals this.metadata.env.fallbackApplicationName, this.metadata.generateApplicationName('1MyDemo') + } + + @Test + void generateApplicationNameInvalidPartCharacter() { + assertEquals this.metadata.env.fallbackApplicationName, this.metadata.generateApplicationName('MyDe|mo') + } + + @Test + void generateApplicationNameInvalidApplicationName() { + assertEquals this.metadata.env.fallbackApplicationName, this.metadata.generateApplicationName('SpringBoot') + } + + @Test + void generateApplicationNameAnotherInvalidApplicationName() { + assertEquals this.metadata.env.fallbackApplicationName, this.metadata.generateApplicationName('Spring') + } + private static ProjectRequest doCreateProjectRequest(InitializrMetadata metadata) { def request = new ProjectRequest() metadata.initializeProjectRequest(request) diff --git a/initializr/src/test/groovy/io/spring/initializr/ProjectRequestTests.groovy b/initializr/src/test/groovy/io/spring/initializr/ProjectRequestTests.groovy index 8762f839..2166ce17 100644 --- a/initializr/src/test/groovy/io/spring/initializr/ProjectRequestTests.groovy +++ b/initializr/src/test/groovy/io/spring/initializr/ProjectRequestTests.groovy @@ -166,7 +166,7 @@ class ProjectRequestTests { def metadata = InitializrMetadataBuilder.withDefaults().validateAndGet() request.resolve(metadata) - assertEquals ProjectRequest.DEFAULT_APPLICATION_NAME, request.applicationName + assertEquals metadata.env.fallbackApplicationName, request.applicationName } @Test @@ -190,74 +190,6 @@ class ProjectRequestTests { assertEquals 'MyApplicationName', request.applicationName } - @Test - void generateApplicationNameSimple() { - assertEquals 'DemoApplication', generateApplicationName('demo') - } - - @Test - void generateApplicationNameSimpleApplication() { - assertEquals 'DemoApplication', generateApplicationName('demoApplication') - } - - @Test - void generateApplicationNameSimpleCamelCase() { - assertEquals 'MyDemoApplication', generateApplicationName('myDemo') - } - - @Test - void generateApplicationNameSimpleUnderscore() { - assertEquals 'MyDemoApplication', generateApplicationName('my_demo') - } - - @Test - void generateApplicationNameSimpleColon() { - assertEquals 'MyDemoApplication', generateApplicationName('my:demo') - } - - @Test - void generateApplicationNameSimpleSpace() { - assertEquals 'MyDemoApplication', generateApplicationName('my demo') - } - - @Test - void generateApplicationNamSsimpleDash() { - assertEquals 'MyDemoApplication', generateApplicationName('my-demo') - } - - @Test - void generateApplicationNameUpperCaseUnderscore() { - assertEquals 'MyDemoApplication', generateApplicationName('MY_DEMO') - } - - @Test - void generateApplicationNameUpperCaseDash() { - assertEquals 'MyDemoApplication', generateApplicationName('MY-DEMO') - } - - @Test - void generateApplicationNameMultiSpaces() { - assertEquals 'MyDemoApplication', generateApplicationName(' my demo ') - } - - @Test - void generateApplicationNameMultiSpacesUpperCase() { - assertEquals 'MyDemoApplication', generateApplicationName(' MY DEMO ') - } - - @Test - void generateApplicationNameInvalidStartCharacter() { - assertEquals DEFAULT_APPLICATION_NAME, generateApplicationName('1MyDemo') - } - - @Test - void generateApplicationNameInvalidPartCharacter() { - assertEquals DEFAULT_APPLICATION_NAME, generateApplicationName('MyDe|mo') - } - - private static generateApplicationName(String text) { - ProjectRequest.generateApplicationName(text, DEFAULT_APPLICATION_NAME) - } private static void assertBootStarter(InitializrMetadata.Dependency actual, String name) { def expected = new InitializrMetadata.Dependency() diff --git a/initializr/src/test/groovy/io/spring/initializr/web/MainControllerEnvIntegrationTests.groovy b/initializr/src/test/groovy/io/spring/initializr/web/MainControllerEnvIntegrationTests.groovy index 504faa5b..75379db7 100644 --- a/initializr/src/test/groovy/io/spring/initializr/web/MainControllerEnvIntegrationTests.groovy +++ b/initializr/src/test/groovy/io/spring/initializr/web/MainControllerEnvIntegrationTests.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,4 +44,15 @@ class MainControllerEnvIntegrationTests extends AbstractInitializrControllerInte assertTrue "Force SSL should be disabled", body.contains("http://localhost:$port/install.sh") } + @Test + void generateProjectWithInvalidName() { + downloadZip('/starter.zip?style=data-jpa&name=Invalid') + .isJavaProject('FooBarApplication') + .isMavenProject() + .hasStaticAndTemplatesResources(false).pomAssert() + .hasDependenciesCount(2) + .hasSpringBootStarterDependency('data-jpa') + .hasSpringBootStarterDependency('test') + } + } diff --git a/initializr/src/test/resources/application-test-custom-env.yml b/initializr/src/test/resources/application-test-custom-env.yml index aaace38d..ddce24a7 100644 --- a/initializr/src/test/resources/application-test-custom-env.yml +++ b/initializr/src/test/resources/application-test-custom-env.yml @@ -1,4 +1,7 @@ initializr: env: artifactRepository: https://repo.spring.io/lib-release - forceSsl: false \ No newline at end of file + forceSsl: false + fallbackApplicationName: FooBarApplication + invalidApplicationNames: + - InvalidApplication \ No newline at end of file