diff --git a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java index 40ec2df61f..6940df604c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java +++ b/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedNames.java @@ -17,7 +17,8 @@ package org.springframework.boot.bind; import java.util.Iterator; -import java.util.NoSuchElementException; +import java.util.LinkedHashSet; +import java.util.Set; import org.springframework.util.StringUtils; @@ -33,6 +34,8 @@ public final class RelaxedNames implements Iterable { private final String name; + private Set values = new LinkedHashSet(); + /** * Create a new {@link RelaxedNames} instance. * @@ -41,45 +44,27 @@ public final class RelaxedNames implements Iterable { */ public RelaxedNames(String name) { this.name = name; + initialize(RelaxedNames.this.name, this.values); } @Override public Iterator iterator() { - return new RelaxedNamesIterator(); + return this.values.iterator(); } - private class RelaxedNamesIterator implements Iterator { - - private int variation = 0; - - private int manipulation = 0; - - @Override - public boolean hasNext() { - return (this.variation < Variation.values().length); + private void initialize(String name, Set values) { + if (values.contains(name)) { + return; } - - @Override - public String next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - String result = RelaxedNames.this.name; - result = Manipulation.values()[this.manipulation].apply(result); - result = Variation.values()[this.variation].apply(result); - this.manipulation++; - if (this.manipulation >= Manipulation.values().length) { - this.variation++; - this.manipulation = 0; + for (Variation variation : Variation.values()) { + for (Manipulation manipulation : Manipulation.values()) { + String result = name; + result = manipulation.apply(result); + result = variation.apply(result); + values.add(result); + initialize(result, values); } - return result; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); } - } static enum Variation { @@ -118,6 +103,22 @@ public final class RelaxedNames implements Iterable { return value.replace("-", "_"); } }, + UNCAMELCASE { + @Override + public String apply(String value) { + value = value.replaceAll("([^A-Z-])([A-Z])", "$1_$2"); + StringBuilder builder = new StringBuilder(); + for (String field : value.split("_")) { + if (builder.length() == 0) { + builder.append(field); + } + else { + builder.append("_").append(StringUtils.uncapitalize(field)); + } + } + return builder.toString(); + } + }, CAMELCASE { @Override public String apply(String value) { diff --git a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java index 458ae77bfc..6d99910a5b 100644 --- a/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/bind/RelaxedNamesTests.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertThat; * Tests for {@link RelaxedNames}. * * @author Phillip Webb + * @author Dave Syer */ public class RelaxedNamesTests { @@ -43,18 +44,36 @@ public class RelaxedNamesTests { assertThat(iterator.next(), equalTo("MY_RELAXED_PROPERTY")); assertThat(iterator.next(), equalTo("MYRELAXEDPROPERTY")); assertThat(iterator.hasNext(), equalTo(false)); + } - iterator = new RelaxedNames("nes_ted").iterator(); - assertThat(iterator.next(), equalTo("nes_ted")); + @Test + public void fromUnderscores() throws Exception { + Iterator iterator = new RelaxedNames("nes_ted").iterator(); assertThat(iterator.next(), equalTo("nes_ted")); assertThat(iterator.next(), equalTo("nesTed")); - assertThat(iterator.next(), equalTo("nes_ted")); - assertThat(iterator.next(), equalTo("nes_ted")); assertThat(iterator.next(), equalTo("nested")); assertThat(iterator.next(), equalTo("NES_TED")); - assertThat(iterator.next(), equalTo("NES_TED")); assertThat(iterator.next(), equalTo("NESTED")); assertThat(iterator.hasNext(), equalTo(false)); } + @Test + public void fromPlain() throws Exception { + Iterator iterator = new RelaxedNames("plain").iterator(); + assertThat(iterator.next(), equalTo("plain")); + assertThat(iterator.next(), equalTo("PLAIN")); + assertThat(iterator.hasNext(), equalTo(false)); + } + + @Test + public void fromCamelCase() throws Exception { + Iterator iterator = new RelaxedNames("caMel").iterator(); + assertThat(iterator.next(), equalTo("caMel")); + assertThat(iterator.next(), equalTo("ca_mel")); + assertThat(iterator.next(), equalTo("camel")); + assertThat(iterator.next(), equalTo("CAMEL")); + assertThat(iterator.next(), equalTo("CA_MEL")); + assertThat(iterator.hasNext(), equalTo(false)); + } + }