mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-21 21:14:12 +08:00
improvements to PEntityMap and PEntityList
This commit is contained in:
parent
63f7af1b89
commit
c48d02ad18
@ -1,5 +1,7 @@
|
||||
package com.mysema.query.domain;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -115,5 +117,12 @@ public class RelationTest extends AbstractTest{
|
||||
match(PEntityMap.class, "map8");
|
||||
match(PComponentMap.class, "map9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listUsage(){
|
||||
String expected = "relationType.list.get(0).set";
|
||||
assertEquals(expected, QRelationType.relationType.list.get(0).set.toString());
|
||||
assertEquals(expected, QRelationType.relationType.list(0).set.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,12 +18,12 @@ import com.mysema.query.types.path.PBoolean;
|
||||
import com.mysema.query.types.path.PBooleanArray;
|
||||
import com.mysema.query.types.path.PComparable;
|
||||
import com.mysema.query.types.path.PComparableArray;
|
||||
import com.mysema.query.types.path.PComponentList;
|
||||
import com.mysema.query.types.path.PComponentMap;
|
||||
import com.mysema.query.types.path.PDate;
|
||||
import com.mysema.query.types.path.PDateTime;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityList;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PNumber;
|
||||
import com.mysema.query.types.path.PSimple;
|
||||
import com.mysema.query.types.path.PString;
|
||||
@ -151,12 +151,12 @@ public final class Alias {
|
||||
return pathFactory.createTime(arg);
|
||||
}
|
||||
|
||||
public static <K, V> PEntityMap<K, V> $(Map<K, V> args) {
|
||||
return pathFactory.createEntityMap(args);
|
||||
public static <K, V> PComponentMap<K, V> $(Map<K, V> args) {
|
||||
return pathFactory.createMap(args);
|
||||
}
|
||||
|
||||
public static <D> PEntityList<D> $(List<D> args) {
|
||||
return pathFactory.createEntityList(args);
|
||||
public static <D> PComponentList<D> $(List<D> args) {
|
||||
return pathFactory.createList(args);
|
||||
}
|
||||
|
||||
public static <D> PEntity<D> $(D arg) {
|
||||
|
||||
@ -14,12 +14,12 @@ import com.mysema.query.types.path.PBoolean;
|
||||
import com.mysema.query.types.path.PBooleanArray;
|
||||
import com.mysema.query.types.path.PComparable;
|
||||
import com.mysema.query.types.path.PComparableArray;
|
||||
import com.mysema.query.types.path.PComponentList;
|
||||
import com.mysema.query.types.path.PComponentMap;
|
||||
import com.mysema.query.types.path.PDate;
|
||||
import com.mysema.query.types.path.PDateTime;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityList;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PNumber;
|
||||
import com.mysema.query.types.path.PString;
|
||||
import com.mysema.query.types.path.PStringArray;
|
||||
@ -105,14 +105,14 @@ class AliasAwarePathFactory implements PathFactory {
|
||||
return rv != null ? rv : factory.createEntityCollection(arg);
|
||||
}
|
||||
|
||||
public <D> PEntityList<D> createEntityList(List<D> arg) {
|
||||
PEntityList<D> rv = aliasFactory.<PEntityList<D>> getCurrentAndReset();
|
||||
return rv != null ? rv : factory.createEntityList(arg);
|
||||
public <D> PComponentList<D> createList(List<D> arg) {
|
||||
PComponentList<D> rv = aliasFactory.<PComponentList<D>> getCurrentAndReset();
|
||||
return rv != null ? rv : factory.createList(arg);
|
||||
}
|
||||
|
||||
public <K, V> PEntityMap<K, V> createEntityMap(Map<K, V> arg) {
|
||||
PEntityMap<K, V> rv = aliasFactory.<PEntityMap<K, V>> getCurrentAndReset();
|
||||
return rv != null ? rv : factory.createEntityMap(arg);
|
||||
public <K, V> PComponentMap<K, V> createMap(Map<K, V> arg) {
|
||||
PComponentMap<K, V> rv = aliasFactory.<PComponentMap<K, V>> getCurrentAndReset();
|
||||
return rv != null ? rv : factory.createMap(arg);
|
||||
}
|
||||
|
||||
public <D extends Number & Comparable<?>> PNumber<D> createNumber(D arg) {
|
||||
|
||||
@ -14,12 +14,12 @@ import com.mysema.query.types.path.PBoolean;
|
||||
import com.mysema.query.types.path.PBooleanArray;
|
||||
import com.mysema.query.types.path.PComparable;
|
||||
import com.mysema.query.types.path.PComparableArray;
|
||||
import com.mysema.query.types.path.PComponentList;
|
||||
import com.mysema.query.types.path.PComponentMap;
|
||||
import com.mysema.query.types.path.PDate;
|
||||
import com.mysema.query.types.path.PDateTime;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityList;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PNumber;
|
||||
import com.mysema.query.types.path.PString;
|
||||
import com.mysema.query.types.path.PStringArray;
|
||||
@ -54,9 +54,9 @@ interface PathFactory {
|
||||
|
||||
<D> PEntity<D> createEntity(D arg);
|
||||
|
||||
<D> PEntityList<D> createEntityList(List<D> arg);
|
||||
<D> PComponentList<D> createList(List<D> arg);
|
||||
|
||||
<K, V> PEntityMap<K, V> createEntityMap(Map<K, V> arg);
|
||||
<K, V> PComponentMap<K, V> createMap(Map<K, V> arg);
|
||||
|
||||
<D> PEntityCollection<D> createEntityCollection(Collection<D> arg);
|
||||
|
||||
|
||||
@ -33,12 +33,12 @@ import com.mysema.query.types.expr.EMap;
|
||||
import com.mysema.query.types.expr.Expr;
|
||||
import com.mysema.query.types.path.PBoolean;
|
||||
import com.mysema.query.types.path.PComparable;
|
||||
import com.mysema.query.types.path.PComponentList;
|
||||
import com.mysema.query.types.path.PComponentMap;
|
||||
import com.mysema.query.types.path.PDate;
|
||||
import com.mysema.query.types.path.PDateTime;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityList;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PList;
|
||||
import com.mysema.query.types.path.PMap;
|
||||
import com.mysema.query.types.path.PNumber;
|
||||
@ -274,7 +274,7 @@ class PropertyAccessInvocationHandler implements MethodInterceptor {
|
||||
|
||||
} else if (List.class.isAssignableFrom(type)) {
|
||||
Class<?> elementType = getTypeParameter(genericType, 0);
|
||||
path = new PEntityList(elementType, elementType.getSimpleName(), pm);
|
||||
path = new PComponentList(elementType, pm);
|
||||
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
|
||||
|
||||
} else if (Set.class.isAssignableFrom(type)) {
|
||||
@ -290,7 +290,7 @@ class PropertyAccessInvocationHandler implements MethodInterceptor {
|
||||
} else if (Map.class.isAssignableFrom(type)) {
|
||||
Class<?> keyType = getTypeParameter(genericType, 0);
|
||||
Class<?> valueType = getTypeParameter(genericType, 1);
|
||||
path = new PEntityMap(keyType, valueType, valueType.getSimpleName(), pm);
|
||||
path = new PComponentMap(keyType, valueType, pm);
|
||||
rv = (T) aliasFactory.createAliasForProp(type, parent, path);
|
||||
|
||||
} else if (Enum.class.isAssignableFrom(type)) {
|
||||
|
||||
@ -20,11 +20,12 @@ import com.mysema.query.types.path.PBoolean;
|
||||
import com.mysema.query.types.path.PBooleanArray;
|
||||
import com.mysema.query.types.path.PComparable;
|
||||
import com.mysema.query.types.path.PComparableArray;
|
||||
import com.mysema.query.types.path.PComponentList;
|
||||
import com.mysema.query.types.path.PComponentMap;
|
||||
import com.mysema.query.types.path.PDate;
|
||||
import com.mysema.query.types.path.PDateTime;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityList;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PNumber;
|
||||
import com.mysema.query.types.path.PString;
|
||||
@ -87,30 +88,30 @@ class SimplePathFactory implements PathFactory {
|
||||
}
|
||||
});
|
||||
|
||||
private final Map<List<?>, PEntityList<?>> elToPath = new PathFactory<List<?>, PEntityList<?>>(
|
||||
new Transformer<List<?>, PEntityList<?>>() {
|
||||
private final Map<List<?>, PComponentList<?>> elToPath = new PathFactory<List<?>, PComponentList<?>>(
|
||||
new Transformer<List<?>, PComponentList<?>>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public PEntityList<?> transform(List<?> arg) {
|
||||
public PComponentList<?> transform(List<?> arg) {
|
||||
if (!arg.isEmpty()) {
|
||||
Class<?> cl = arg.get(0).getClass();
|
||||
return new PEntityList(cl, cl.getSimpleName(), md());
|
||||
return new PComponentList(cl, md());
|
||||
} else {
|
||||
return new PEntityList(Object.class, "Object", md());
|
||||
return new PComponentList(Object.class, md());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
private final Map<Map<?, ?>, PEntityMap<?, ?>> emToPath = new PathFactory<Map<?, ?>, PEntityMap<?, ?>>(
|
||||
new Transformer<Map<?, ?>, PEntityMap<?, ?>>() {
|
||||
private final Map<Map<?, ?>, PComponentMap<?, ?>> emToPath = new PathFactory<Map<?, ?>, PComponentMap<?, ?>>(
|
||||
new Transformer<Map<?, ?>, PComponentMap<?, ?>>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public PEntityMap<?, ?> transform(Map<?, ?> arg) {
|
||||
public PComponentMap<?, ?> transform(Map<?, ?> arg) {
|
||||
if (!arg.isEmpty()) {
|
||||
Map.Entry entry = arg.entrySet().iterator().next();
|
||||
Class<?> keyType = entry.getKey().getClass();
|
||||
Class<?> valueType = entry.getValue().getClass();
|
||||
return new PEntityMap(keyType, valueType, valueType.getSimpleName(), md());
|
||||
return new PComponentMap(keyType, valueType, md());
|
||||
} else {
|
||||
return new PEntityMap(Object.class, Object.class, "Object", md());
|
||||
return new PComponentMap(Object.class, Object.class, md());
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,13 +225,8 @@ class SimplePathFactory implements PathFactory {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <D> PEntityList<D> createEntityList(List<D> arg) {
|
||||
return (PEntityList<D>) elToPath.get(arg);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <K, V> PEntityMap<K, V> createEntityMap(Map<K, V> arg) {
|
||||
return (PEntityMap<K, V>) emToPath.get(arg);
|
||||
public <K, V> PComponentMap<K, V> createMap(Map<K, V> arg) {
|
||||
return (PComponentMap<K, V>) emToPath.get(arg);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -256,4 +252,10 @@ class SimplePathFactory implements PathFactory {
|
||||
return PathMetadata.forVariable("v" + String.valueOf(++counter));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <D> PComponentList<D> createList(List<D> arg) {
|
||||
return (PComponentList<D>) elToPath.get(arg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@ package com.mysema.query.codegen;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.jcip.annotations.Immutable;
|
||||
|
||||
@ -133,7 +135,7 @@ public class EntitySerializer implements Serializer{
|
||||
}
|
||||
|
||||
protected void collectionOfEntity(PropertyModel field, Writer writer) throws IOException {
|
||||
serialize(field, "PEntityCollection<" + field.getGenericTypeName()+">", writer, "createEntityCollection", field.getTypeName()+".class", "\"" + field.getSimpleTypeName()+"\"");
|
||||
serialize(field, "PEntityCollection<" + field.getGenericTypeName()+">", writer, "createEntityCollection", field.getTypeName()+".class");
|
||||
}
|
||||
|
||||
protected void collectionOfSimple(PropertyModel field, Writer writer) throws IOException {
|
||||
@ -167,7 +169,7 @@ public class EntitySerializer implements Serializer{
|
||||
builder.append(");\n");
|
||||
builder.append(" }\n\n");
|
||||
|
||||
// 3
|
||||
// 3
|
||||
builder.append(" public " + queryType + "(PathMetadata<?> metadata) {\n");
|
||||
if (hasEntityFields){
|
||||
builder.append(" this(metadata, metadata.isRoot() ? __inits : PathInits.DEFAULT);\n");
|
||||
@ -286,13 +288,22 @@ public class EntitySerializer implements Serializer{
|
||||
|
||||
protected void introInits(StringBuilder builder, BeanModel model) {
|
||||
if (!model.getEntityProperties().isEmpty()){
|
||||
builder.append(" private static final PathInits __inits = new PathInits(\"*\"");
|
||||
List<String> inits = new ArrayList<String>();
|
||||
for (PropertyModel property : model.getEntityProperties()){
|
||||
for (String init : property.getInits()){
|
||||
builder.append(", \"" + property.getEscapedName() + "." + init + "\"");
|
||||
inits.add(property.getEscapedName() + "." + init);
|
||||
}
|
||||
}
|
||||
builder.append(");\n\n");
|
||||
}
|
||||
if (!inits.isEmpty()){
|
||||
builder.append(" private static final PathInits __inits = new PathInits(\"*\"");
|
||||
for (String init : inits){
|
||||
builder.append(", \"" + init + "\"");
|
||||
}
|
||||
builder.append(");\n\n");
|
||||
}else{
|
||||
builder.append(" private static final PathInits __inits = PathInits.DIRECT;\n\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +359,9 @@ public class EntitySerializer implements Serializer{
|
||||
}
|
||||
|
||||
protected void listOfEntity(PropertyModel field, Writer writer) throws IOException {
|
||||
serialize(field, "PEntityList<" + field.getGenericTypeName()+ ">", writer, "createEntityList", field.getTypeName()+".class", "\"" + field.getSimpleTypeName()+"\"");
|
||||
serialize(field, "PEntityList<" + field.getGenericTypeName()+ "," + field.getQueryTypeName() + ">", writer, "createEntityList",
|
||||
field.getTypeName()+".class",
|
||||
field.getQueryTypeName() +".class");
|
||||
}
|
||||
|
||||
protected void listOfEntityAccessor(PropertyModel field, Writer writer) throws IOException {
|
||||
@ -357,10 +370,10 @@ public class EntitySerializer implements Serializer{
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(" public " + queryType + " " + escapedName + "(int index) {\n");
|
||||
builder.append(" return new " + queryType + "(PathMetadata.forListAccess(" + escapedName+", index));\n");
|
||||
builder.append(" return " + escapedName + ".get(index);\n");
|
||||
builder.append(" }\n\n");
|
||||
builder.append(" public " + queryType + " " + escapedName + "(com.mysema.query.types.expr.Expr<Integer> index) {\n");
|
||||
builder.append(" return new " + queryType + "(PathMetadata.forListAccess(" + escapedName+", index));\n");
|
||||
builder.append(" return " + escapedName + ".get(index);\n");
|
||||
builder.append(" }\n\n");
|
||||
writer.append(builder.toString());
|
||||
}
|
||||
@ -371,10 +384,10 @@ public class EntitySerializer implements Serializer{
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(" public PSimple<" + valueType + "> " + escapedName + "(int index) {\n");
|
||||
builder.append(" return new PSimple<" + valueType + ">("+valueType+".class, PathMetadata.forListAccess(" + escapedName+", index));\n");
|
||||
builder.append(" return " + escapedName + ".get(index);\n");
|
||||
builder.append(" }\n\n");
|
||||
builder.append(" public PSimple<" + valueType + "> " + escapedName + "(com.mysema.query.types.expr.Expr<Integer> index) {\n");
|
||||
builder.append(" return new PSimple<" + valueType + ">("+valueType+".class, PathMetadata.forListAccess(" + escapedName+", index));\n");
|
||||
builder.append(" return " + escapedName + ".get(index);\n");
|
||||
builder.append(" }\n\n");
|
||||
writer.append(builder.toString());
|
||||
|
||||
@ -387,12 +400,15 @@ public class EntitySerializer implements Serializer{
|
||||
protected void mapOfEntity(PropertyModel field, Writer writer) throws IOException{
|
||||
final String keyType = field.getParameterName(0);
|
||||
final String valueType = field.getParameterName(1);
|
||||
final String simpleName = field.getSimpleTypeName();
|
||||
// final String simpleName = field.getSimpleTypeName();
|
||||
final String genericKey = field.getGenericParameterName(0);
|
||||
final String genericValue = field.getGenericParameterName(1);
|
||||
|
||||
serialize(field, "PEntityMap<"+genericKey+","+genericValue+">",
|
||||
writer, "createEntityMap", keyType+".class", valueType+".class", "\""+simpleName+"\"");
|
||||
serialize(field, "PEntityMap<"+genericKey+","+genericValue+","+field.getQueryTypeName()+">",
|
||||
writer, "createEntityMap",
|
||||
keyType+".class",
|
||||
valueType+".class",
|
||||
field.getQueryTypeName()+".class");
|
||||
|
||||
}
|
||||
|
||||
@ -404,10 +420,10 @@ public class EntitySerializer implements Serializer{
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(" public " + queryType + " " + escapedName + "(" + keyType+ " key) {\n");
|
||||
builder.append(" return new " + queryType + "(PathMetadata.forMapAccess(" + escapedName+", key));\n");
|
||||
builder.append(" return " + escapedName + ".get(key);\n");
|
||||
builder.append(" }\n\n");
|
||||
builder.append(" public " + queryType + " " + escapedName + "(com.mysema.query.types.expr.Expr<"+genericKey+"> key) {\n");
|
||||
builder.append(" return new " + queryType + "(PathMetadata.forMapAccess(" + escapedName+", key));\n");
|
||||
builder.append(" return " + escapedName + ".get(key);\n");
|
||||
builder.append(" }\n\n");
|
||||
writer.append(builder.toString());
|
||||
|
||||
@ -427,17 +443,17 @@ public class EntitySerializer implements Serializer{
|
||||
protected void mapOfSimpleAccessor(PropertyModel field, Writer writer) throws IOException {
|
||||
final String escapedName = field.getEscapedName();
|
||||
// final String keyType = field.getParameterName(0);
|
||||
final String valueType = field.getParameterName(1);
|
||||
// final String valueType = field.getParameterName(1);
|
||||
final String genericKey = field.getGenericParameterName(0);
|
||||
final String genericValue = field.getGenericParameterName(1);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append(" public PSimple<" + genericValue + "> " + escapedName + "(" + genericKey + " key) {\n");
|
||||
builder.append(" return new PSimple<" + genericValue + ">("+valueType+".class, PathMetadata.forMapAccess(" + escapedName+", key));\n");
|
||||
builder.append(" return " + escapedName + ".get(key);\n");
|
||||
builder.append(" }\n\n");
|
||||
builder.append(" public PSimple<" + genericValue + "> " + escapedName + "(com.mysema.query.types.expr.Expr<"+genericKey+"> key) {\n");
|
||||
builder.append(" return new PSimple<" + valueType + ">("+valueType+".class, PathMetadata.forMapAccess(" + escapedName+", key));\n");
|
||||
builder.append(" return " + escapedName + ".get(key);\n");
|
||||
builder.append(" }\n\n");
|
||||
writer.append(builder.toString());
|
||||
|
||||
|
||||
@ -30,17 +30,15 @@ public class SupertypeSerializer extends EntitySerializer{
|
||||
builder.append(" super(entity.getType(), entity.getEntityName(), entity.getMetadata());\n");
|
||||
builder.append(" }\n\n");
|
||||
|
||||
builder.append(" public "+queryType+"(Class<? extends "+genericName+"> type, @NotEmpty String entityName, PathMetadata<?> metadata) {\n");
|
||||
builder.append(" super(type, entityName, metadata);\n");
|
||||
|
||||
}else{
|
||||
builder.append(" public "+queryType+"(Class<? extends "+genericName+"> type, @NotEmpty String entityName, PathMetadata<?> metadata, PathInits inits) {\n");
|
||||
builder.append(" super(type, entityName, metadata);\n");
|
||||
if (!model.getEntityProperties().isEmpty()){
|
||||
initEntityFields(builder, model);
|
||||
}
|
||||
}
|
||||
builder.append(" }\n");
|
||||
}
|
||||
builder.append(" }\n");
|
||||
|
||||
writer.append(builder.toString());
|
||||
}
|
||||
|
||||
@ -56,7 +54,9 @@ public class SupertypeSerializer extends EntitySerializer{
|
||||
|
||||
@Override
|
||||
protected void introImports(StringBuilder builder, BeanModel model) {
|
||||
builder.append("import com.mysema.query.util.*;\n");
|
||||
if (!model.getEntityProperties().isEmpty()){
|
||||
builder.append("import com.mysema.query.util.*;\n");
|
||||
}
|
||||
builder.append("import com.mysema.query.types.path.*;\n\n");
|
||||
}
|
||||
|
||||
|
||||
@ -145,9 +145,9 @@ public interface Visitor {
|
||||
|
||||
void visit(PEntityCollection<?> expr);
|
||||
|
||||
void visit(PEntityList<?> expr);
|
||||
void visit(PEntityList<?, ?> expr);
|
||||
|
||||
void visit(PEntityMap<?, ?> expr);
|
||||
void visit(PEntityMap<?, ?, ?> expr);
|
||||
|
||||
void visit(PList<?> expr);
|
||||
|
||||
|
||||
@ -254,12 +254,12 @@ public abstract class VisitorBase<SubType extends VisitorBase<SubType>> implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PEntityList<?> expr) {
|
||||
public void visit(PEntityList<?,?> expr) {
|
||||
visit((PList<?>) expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PEntityMap<?, ?> expr) {
|
||||
public void visit(PEntityMap<?, ?, ?> expr) {
|
||||
visit((PMap<?, ?>) expr);
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
package com.mysema.query.types.path;
|
||||
|
||||
import com.mysema.query.types.expr.Expr;
|
||||
import com.mysema.query.util.NotEmpty;
|
||||
|
||||
/**
|
||||
* PComponentList represents component list paths
|
||||
@ -22,21 +21,13 @@ public class PComponentList<D> extends PComponentCollection<D> implements PList<
|
||||
super(type, metadata);
|
||||
}
|
||||
|
||||
public PComponentList(Class<D> type, @NotEmpty String var) {
|
||||
super(type, PathMetadata.forVariable(var));
|
||||
}
|
||||
|
||||
public PComponentList(Class<D> type, Path<?> path, @NotEmpty String property) {
|
||||
super(type, PathMetadata.forProperty(path, property));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr<D> get(Expr<Integer> index) {
|
||||
public PSimple<D> get(Expr<Integer> index) {
|
||||
return new PSimple<D>(type, PathMetadata.forListAccess(this, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr<D> get(int index) {
|
||||
public PSimple<D> get(int index) {
|
||||
return new PSimple<D>(type, PathMetadata.forListAccess(this, index));
|
||||
}
|
||||
}
|
||||
@ -37,8 +37,7 @@ public class PComponentMap<K, V> extends EMapBase<K, V> implements PMap<K, V> {
|
||||
private volatile EBoolean isnull, isnotnull;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public PComponentMap(Class<? super K> keyType, Class<? super V> valueType,
|
||||
PathMetadata<?> metadata) {
|
||||
public PComponentMap(Class<? super K> keyType, Class<? super V> valueType, PathMetadata<?> metadata) {
|
||||
super((Class)Map.class);
|
||||
this.keyType = (Class<K>)keyType;
|
||||
this.valueType = (Class<V>)valueType;
|
||||
@ -67,12 +66,12 @@ public class PComponentMap<K, V> extends EMapBase<K, V> implements PMap<K, V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr<V> get(Expr<K> key) {
|
||||
public PSimple<V> get(Expr<K> key) {
|
||||
return new PSimple<V>(valueType, PathMetadata.forMapAccess(this, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr<V> get(K key) {
|
||||
public PSimple<V> get(K key) {
|
||||
return new PSimple<V>(valueType, PathMetadata.forMapAccess(this, key));
|
||||
}
|
||||
|
||||
|
||||
@ -42,32 +42,28 @@ public class PEntity<D> extends EEntity<D> implements Path<D> {
|
||||
return new PBoolean(this, propertyName);
|
||||
}
|
||||
|
||||
protected <A extends Comparable<?>> PComparable<A> createComparable(@NotEmpty String propertyName, Class<A> type) {
|
||||
return new PComparable<A>(type, this, propertyName);
|
||||
protected <A extends Comparable<?>> PComparable<A> createComparable(@NotEmpty String property, Class<A> type) {
|
||||
return new PComparable<A>(type, this, property);
|
||||
}
|
||||
|
||||
protected <A extends Comparable<?>> PDate<A> createDate(@NotEmpty String propertyName, Class<A> type) {
|
||||
return new PDate<A>(type, PathMetadata.forProperty(this, propertyName));
|
||||
protected <A extends Comparable<?>> PDate<A> createDate(@NotEmpty String property, Class<A> type) {
|
||||
return new PDate<A>(type, PathMetadata.forProperty(this, property));
|
||||
}
|
||||
|
||||
protected <A extends Comparable<?>> PDateTime<A> createDateTime(@NotEmpty String propertyName, Class<A> type) {
|
||||
return new PDateTime<A>(type, this, propertyName);
|
||||
protected <A extends Comparable<?>> PDateTime<A> createDateTime(@NotEmpty String property, Class<A> type) {
|
||||
return new PDateTime<A>(type, this, property);
|
||||
}
|
||||
|
||||
protected <A> PEntity<A> createEntity(@NotEmpty String property, @NotEmpty String entityName, Class<A> type) {
|
||||
return new PEntity<A>(type, entityName, PathMetadata.forProperty(this, property));
|
||||
protected <A> PEntityCollection<A> createEntityCollection(@NotEmpty String property, Class<? super A> type) {
|
||||
return new PEntityCollection<A>(type, type.getSimpleName(), this, property);
|
||||
}
|
||||
|
||||
protected <A> PEntityCollection<A> createEntityCollection(@NotEmpty String property, Class<? super A> type, @NotEmpty String entityName) {
|
||||
return new PEntityCollection<A>(type, entityName, this, property);
|
||||
protected <A, E extends PEntity<A>> PEntityList<A, E> createEntityList(@NotEmpty String property, Class<? super A> type, Class<E> queryType) {
|
||||
return new PEntityList<A, E>(type, queryType, PathMetadata.forProperty(this, property));
|
||||
}
|
||||
|
||||
protected <A> PEntityList<A> createEntityList(@NotEmpty String property, Class<? super A> type, @NotEmpty String entityName) {
|
||||
return new PEntityList<A>(type, entityName, this, property);
|
||||
}
|
||||
|
||||
protected <K, V> PEntityMap<K, V> createEntityMap(@NotEmpty String property, Class<? super K> key, Class<? super V> value, @NotEmpty String entityName) {
|
||||
return new PEntityMap<K, V>(key, value, entityName, this, property);
|
||||
protected <K, V, E extends PEntity<V>> PEntityMap<K, V, E> createEntityMap(@NotEmpty String property, Class<? super K> key, Class<? super V> value, Class<E> queryType) {
|
||||
return new PEntityMap<K, V, E>(key, value, queryType, PathMetadata.forProperty(this, property));
|
||||
}
|
||||
|
||||
protected <A extends Number & Comparable<?>> PNumber<A> createNumber(@NotEmpty String property, Class<A> type) {
|
||||
@ -79,24 +75,24 @@ public class PEntity<D> extends EEntity<D> implements Path<D> {
|
||||
return new PSimple<A>((Class<A>)type, this, path);
|
||||
}
|
||||
|
||||
protected <A> PComponentCollection<A> createSimpleCollection(@NotEmpty String path, Class<A> type) {
|
||||
return new PComponentCollection<A>(type, this,path);
|
||||
protected <A> PComponentCollection<A> createSimpleCollection(@NotEmpty String property, Class<A> type) {
|
||||
return new PComponentCollection<A>(type, this, property);
|
||||
}
|
||||
|
||||
protected <A> PComponentList<A> createSimpleList(@NotEmpty String path, Class<A> type) {
|
||||
return new PComponentList<A>(type, this, path);
|
||||
protected <A> PComponentList<A> createSimpleList(@NotEmpty String property, Class<A> type) {
|
||||
return new PComponentList<A>(type, PathMetadata.forProperty(this, property));
|
||||
}
|
||||
|
||||
protected <K, V> PComponentMap<K, V> createSimpleMap(@NotEmpty String path, Class<? super K> key, Class<? super V> value) {
|
||||
return new PComponentMap<K, V>(key, value, this, path);
|
||||
protected <K, V> PComponentMap<K, V> createSimpleMap(@NotEmpty String property, Class<? super K> key, Class<? super V> value) {
|
||||
return new PComponentMap<K, V>(key, value, this, property);
|
||||
}
|
||||
|
||||
protected PString createString(@NotEmpty String property) {
|
||||
return new PString(this, property);
|
||||
}
|
||||
|
||||
protected <A extends Comparable<?>> PTime<A> createTime(@NotEmpty String propertyName, Class<A> type) {
|
||||
return new PTime<A>(type, this, propertyName);
|
||||
protected <A extends Comparable<?>> PTime<A> createTime(@NotEmpty String property, Class<A> type) {
|
||||
return new PTime<A>(type, this, property);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
package com.mysema.query.types.path;
|
||||
|
||||
import com.mysema.query.types.expr.Expr;
|
||||
import com.mysema.query.util.NotEmpty;
|
||||
|
||||
/**
|
||||
* PEntityList represents entity list paths
|
||||
@ -16,29 +15,34 @@ import com.mysema.query.util.NotEmpty;
|
||||
* @param <D> component type
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class PEntityList<D> extends PEntityCollection<D> implements PList<D> {
|
||||
public class PEntityList<D, E extends PEntity<D>> extends PEntityCollection<D> implements PList<D> {
|
||||
|
||||
public PEntityList(Class<? super D> elementType, @NotEmpty String entityName, PathMetadata<?> metadata) {
|
||||
super(elementType, entityName, metadata);
|
||||
}
|
||||
|
||||
public PEntityList(Class<? super D> elementType, @NotEmpty String entityName, @NotEmpty String var) {
|
||||
super(elementType, entityName, PathMetadata.forVariable(var));
|
||||
}
|
||||
|
||||
public PEntityList(Class<? super D> elementType, @NotEmpty String entityName, Path<?> parent, @NotEmpty String property) {
|
||||
super(elementType, entityName, PathMetadata.forProperty(parent, property));
|
||||
private final Class<E> queryType;
|
||||
|
||||
public PEntityList(Class<? super D> elementType, Class<E> queryType, PathMetadata<?> metadata) {
|
||||
super(elementType, elementType.getSimpleName(), metadata);
|
||||
this.queryType = queryType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PEntity<D> get(Expr<Integer> index) {
|
||||
return new PEntity<D>(elementType, entityName, PathMetadata.forListAccess(this, index));
|
||||
public E get(Expr<Integer> index) {
|
||||
PathMetadata<Integer> md = PathMetadata.forListAccess(this, index);
|
||||
try {
|
||||
return queryType.getConstructor(PathMetadata.class).newInstance(md);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PEntity<D> get(int index) {
|
||||
public E get(int index) {
|
||||
// TODO : cache
|
||||
return new PEntity<D>(elementType, entityName, PathMetadata.forListAccess(this, index));
|
||||
PathMetadata<Integer> md = PathMetadata.forListAccess(this, index);
|
||||
try {
|
||||
return queryType.getConstructor(PathMetadata.class).newInstance(md);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -24,40 +24,34 @@ import com.mysema.query.util.NotEmpty;
|
||||
* @param <V> value type
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class PEntityMap<K, V> extends EMapBase<K, V> implements PMap<K, V> {
|
||||
public class PEntityMap<K, V, E extends PEntity<V>> extends EMapBase<K, V> implements PMap<K, V> {
|
||||
|
||||
private volatile EBoolean isnull, isnotnull;
|
||||
|
||||
private final Class<K> keyType;
|
||||
|
||||
private final PathMetadata<?> metadata;
|
||||
|
||||
private final Class<V> valueType;
|
||||
|
||||
private final Class<E> queryType;
|
||||
|
||||
private final PathMetadata<?> metadata;
|
||||
|
||||
@NotEmpty
|
||||
private final String entityName;
|
||||
|
||||
private final Path<?> root;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public PEntityMap(Class<? super K> keyType, Class<? super V> valueType, @NotEmpty String entityName,
|
||||
PathMetadata<?> metadata) {
|
||||
public PEntityMap(Class<? super K> keyType, Class<? super V> valueType, Class<E> queryType, PathMetadata<?> metadata) {
|
||||
super((Class)Map.class);
|
||||
this.keyType = (Class<K>) keyType;
|
||||
this.valueType = (Class<V>) valueType;
|
||||
this.entityName = entityName;
|
||||
this.queryType = queryType;
|
||||
this.entityName = valueType.getSimpleName();
|
||||
this.metadata = metadata;
|
||||
this.root = metadata.getRoot() != null ? metadata.getRoot() : this;
|
||||
}
|
||||
|
||||
public PEntityMap(Class<? super K> keyType, Class<? super V> valueType, @NotEmpty String entityName, @NotEmpty String var) {
|
||||
this(keyType, valueType, entityName, PathMetadata.forVariable(var));
|
||||
}
|
||||
|
||||
public PEntityMap(Class<? super K> keyType, Class<? super V> valueType, @NotEmpty String entityName, Path<?> parent, @NotEmpty String var) {
|
||||
this(keyType, valueType, entityName, PathMetadata.forProperty(parent, var));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor v) {
|
||||
v.visit(this);
|
||||
@ -71,15 +65,23 @@ public class PEntityMap<K, V> extends EMapBase<K, V> implements PMap<K, V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PEntity<V> get(Expr<K> key) {
|
||||
return new PEntity<V>(valueType, entityName, PathMetadata.forMapAccess(
|
||||
this, key));
|
||||
public E get(Expr<K> key) {
|
||||
PathMetadata<K> md = PathMetadata.forMapAccess(this, key);
|
||||
try {
|
||||
return queryType.getConstructor(PathMetadata.class).newInstance(md);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PEntity<V> get(K key) {
|
||||
return new PEntity<V>(valueType, entityName, PathMetadata.forMapAccess(
|
||||
this, key));
|
||||
public E get(K key) {
|
||||
PathMetadata<K> md = PathMetadata.forMapAccess(this, key);
|
||||
try {
|
||||
return queryType.getConstructor(PathMetadata.class).newInstance(md);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -19,6 +19,8 @@ public class PathInits {
|
||||
|
||||
public static final PathInits DEFAULT = new PathInits();
|
||||
|
||||
public static final PathInits DIRECT = new PathInits("*");
|
||||
|
||||
private final Map<String,PathInits> propertyToInits = new HashMap<String,PathInits>();
|
||||
|
||||
private boolean initAllProps = false;
|
||||
|
||||
@ -8,8 +8,8 @@ package com.mysema.query.hql;
|
||||
import com.mysema.query.Projectable;
|
||||
import com.mysema.query.Query;
|
||||
import com.mysema.query.types.expr.EBoolean;
|
||||
import com.mysema.query.types.path.PCollection;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
|
||||
/**
|
||||
@ -24,27 +24,27 @@ public interface HQLQuery extends Query<HQLQuery>, Projectable {
|
||||
|
||||
<P> HQLQuery innerJoin(PEntity<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery innerJoin(PEntityCollection<P> target, PEntity<P> alias);
|
||||
<P> HQLQuery innerJoin(PCollection<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery innerJoin(PEntityMap<?,P> target, PEntity<P> alias);
|
||||
<P> HQLQuery innerJoin(PEntityMap<?,P,?> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery join(PEntity<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery join(PEntityCollection<P> target, PEntity<P> alias);
|
||||
<P> HQLQuery join(PCollection<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery join(PEntityMap<?,P> target, PEntity<P> alias);
|
||||
<P> HQLQuery join(PEntityMap<?,P,?> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery leftJoin(PEntity<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery leftJoin(PEntityCollection<P> target, PEntity<P> alias);
|
||||
<P> HQLQuery leftJoin(PCollection<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery leftJoin(PEntityMap<?,P> target, PEntity<P> alias);
|
||||
<P> HQLQuery leftJoin(PEntityMap<?,P,?> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery fullJoin(PEntity<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery fullJoin(PEntityCollection<P> target, PEntity<P> alias);
|
||||
<P> HQLQuery fullJoin(PCollection<P> target, PEntity<P> alias);
|
||||
|
||||
<P> HQLQuery fullJoin(PEntityMap<?,P> target, PEntity<P> alias);
|
||||
<P> HQLQuery fullJoin(PEntityMap<?,P,?> target, PEntity<P> alias);
|
||||
|
||||
HQLQuery with(EBoolean condition);
|
||||
|
||||
|
||||
@ -16,12 +16,11 @@ import com.mysema.query.JoinType;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.support.QueryBaseWithProjection;
|
||||
import com.mysema.query.types.expr.EBoolean;
|
||||
import com.mysema.query.types.expr.EEntity;
|
||||
import com.mysema.query.types.expr.Expr;
|
||||
import com.mysema.query.types.operation.OSimple;
|
||||
import com.mysema.query.types.operation.Ops;
|
||||
import com.mysema.query.types.path.PCollection;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PSimple;
|
||||
import com.mysema.query.types.path.PathMetadata;
|
||||
@ -57,12 +56,17 @@ public abstract class HQLQueryBase<SubType extends HQLQueryBase<SubType>> extend
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <D> Expr<D> createAlias(EEntity<?> target, PEntity<D> alias){
|
||||
private <D> Expr<D> createAlias(PEntity<?> target, PEntity<D> alias){
|
||||
return OSimple.create((Class<D>)alias.getType(), Ops.ALIAS, target, alias);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <D> Expr<D> createAlias(PEntityMap<?,D> target, PEntity<D> alias){
|
||||
private <D> Expr<D> createAlias(PCollection<?> target, PEntity<D> alias){
|
||||
return OSimple.create((Class<D>)alias.getType(), Ops.ALIAS, target.asExpr(), alias);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <D> Expr<D> createAlias(PEntityMap<?,D,?> target, PEntity<D> alias){
|
||||
return OSimple.create((Class<D>)alias.getType(), Ops.ALIAS, target, alias);
|
||||
}
|
||||
|
||||
@ -98,12 +102,12 @@ public abstract class HQLQueryBase<SubType extends HQLQueryBase<SubType>> extend
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType fullJoin(PEntityCollection<P> target, PEntity<P> alias) {
|
||||
public <P> SubType fullJoin(PCollection<P> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.FULLJOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType fullJoin(PEntityMap<?,P> target, PEntity<P> alias) {
|
||||
public <P> SubType fullJoin(PEntityMap<?,P,?> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.FULLJOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
@ -117,12 +121,12 @@ public abstract class HQLQueryBase<SubType extends HQLQueryBase<SubType>> extend
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType innerJoin(PEntityCollection<P> target, PEntity<P> alias) {
|
||||
public <P> SubType innerJoin(PCollection<P> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType innerJoin(PEntityMap<?,P> target, PEntity<P> alias) {
|
||||
public <P> SubType innerJoin(PEntityMap<?,P,?> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
@ -132,12 +136,12 @@ public abstract class HQLQueryBase<SubType extends HQLQueryBase<SubType>> extend
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType join(PEntityCollection<P> target, PEntity<P> alias) {
|
||||
public <P> SubType join(PCollection<P> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.JOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType join(PEntityMap<?,P> target, PEntity<P> alias) {
|
||||
public <P> SubType join(PEntityMap<?,P,?> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.JOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
@ -147,12 +151,12 @@ public abstract class HQLQueryBase<SubType extends HQLQueryBase<SubType>> extend
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType leftJoin(PEntityCollection<P> target, PEntity<P> alias) {
|
||||
public <P> SubType leftJoin(PCollection<P> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
|
||||
public <P> SubType leftJoin(PEntityMap<?,P> target, PEntity<P> alias) {
|
||||
public <P> SubType leftJoin(PEntityMap<?,P,?> target, PEntity<P> alias) {
|
||||
getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias));
|
||||
return _this;
|
||||
}
|
||||
|
||||
@ -5,7 +5,11 @@
|
||||
*/
|
||||
package com.mysema.query.jdoql.testdomain;
|
||||
|
||||
import com.mysema.query.types.path.*;
|
||||
import com.mysema.query.types.path.PEntity;
|
||||
import com.mysema.query.types.path.PEntityCollection;
|
||||
import com.mysema.query.types.path.PEntityMap;
|
||||
import com.mysema.query.types.path.PString;
|
||||
import com.mysema.query.types.path.PathMetadata;
|
||||
|
||||
/**
|
||||
* QStore is a Querydsl query type for Store
|
||||
@ -18,9 +22,9 @@ public class QStore extends PEntity<com.mysema.query.jdoql.testdomain.Store>{
|
||||
|
||||
public final PString name = createString("name");
|
||||
|
||||
public final PEntityMap<String,Product> productsByName = createEntityMap("productsByName",String.class,Product.class,"Product");
|
||||
public final PEntityMap<String,Product,QProduct> productsByName = createEntityMap("productsByName",String.class,Product.class,QProduct.class);
|
||||
|
||||
public final PEntityCollection<Product> products = createEntityCollection("products",Product.class, "Product");
|
||||
public final PEntityCollection<Product> products = createEntityCollection("products",Product.class);
|
||||
|
||||
public QProduct productsByName(String key) {
|
||||
return new QProduct(PathMetadata.forMapAccess(productsByName,key));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user