mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
Replaced System.arraycopy with reflective array access.
This solves ArrayStoreExceptions that would otherwise occur with a primitive array.
This commit is contained in:
parent
3ff199fe61
commit
92b978bda9
@ -166,13 +166,19 @@ public class ConstructorUtils {
|
||||
|
||||
private static class VarArgsTransformer extends ConstructorArgumentTransformer {
|
||||
|
||||
private Class<?>[] paramtypes;
|
||||
private final Class<?>[] paramTypes;
|
||||
private final Class<?> componentType;
|
||||
|
||||
private VarArgsTransformer(Constructor<?> constructor) {
|
||||
super(constructor);
|
||||
|
||||
paramtypes = constructor.getParameterTypes();
|
||||
paramTypes = constructor.getParameterTypes();
|
||||
if (paramTypes.length > 0) {
|
||||
componentType = paramTypes[paramTypes.length - 1].getComponentType();
|
||||
|
||||
} else {
|
||||
componentType = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -182,16 +188,23 @@ public class ConstructorUtils {
|
||||
|
||||
@Override
|
||||
public Object[] apply(Object[] args) {
|
||||
Class<?>[] paramTypes = constructor.getParameterTypes();
|
||||
Iterator<Object> iterator = Arrays
|
||||
.asList(args)
|
||||
.iterator();
|
||||
|
||||
// constructor args
|
||||
Object[] cargs = new Object[paramTypes.length];
|
||||
System.arraycopy(args, 0, cargs, 0, cargs.length - 1);
|
||||
for (int i = 0; i < cargs.length - 1; i++) {
|
||||
Array.set(cargs, i, iterator.next());
|
||||
}
|
||||
// array with vargs
|
||||
int size = args.length - cargs.length + 1;
|
||||
Object[] array = (Object[]) Array.newInstance(
|
||||
paramTypes[paramTypes.length - 1].getComponentType(), size);
|
||||
cargs[cargs.length - 1] = array;
|
||||
System.arraycopy(args, cargs.length - 1, array, 0, size);
|
||||
Object vargs = Array.newInstance(
|
||||
componentType, size);
|
||||
cargs[cargs.length - 1] = vargs;
|
||||
for (int i = 0; i < Array.getLength(vargs); i++) {
|
||||
Array.set(vargs, i, iterator.next());
|
||||
}
|
||||
return cargs;
|
||||
}
|
||||
|
||||
|
||||
@ -13,12 +13,12 @@
|
||||
*/
|
||||
package com.mysema.query.types;
|
||||
|
||||
public class ProjectionExample{
|
||||
public class ProjectionExample {
|
||||
|
||||
public Long id;
|
||||
|
||||
|
||||
public String text;
|
||||
|
||||
|
||||
public ProjectionExample() {
|
||||
|
||||
}
|
||||
@ -43,4 +43,9 @@ public class ProjectionExample{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public ProjectionExample(Long id, char... characters) {
|
||||
this.id = id;
|
||||
this.text = String.copyValueOf(characters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,41 +23,41 @@ 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,
|
||||
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());
|
||||
assertEquals(String[].class, expr.newInstance("1", "2").getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void BeanClassOfTExpressionOfQArray() {
|
||||
PathBuilder<Entity> entity = new PathBuilder<Entity>(Entity.class, "entity");
|
||||
QBean<Entity> beanProjection = Projections.bean(Entity.class,
|
||||
entity.getNumber("cId",Integer.class),
|
||||
entity.getNumber("cId", Integer.class),
|
||||
entity.getNumber("eId", Integer.class));
|
||||
|
||||
assertEquals(Entity.class, beanProjection.newInstance(1,2).getClass());
|
||||
assertEquals(Entity.class, beanProjection.newInstance(1, 2).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -65,33 +65,43 @@ public class ProjectionsTest {
|
||||
Expression<Long> longVal = ConstantImpl.create(1l);
|
||||
Expression<String> stringVal = ConstantImpl.create("");
|
||||
assertEquals(ProjectionExample.class, Projections.constructor(ProjectionExample.class, longVal, stringVal)
|
||||
.newInstance(0l,"").getClass());
|
||||
.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);
|
||||
VarArgs instance = Projections.constructor(VarArgs.class, stringVal, 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, stringVal, stringVal).newInstance("X", "Y", "Z");
|
||||
assertEquals("X", instance.arg);
|
||||
assertArrayEquals(new String[]{"Y", "Z"}, instance.args);
|
||||
assertArrayEquals(new String[]{"Y", "Z"}, instance.args);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Constructor_VarArgs3() {
|
||||
Constant<Long> longVal = ConstantImpl.create(1L);
|
||||
Constant<Character> charVal = ConstantImpl.create('\0');
|
||||
ProjectionExample instance = Projections
|
||||
.constructor(ProjectionExample.class, longVal, charVal, charVal, charVal, charVal, charVal, charVal)
|
||||
.newInstance(1L, 'm', 'y', 's', 'e', 'm', 'a');
|
||||
assertEquals(1L, (long) instance.id);
|
||||
assertEquals("mysema", instance.text);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FieldsClassOfTExpressionOfQArray() {
|
||||
PathBuilder<Entity> entity = new PathBuilder<Entity>(Entity.class, "entity");
|
||||
QBean<Entity> beanProjection = Projections.fields(Entity.class,
|
||||
entity.getNumber("cId",Integer.class),
|
||||
entity.getNumber("cId", Integer.class),
|
||||
entity.getNumber("eId", Integer.class));
|
||||
|
||||
assertEquals(Entity.class, beanProjection.newInstance(1,2).getClass());
|
||||
assertEquals(Entity.class, beanProjection.newInstance(1, 2).getClass());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user