mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
#163 fixed constructor expression issues
This commit is contained in:
parent
7398c23fc0
commit
ffa6bc0068
@ -13,6 +13,7 @@
|
||||
*/
|
||||
package com.mysema.query.types;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
@ -39,8 +40,10 @@ public class ConstructorExpression<T> extends ExpressionBase<T> implements Facto
|
||||
|
||||
private static Class<?>[] getRealParameters(Class<?> type, Class<?>[] givenTypes) {
|
||||
for (Constructor<?> c : type.getConstructors()){
|
||||
Class<?>[] paramTypes = c.getParameterTypes();
|
||||
if (paramTypes.length == givenTypes.length) {
|
||||
Class<?>[] paramTypes = c.getParameterTypes();
|
||||
if (c.isVarArgs()) {
|
||||
return paramTypes;
|
||||
} else if (paramTypes.length == givenTypes.length) {
|
||||
boolean found = true;
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
if (!normalize(paramTypes[i]).isAssignableFrom(normalize(givenTypes[i]))) {
|
||||
@ -67,10 +70,10 @@ public class ConstructorExpression<T> extends ExpressionBase<T> implements Facto
|
||||
private final List<Expression<?>> args;
|
||||
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
|
||||
@Nullable
|
||||
private transient Constructor<?> constructor;
|
||||
|
||||
|
||||
public ConstructorExpression(Class<T> type, Class<?>[] paramTypes, Expression<?>... args) {
|
||||
this(type, paramTypes, Arrays.asList(args));
|
||||
}
|
||||
@ -94,7 +97,7 @@ public class ConstructorExpression<T> extends ExpressionBase<T> implements Facto
|
||||
/**
|
||||
* Create an alias for the expression
|
||||
*
|
||||
* @return
|
||||
* @retu rn
|
||||
*/
|
||||
public Expression<T> as(String alias) {
|
||||
return as(new PathImpl<T>(getType(), alias));
|
||||
@ -129,7 +132,22 @@ public class ConstructorExpression<T> extends ExpressionBase<T> implements Facto
|
||||
if (constructor == null) {
|
||||
constructor = getType().getConstructor(parameterTypes);
|
||||
}
|
||||
return (T) constructor.newInstance(args);
|
||||
if (constructor.isVarArgs()) {
|
||||
Class<?>[] paramTypes = constructor.getParameterTypes();
|
||||
// constructor args
|
||||
Object[] cargs = new Object[paramTypes.length];
|
||||
System.arraycopy(args, 0, cargs, 0, cargs.length - 1);
|
||||
// array with vargs
|
||||
int size = args.length - cargs.length + 1;
|
||||
Object array = Array.newInstance(
|
||||
paramTypes[paramTypes.length - 1].getComponentType(), size);
|
||||
cargs[cargs.length - 1] = array;
|
||||
System.arraycopy(args, cargs.length - 1, array, 0, size);
|
||||
return (T) constructor.newInstance(cargs);
|
||||
} else {
|
||||
return (T) constructor.newInstance(args);
|
||||
}
|
||||
|
||||
} catch (SecurityException e) {
|
||||
throw new ExpressionException(e.getMessage(), e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
*/
|
||||
package com.mysema.query.types;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@ -22,10 +22,31 @@ import com.mysema.query.types.path.PathBuilder;
|
||||
|
||||
public class ProjectionsTest {
|
||||
|
||||
public static class VarArgs {
|
||||
|
||||
String[] args;
|
||||
|
||||
public VarArgs(String... strs) {
|
||||
args = strs;
|
||||
}
|
||||
}
|
||||
|
||||
public static class VarArgs2 {
|
||||
|
||||
String arg;
|
||||
String[] args;
|
||||
|
||||
public VarArgs2(String s, String... strs) {
|
||||
arg = s;
|
||||
args = strs;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void Array() {
|
||||
FactoryExpression<String[]> expr = Projections.array(String[].class, new PathImpl(String.class, "p1"), new PathImpl(String.class, "p2"));
|
||||
FactoryExpression<String[]> expr = Projections.array(String[].class,
|
||||
new PathImpl(String.class, "p1"), new PathImpl(String.class, "p2"));
|
||||
assertEquals(String[].class, expr.newInstance("1","2").getClass());
|
||||
}
|
||||
|
||||
@ -43,7 +64,23 @@ public class ProjectionsTest {
|
||||
public void Constructor() {
|
||||
Expression<Long> longVal = ConstantImpl.create(1l);
|
||||
Expression<String> stringVal = ConstantImpl.create("");
|
||||
assertEquals(ProjectionExample.class, Projections.constructor(ProjectionExample.class, longVal, stringVal).newInstance(0l,"").getClass());
|
||||
assertEquals(ProjectionExample.class, Projections.constructor(ProjectionExample.class, longVal, stringVal)
|
||||
.newInstance(0l,"").getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Constructor_VarArgs() {
|
||||
Expression<String> stringVal = ConstantImpl.create("");
|
||||
VarArgs instance = Projections.constructor(VarArgs.class, stringVal).newInstance("X", "Y");
|
||||
assertArrayEquals(new String[]{"X", "Y"}, instance.args);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Constructor_VarArgs2() {
|
||||
Expression<String> stringVal = ConstantImpl.create("");
|
||||
VarArgs2 instance = Projections.constructor(VarArgs2.class, stringVal).newInstance("X", "Y", "Z");
|
||||
assertEquals("X", instance.arg);
|
||||
assertArrayEquals(new String[]{"Y", "Z"}, instance.args);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user