Skip to content

Commit f0a0572

Browse files
Rustam Sultansoyjknack
authored andcommitted
Add length to collections (list, set)
1 parent 317f4a0 commit f0a0572

2 files changed

Lines changed: 132 additions & 53 deletions

File tree

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/**
22
* Copyright (c) 2012-2015 Edgar Espina
3-
*
3+
* <p>
44
* This file is part of Handlebars.java.
5-
*
5+
* <p>
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
88
* You may obtain a copy of the License at
9-
*
10-
* http://www.apache.org/licenses/LICENSE-2.0
11-
*
9+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
1212
* Unless required by applicable law or agreed to in writing, software
1313
* distributed under the License is distributed on an "AS IS" BASIS,
1414
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,6 +18,7 @@
1818
package com.github.jknack.handlebars.context;
1919

2020
import java.lang.reflect.Method;
21+
import java.util.Collection;
2122

2223
import com.github.jknack.handlebars.ValueResolver;
2324

@@ -29,60 +30,90 @@
2930
*/
3031
public class JavaBeanValueResolver extends MethodValueResolver {
3132

32-
/**
33-
* The 'is' prefix.
34-
*/
35-
private static final String IS_PREFIX = "is";
33+
/**
34+
* The 'is' prefix.
35+
*/
36+
private static final String IS_PREFIX = "is";
37+
38+
/**
39+
* The 'get' prefix.
40+
*/
41+
private static final String GET_PREFIX = "get";
3642

37-
/**
38-
* The 'get' prefix.
39-
*/
40-
private static final String GET_PREFIX = "get";
43+
/**
44+
* The default value resolver.
45+
*/
46+
public static final ValueResolver INSTANCE = new JavaBeanValueResolver();
4147

42-
/**
43-
* The default value resolver.
44-
*/
45-
public static final ValueResolver INSTANCE = new JavaBeanValueResolver();
48+
@Override
49+
public boolean matches(final Method method, final String name) {
50+
if (method.getName().equals("size") && name.equals("length")) {
51+
boolean isCollection = isCollectionMethod(method);
52+
if (isCollection) {
53+
return true;
54+
}
55+
}
4656

47-
@Override
48-
public boolean matches(final Method method, final String name) {
49-
boolean isStatic = isStatic(method);
50-
boolean isPublic = isPublic(method);
51-
boolean isGet = method.getName().equals(javaBeanMethod(GET_PREFIX, name));
52-
boolean isBoolGet = method.getName().equals(javaBeanMethod(IS_PREFIX, name));
53-
int parameterCount = method.getParameterTypes().length;
57+
boolean isStatic = isStatic(method);
58+
boolean isPublic = isPublic(method);
59+
boolean isGet = method.getName().equals(javaBeanMethod(GET_PREFIX, name));
60+
boolean isBoolGet = method.getName().equals(javaBeanMethod(IS_PREFIX, name));
61+
int parameterCount = method.getParameterTypes().length;
5462

55-
return !isStatic && isPublic && parameterCount == 0 && (isGet || isBoolGet);
56-
}
63+
return !isStatic && isPublic && parameterCount == 0 && (isGet || isBoolGet);
64+
}
65+
66+
/**
67+
* Convert the property's name to a JavaBean read method name.
68+
*
69+
* @param prefix The prefix: 'get' or 'is'.
70+
* @param name The unqualified property name.
71+
* @return The javaBean method name.
72+
*/
73+
private static String javaBeanMethod(final String prefix,
74+
final String name) {
75+
StringBuilder buffer = new StringBuilder(prefix);
76+
buffer.append(name);
77+
buffer.setCharAt(prefix.length(), Character.toUpperCase(name.charAt(0)));
78+
return buffer.toString();
79+
}
5780

58-
/**
59-
* Convert the property's name to a JavaBean read method name.
60-
*
61-
* @param prefix The prefix: 'get' or 'is'.
62-
* @param name The unqualified property name.
63-
* @return The javaBean method name.
64-
*/
65-
private static String javaBeanMethod(final String prefix,
66-
final String name) {
67-
StringBuilder buffer = new StringBuilder(prefix);
68-
buffer.append(name);
69-
buffer.setCharAt(prefix.length(), Character.toUpperCase(name.charAt(0)));
70-
return buffer.toString();
71-
}
81+
@Override
82+
protected String memberName(final Method member) {
83+
if (member.getName().equals("size")) {
84+
boolean isCollection = isCollectionMethod(member);
7285

73-
@Override
74-
protected String memberName(final Method member) {
75-
String name = member.getName();
76-
if (name.startsWith(GET_PREFIX)) {
77-
name = name.substring(GET_PREFIX.length());
78-
} else if (name.startsWith(IS_PREFIX)) {
79-
name = name.substring(IS_PREFIX.length());
80-
} else {
81-
return name;
86+
if (isCollection) {
87+
return "length";
88+
}
89+
}
90+
91+
String name = member.getName();
92+
if (name.startsWith(GET_PREFIX)) {
93+
name = name.substring(GET_PREFIX.length());
94+
} else if (name.startsWith(IS_PREFIX)) {
95+
name = name.substring(IS_PREFIX.length());
96+
} else {
97+
return name;
98+
}
99+
if (name.length() > 0) {
100+
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
101+
}
102+
return member.getName();
82103
}
83-
if (name.length() > 0) {
84-
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
104+
105+
/**
106+
* Check is method class implements Collection interface.
107+
*
108+
* @param method from class
109+
* @return true/false
110+
*/
111+
private boolean isCollectionMethod(final Method method) {
112+
for (Class clazz : method.getDeclaringClass().getInterfaces()) {
113+
if (Collection.class.equals(clazz)) {
114+
return true;
115+
}
116+
}
117+
return false;
85118
}
86-
return member.getName();
87-
}
88119
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.github.jknack.handlebars;
2+
3+
import org.junit.Test;
4+
5+
import java.io.IOException;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
public class CollectionsLengthTest extends AbstractTest {
10+
11+
static class SizeAndLength {
12+
int size;
13+
int length;
14+
15+
public int getSize() {
16+
return size;
17+
}
18+
19+
public void setSize(int size) {
20+
this.size = size;
21+
}
22+
23+
public int getLength() {
24+
return length;
25+
}
26+
27+
public void setLength(int length) {
28+
this.length = length;
29+
}
30+
}
31+
32+
@Test
33+
public void collectionLengthTest() throws IOException {
34+
List<String> list = new ArrayList<>();
35+
list.add("a");
36+
shouldCompileTo("{{this.length}}", list, "1");
37+
}
38+
39+
@Test
40+
public void otherClassSizeAndLength() throws IOException {
41+
SizeAndLength sizeAndLength = new SizeAndLength();
42+
sizeAndLength.length = 5;
43+
sizeAndLength.size = 4;
44+
shouldCompileTo("{{this.length}}", sizeAndLength, "5");
45+
shouldCompileTo("{{this.size}}", sizeAndLength, "4");
46+
47+
}
48+
}

0 commit comments

Comments
 (0)