Skip to content

Commit 883b6db

Browse files
committed
Put java names directly in maps instead of transformation yaml to java each time
1 parent 34f7f11 commit 883b6db

File tree

2 files changed

+57
-18
lines changed

2 files changed

+57
-18
lines changed

src/main/java/net/datafaker/service/FakeValues.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import java.nio.file.Files;
88
import java.nio.file.Path;
99
import java.util.Arrays;
10+
import java.util.HashSet;
1011
import java.util.List;
1112
import java.util.Locale;
1213
import java.util.Map;
1314
import java.util.Objects;
15+
import java.util.Set;
1416
import java.util.logging.Level;
1517
import java.util.logging.Logger;
1618

@@ -98,9 +100,11 @@ private Map<String, Object> loadValues() {
98100
try (InputStream stream = getClass().getResourceAsStream(path)) {
99101
if (stream != null) {
100102
result = readFromStream(stream);
103+
enrichMapWithJavaNames(result);
101104
} else {
102105
try (InputStream stream2 = getClass().getClassLoader().getResourceAsStream(path)) {
103106
result = readFromStream(stream2);
107+
enrichMapWithJavaNames(result);
104108
} catch (Exception e) {
105109
LOG.log(Level.SEVERE, "Exception: ", e);
106110
}
@@ -116,6 +120,40 @@ private Map<String, Object> loadValues() {
116120
return null;
117121
}
118122

123+
private void enrichMapWithJavaNames(Map<String, Object> result) {
124+
if (result != null) {
125+
Set<String> set = new HashSet<>();
126+
for (Map.Entry<String, Object> entry : result.entrySet()) {
127+
final String key = entry.getKey();
128+
if (key.indexOf('_') != -1) {
129+
set.add(key);
130+
}
131+
}
132+
for (String str: set) {
133+
result.put(toJavaNames(str), result.get(str));
134+
}
135+
}
136+
}
137+
138+
private static String toJavaNames(String string) {
139+
if (string == null || string.isEmpty()) {
140+
return string;
141+
}
142+
StringBuilder res = new StringBuilder(string.length());
143+
for (int i = 0; i < string.length(); i++) {
144+
char c = string.charAt(i);
145+
if (i == 0 && Character.isLetter(c)) {
146+
res.append(Character.toUpperCase(c));
147+
} else if (c == '_' && i < string.length() + 1 && Character.isLetter(string.charAt(i + 1))) {
148+
res.append(Character.toUpperCase(string.charAt(i + 1)));
149+
i++;
150+
} else {
151+
res.append(c);
152+
}
153+
}
154+
return res.toString();
155+
}
156+
119157
private Map<String, Object> readFromStream(InputStream stream) {
120158
if (stream == null) return null;
121159
final Map<String, Object> valuesMap = new Yaml().loadAs(stream, Map.class);

src/main/java/net/datafaker/service/FakeValuesService.java

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -630,14 +630,15 @@ private static List<String> splitExpressions(String expression) {
630630
private Object resolveExpression(String directive, String[] args, Object current, Faker root) {
631631
// name.name (resolve locally)
632632
// Name.first_name (resolve to faker.name().firstName())
633-
final String simpleDirective = (isDotDirective(directive) || current == null)
633+
final boolean dotDirective = isDotDirective(directive);
634+
final String simpleDirective = (dotDirective || current == null)
634635
? directive
635636
: classNameToYamlName(current) + "." + directive;
636637

637638
Object resolved;
638639
// resolve method references on CURRENT object like #{number_between '1','10'} on Number or
639640
// #{ssn_valid} on IdNumber
640-
if (!isDotDirective(directive)) {
641+
if (!dotDirective) {
641642
Supplier<Object> supplier = resolveFromMethodOn(current, directive, args);
642643
if (supplier != null && (resolved = supplier.get()) != null) {
643644
//expression2function.put(expression, supplier);
@@ -656,7 +657,7 @@ private Object resolveExpression(String directive, String[] args, Object current
656657
}
657658

658659
// resolve method references on faker object like #{regexify '[a-z]'}
659-
if (!isDotDirective(directive)) {
660+
if (!dotDirective) {
660661
supplier = resolveFromMethodOn(root, directive, args);
661662
if (supplier != null && (resolved = supplier.get()) != null) {
662663
// expression2function.put(expression, supplier);
@@ -665,7 +666,7 @@ private Object resolveExpression(String directive, String[] args, Object current
665666
}
666667

667668
// Resolve Faker Object method references like #{ClassName.method_name}
668-
if (isDotDirective(directive)) {
669+
if (dotDirective) {
669670
supplier = resolveFakerObjectAndMethod(root, directive, args);
670671
if (supplier != null && (resolved = supplier.get()) != null) {
671672
// expression2function.put(expression, supplier);
@@ -678,8 +679,8 @@ private Object resolveExpression(String directive, String[] args, Object current
678679
// thru the normal resolution above, but if we will can't resolve it, we once again do a 'safeFetch' as we
679680
// did first but FIRST we change the Object reference Class.method_name with a yml style internal reference ->
680681
// class.method_name (lowercase)
681-
if (isDotDirective(directive)) {
682-
supplier = () -> safeFetch(javaNameToYamlName(simpleDirective), null);
682+
if (dotDirective) {
683+
supplier = () -> safeFetch(directive, null);
683684
resolved = supplier.get();
684685
}
685686

@@ -706,7 +707,7 @@ private String trimRegexSlashes(String slashDelimitedRegex) {
706707
}
707708

708709
private boolean isDotDirective(String directive) {
709-
return directive.contains(".");
710+
return directive.indexOf('.') != -1;
710711
}
711712

712713
/**
@@ -853,19 +854,23 @@ private Object invokeAndToString(MethodAndCoercedArgs accessor, Object objectWit
853854
* Find an accessor by name ignoring case.
854855
*/
855856
private MethodAndCoercedArgs accessor(Class<?> clazz, String name, String[] args) {
856-
LOG.log(Level.FINE, () -> "Find accessor named " + name + " on " + clazz.getSimpleName() + " with args " + Arrays.toString(args));
857-
858-
if (!class2methodsCache.containsKey(clazz)) {
859-
Map<String, Collection<Method>> methodMap = new HashMap<>();
860-
for (Method m : clazz.getMethods()) {
857+
final String finalName = name;
858+
LOG.log(Level.FINE, () -> "Find accessor named " + finalName + " on " + clazz.getSimpleName() + " with args " + Arrays.toString(args));
859+
name = removeUnderscoreChars(name);
860+
final Collection<Method> methods;
861+
if (class2methodsCache.containsKey(clazz)) {
862+
methods = class2methodsCache.get(clazz).getOrDefault(name.toLowerCase(Locale.ROOT), Collections.emptyList());
863+
} else {
864+
Method[] classMethods = clazz.getMethods();
865+
Map<String, Collection<Method>> methodMap = new HashMap<>(classMethods.length);
866+
for (Method m : classMethods) {
861867
final String key = m.getName().toLowerCase(Locale.ROOT);
862868
methodMap.computeIfAbsent(key, k -> new ArrayList<>());
863869
methodMap.get(key).add(m);
864870
}
865871
class2methodsCache.put(clazz, methodMap);
872+
methods = methodMap.get(name.toLowerCase(Locale.ROOT));
866873
}
867-
final Collection<Method> methods =
868-
class2methodsCache.get(clazz).getOrDefault(name.toLowerCase(Locale.ROOT), Collections.emptyList());
869874
for (Method m : methods) {
870875
if (m.getParameterTypes().length == args.length || m.getParameterTypes().length < args.length && m.isVarArgs()) {
871876
final Object[] coercedArguments = coerceArguments(m, args);
@@ -874,10 +879,6 @@ private MethodAndCoercedArgs accessor(Class<?> clazz, String name, String[] args
874879
}
875880
}
876881
}
877-
878-
if (name.contains("_")) {
879-
return accessor(clazz, removeUnderscoreChars(name), args);
880-
}
881882
return null;
882883
}
883884

0 commit comments

Comments
 (0)