Skip to content

Commit

Permalink
Ignore underscores on Java fields and setters when resolving instanti…
Browse files Browse the repository at this point in the history
…ators. (Fixes #3)
  • Loading branch information
komu committed May 4, 2015
1 parent c0a2b52 commit 8d380c8
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.0.0-alpha.2 (yyyy-mm-dd)

- Ignore underscores on Java fields and setters when resolving instantiators. (Fixes [#3](https://github.com/EvidentSolutions/dalesbred/issues/3))

## 1.0.0-alpha.1 (2015-05-02)

First alpha for 1.0 -version of Dalesbred. This is not source compatible with previous versions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.regex.Pattern;

import static java.lang.reflect.Modifier.isPublic;
import static org.dalesbred.internal.utils.StringUtils.isEqualIgnoringCaseAndUnderscores;

abstract class PropertyAccessor {

Expand All @@ -45,13 +46,12 @@ abstract class PropertyAccessor {

@NotNull
static Optional<PropertyAccessor> findAccessor(@NotNull Class<?> cl, @NotNull String name) {
String normalizedName = UNDERSCORE.matcher(name).replaceAll("");
Optional<PropertyAccessor> setter = findSetter(cl, normalizedName).map(SetterPropertyAccessor::new);
Optional<PropertyAccessor> setter = findSetter(cl, name).map(SetterPropertyAccessor::new);

if (setter.isPresent()) {
return setter;
} else {
return findField(cl, normalizedName).map(FieldPropertyAccessor::new);
return findField(cl, name).map(FieldPropertyAccessor::new);
}
}

Expand All @@ -60,7 +60,7 @@ private static Optional<Field> findField(@NotNull Class<?> cl, @NotNull String n
Field result = null;

for (Field field : cl.getFields())
if (isPublic(field.getModifiers()) && field.getName().equalsIgnoreCase(name) && !field.isAnnotationPresent(DalesbredIgnore.class)) {
if (isPublic(field.getModifiers()) && isEqualIgnoringCaseAndUnderscores(name, field.getName()) && !field.isAnnotationPresent(DalesbredIgnore.class)) {
if (result != null)
throw new InstantiationException("Conflicting fields for property: " + result + " - " + name);
result = field;
Expand All @@ -75,7 +75,8 @@ private static Optional<Method> findSetter(@NotNull Class<?> cl, @NotNull String

String methodName = "set" + name;
for (Method method : cl.getMethods()) {
if (isPublic(method.getModifiers()) && methodName.equalsIgnoreCase(method.getName()) && method.getParameterTypes().length == 1 && !method.isAnnotationPresent(DalesbredIgnore.class)) {

if (isPublic(method.getModifiers()) && isEqualIgnoringCaseAndUnderscores(methodName, method.getName()) && method.getParameterTypes().length == 1 && !method.isAnnotationPresent(DalesbredIgnore.class)) {
if (result != null)
throw new InstantiationException("Conflicting setters for property: " + result + " - " + name);
result = method;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,35 @@ public static String upperCamelToLowerUnderscore(@NotNull CharSequence cs) {
public static String capitalize(@NotNull String s) {
return s.isEmpty() ? s : (toUpperCase(s.charAt(0)) + s.substring(1));
}

/**
* Returns true if two strings are equal, apart from case differences and underscores.
* Underscores in both sides are totally ignored.
*/
public static boolean isEqualIgnoringCaseAndUnderscores(@NotNull String s1, @NotNull String s2) {
int index1 = 0;
int index2 = 0;
int length1 = s1.length();
int length2 = s2.length();

while (index1 < length1 && index2 < length2) {
char nameChar = s1.charAt(index1++);
if (nameChar == '_') continue;

char memberNameChar = s2.charAt(index2++);
if (memberNameChar == '_') {
index1--;
continue;
}

if (toLowerCase(nameChar) != toLowerCase(memberNameChar))
return false;
}

// Skip trailing underscores
while (index1 < length1 && s1.charAt(index1) == '_') index1++;
while (index2 < length2 && s2.charAt(index2) == '_') index2++;

return index1 == length1 && index2 == length2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ public void setterBindingNullValuesAndConversions() {
assertThat(result.getDateTime(), is(nullValue()));
}

@Test
public void fieldsWithUnderscores() {
ClassWithUnderscoreFields result = db.findUnique(ClassWithUnderscoreFields.class, "select 'Fred' as first_name from (values (1))");
assertThat(result.first_name, is("Fred"));
}

@Test
public void settersWithUnderscores() {
ClassWithUnderscoreSetters result = db.findUnique(ClassWithUnderscoreSetters.class, "select 'Fred' as first_name from (values (1))");
assertThat(result.first_name, is("Fred"));
}

public static class MyResult {
public final int constructor;

Expand Down Expand Up @@ -121,4 +133,21 @@ public void setDateTime(DateTime dateTime) {
this.dateTime = dateTime;
}
}

public static class ClassWithUnderscoreFields {

@SuppressWarnings("InstanceVariableNamingConvention")
public String first_name;
}

@SuppressWarnings("InstanceVariableNamingConvention")
public static class ClassWithUnderscoreSetters {

private String first_name;

@Reflective
public void setFirst_name(String firstName) {
this.first_name = firstName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@

import org.junit.Test;

import static org.dalesbred.internal.utils.StringUtils.capitalize;
import static org.dalesbred.internal.utils.StringUtils.upperCamelToLowerUnderscore;
import static org.dalesbred.internal.utils.StringUtils.*;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

Expand Down Expand Up @@ -71,4 +70,20 @@ public void capitalization() {
assertThat(capitalize("foo"), is("Foo"));
assertThat(capitalize("fooBar"), is("FooBar"));
}

@Test
public void caseAndUnderscoreIgnoringEquality() {
assertThat(isEqualIgnoringCaseAndUnderscores("", ""), is(true));
assertThat(isEqualIgnoringCaseAndUnderscores("foo", "foo"), is(true));
assertThat(isEqualIgnoringCaseAndUnderscores("foo", "bar"), is(false));

assertThat(isEqualIgnoringCaseAndUnderscores("foo", "FOo"), is(true));
assertThat(isEqualIgnoringCaseAndUnderscores("Foo", "FOo"), is(true));

assertThat(isEqualIgnoringCaseAndUnderscores("Foo_bar", "FOoBar"), is(true));
assertThat(isEqualIgnoringCaseAndUnderscores("Foobar", "FOo_Bar"), is(true));

assertThat(isEqualIgnoringCaseAndUnderscores("_foo_", "foo"), is(true));
assertThat(isEqualIgnoringCaseAndUnderscores("foo", "__foo__"), is(true));
}
}

0 comments on commit 8d380c8

Please sign in to comment.