From 46cca610223ff0cdbabb6048be789ca343f08aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Sun, 28 Mar 2010 19:48:19 +0000 Subject: [PATCH] #550200 : replaced JaninoEvaluator with Java Compiler API based implementation --- querydsl-collections/pom.xml | 6 - .../query/collections/AbstractColQuery.java | 21 +-- .../query/collections/ColDeleteClause.java | 9 ++ .../mysema/query/collections/ColQuery.java | 2 +- .../query/collections/ColQueryImpl.java | 16 ++- .../query/collections/ColQuerySerializer.java | 47 ++++--- .../query/collections/ColQueryTemplates.java | 2 +- .../query/collections/ColUpdateClause.java | 9 ++ .../mysema/query/collections/Evaluator.java | 2 +- .../query/collections/EvaluatorFactory.java | 51 +++---- .../query/collections/EvaluatorPredicate.java | 9 +- .../collections/EvaluatorTransformer.java | 10 +- .../query/collections/IteratorFactory.java | 9 +- .../query/collections/JaninoEvaluator.java | 45 ------ .../query/collections/LimitingIterator.java | 4 +- .../com/mysema/query/collections/MiniApi.java | 2 +- .../query/collections/SimpleEvaluator.java | 133 ++++++++++++++++++ .../SingleArgEvaluatorPredicate.java | 9 +- .../query/collections/package-info.java | 2 +- .../ArrayTransformer.java | 11 +- .../collections => util}/MultiComparator.java | 9 +- .../java/com/mysema/query/file/QFile.java | 4 +- .../java/com/mysema/query/file/QFileTest.java | 2 - .../com/mysema/query/file/QFileUtils.java | 5 + .../test/java/com/mysema/query/url/QURL.java | 61 ++++++++ 25 files changed, 348 insertions(+), 132 deletions(-) delete mode 100644 querydsl-collections/src/main/java/com/mysema/query/collections/JaninoEvaluator.java create mode 100644 querydsl-collections/src/main/java/com/mysema/query/collections/SimpleEvaluator.java rename querydsl-collections/src/main/java/com/mysema/{query/collections => util}/ArrayTransformer.java (64%) rename querydsl-collections/src/main/java/com/mysema/{query/collections => util}/MultiComparator.java (86%) create mode 100644 querydsl-collections/src/test/java/com/mysema/query/url/QURL.java diff --git a/querydsl-collections/pom.xml b/querydsl-collections/pom.xml index 62ee6cc69..99c58f2aa 100644 --- a/querydsl-collections/pom.xml +++ b/querydsl-collections/pom.xml @@ -27,12 +27,6 @@ provided - - janino - janino - 2.5.10 - - diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractColQuery.java b/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractColQuery.java index 8bd7b2e8d..c47375f76 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractColQuery.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractColQuery.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ @@ -35,6 +35,7 @@ import com.mysema.query.types.Order; import com.mysema.query.types.OrderSpecifier; import com.mysema.query.types.Path; import com.mysema.query.types.expr.EBoolean; +import com.mysema.util.MultiComparator; import com.mysema.util.MultiIterator; /** @@ -123,15 +124,15 @@ public abstract class AbstractColQuery> it = handleFromWhereMultiSource(sources); } - // group by - if (!md.getGroupBy().isEmpty()){ - // TODO - - // having - if (md.getHaving() != null){ - it = iteratorFactory.multiArgFilter(it, sources, md.getHaving()); - } - } +// // group by +// if (!md.getGroupBy().isEmpty()){ +// // TODO +// +// // having +// if (md.getHaving() != null){ +// it = iteratorFactory.multiArgFilter(it, sources, md.getHaving()); +// } +// } if (it.hasNext()) { // order diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColDeleteClause.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColDeleteClause.java index c623d4c11..d34f7269a 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColDeleteClause.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColDeleteClause.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ package com.mysema.query.collections; import java.util.Collection; @@ -19,6 +24,10 @@ public class ColDeleteClause implements DeleteClause>{ private final Collection col; + public ColDeleteClause(Path expr, Collection col){ + this(EvaluatorFactory.DEFAULT, expr, col); + } + public ColDeleteClause(EvaluatorFactory ef, Path expr, Collection col){ this.query = new ColQueryImpl(ef).from(expr, col); this.expr = expr; diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuery.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuery.java index 7e9d77655..953ced364 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuery.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuery.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryImpl.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryImpl.java index 0aae54f53..eed1153dd 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryImpl.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ @@ -17,14 +17,28 @@ import com.mysema.query.QueryMetadata; */ public class ColQueryImpl extends AbstractColQuery implements ColQuery, Cloneable{ + /** + * Create a new ColQueryImpl instance + */ public ColQueryImpl() { super(new DefaultQueryMetadata(), EvaluatorFactory.DEFAULT); } + /** + * Create a new ColQueryImpl instance + * + * @param evaluatorFactory + */ public ColQueryImpl(EvaluatorFactory evaluatorFactory) { super(new DefaultQueryMetadata(), evaluatorFactory); } + /** + * Create a new ColQueryImpl instance + * + * @param metadata + * @param evaluatorFactory + */ public ColQueryImpl(QueryMetadata metadata, EvaluatorFactory evaluatorFactory) { super(metadata, evaluatorFactory); } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuerySerializer.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuerySerializer.java index 834dc8f84..ffc05e8bb 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuerySerializer.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQuerySerializer.java @@ -1,12 +1,11 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ package com.mysema.query.collections; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; @@ -28,13 +27,6 @@ import com.mysema.query.types.Template; * @version $Id$ */ public final class ColQuerySerializer extends SerializerBase { - - private static final List nonGeneric = Arrays.asList( - PathType.ARRAYVALUE, - PathType.ARRAYVALUE_CONSTANT, - PathType.PROPERTY, - PathType.VARIABLE - ); public ColQuerySerializer(ColQueryTemplates patterns) { super(patterns); @@ -44,7 +36,8 @@ public final class ColQuerySerializer extends SerializerBase public void visit(Path path) { PathType pathType = path.getMetadata().getPathType(); - if (pathType == PathType.PROPERTY){ + if (pathType == PathType.PROPERTY){ + // TODO : move this to PathMetadata ?!? String prefix = "get"; if (path.getType() != null && path.getType().equals(Boolean.class)) { prefix = "is"; @@ -54,9 +47,6 @@ public final class ColQuerySerializer extends SerializerBase append(StringUtils.capitalize(path.getMetadata().getExpression().toString()) + "()"); }else{ - if (!nonGeneric.contains(pathType)){ - append("((").append(path.getType().getName()).append(")"); - } List> args = new ArrayList>(2); if (path.getMetadata().getParent() != null){ args.add((Expr)path.getMetadata().getParent()); @@ -71,10 +61,7 @@ public final class ColQuerySerializer extends SerializerBase }else{ handle(args.get(element.getIndex())); } - } - if (!nonGeneric.contains(pathType)){ - append(")"); - } + } } } @@ -109,9 +96,29 @@ public final class ColQuerySerializer extends SerializerBase @Override protected void visitOperation(Class type, Operator operator, List> args) { - if (operator.equals(Ops.STRING_CAST)) { + if (args.size() == 2 + && Number.class.isAssignableFrom(args.get(0).getType()) + && Number.class.isAssignableFrom(args.get(1).getType())){ + + if (operator == Ops.AFTER){ + handle(args.get(0)).append(" > ").handle(args.get(1)); + return; + }else if (operator == Ops.BEFORE){ + handle(args.get(0)).append(" < ").handle(args.get(1)); + return; + }else if (operator == Ops.AOE){ + handle(args.get(0)).append(" >= ").handle(args.get(1)); + return; + }else if (operator == Ops.BOE){ + handle(args.get(0)).append(" <= ").handle(args.get(1)); + return; + } + // TODO : Ops.BETWEEN + } + + if (operator == Ops.STRING_CAST) { visitCast(operator, args.get(0), String.class); - } else if (operator.equals(Ops.NUMCAST)) { + } else if (operator == Ops.NUMCAST) { visitCast(operator, args.get(0), (Class) ((Constant) args.get(1)).getConstant()); } else { super.visitOperation(type, operator, args); @@ -119,7 +126,7 @@ public final class ColQuerySerializer extends SerializerBase } @Override - public void visit(SubQuery expr) { + public void visit(SubQuery expr) { throw new IllegalArgumentException("Not supported"); } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java index 7f56c6333..b4680749a 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColQueryTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ColUpdateClause.java b/querydsl-collections/src/main/java/com/mysema/query/collections/ColUpdateClause.java index be468536e..5ca62107a 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ColUpdateClause.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/ColUpdateClause.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ package com.mysema.query.collections; import com.mysema.query.dml.UpdateClause; @@ -15,6 +20,10 @@ public class ColUpdateClause implements UpdateClause>{ private final Path expr; + public ColUpdateClause(Path expr, Iterable col){ + this(EvaluatorFactory.DEFAULT, expr, col); + } + public ColUpdateClause(EvaluatorFactory ef, Path expr, Iterable col){ this.query = new ColQueryImpl(ef).from(expr, col); this.expr = expr; diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/Evaluator.java b/querydsl-collections/src/main/java/com/mysema/query/collections/Evaluator.java index 71e4cfa34..1d34d68dc 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/Evaluator.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/Evaluator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFactory.java b/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFactory.java index 6cb34b3d5..cd9006d6c 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFactory.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFactory.java @@ -1,6 +1,11 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ package com.mysema.query.collections; -import java.util.Arrays; +import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; @@ -8,12 +13,7 @@ import java.util.Set; import net.jcip.annotations.Immutable; -import org.codehaus.janino.CompileException; -import org.codehaus.janino.ExpressionEvaluator; -import org.codehaus.janino.Parser.ParseException; -import org.codehaus.janino.Scanner.ScanException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.commons.lang.ClassUtils; import com.mysema.query.QueryException; import com.mysema.query.types.Expr; @@ -25,8 +25,6 @@ import com.mysema.query.types.Expr; @Immutable public class EvaluatorFactory { - private static final Logger logger = LoggerFactory.getLogger(EvaluatorFactory.class); - public static final EvaluatorFactory DEFAULT = new EvaluatorFactory(ColQueryTemplates.DEFAULT); private final ColQueryTemplates templates; @@ -39,10 +37,10 @@ public class EvaluatorFactory { ColQuerySerializer serializer = new ColQuerySerializer(templates); serializer.handle(projection); Map constantToLabel = serializer.getConstantToLabel(); - final String javaSource = serializer.toString(); - final Object[] constArray = constantToLabel.keySet().toArray(); - final Class[] types = new Class[constArray.length + sources.size()]; - final String[] names = new String[constArray.length + sources.size()]; + String javaSource = serializer.toString(); + Object[] constArray = constantToLabel.keySet().toArray(); + Class[] types = new Class[constArray.length + sources.size()]; + String[] names = new String[constArray.length + sources.size()]; for (int i = 0; i < constArray.length; i++) { if (List.class.isAssignableFrom(constArray[i].getClass())){ types[i] = List.class; @@ -61,21 +59,24 @@ public class EvaluatorFactory { types[off + i] = sources.get(i).getType(); names[off + i] = sources.get(i).toString(); } - - if (logger.isInfoEnabled()) { - logger.info(javaSource + " " + Arrays.asList(names) + " " + Arrays.asList(types)); + + // normalize types + for (int i = 0; i < types.length; i++){ + if (ClassUtils.wrapperToPrimitive(types[i]) != null){ + types[i] = ClassUtils.wrapperToPrimitive(types[i]); + } } try { - ExpressionEvaluator evaluator = new ExpressionEvaluator(javaSource, projection.getType(), names, types); - return new JaninoEvaluator(javaSource, evaluator, names, constArray); - - } catch (CompileException e) { - throw new QueryException(e.getMessage() + " with source " + javaSource, e); - } catch (ParseException e) { - throw new QueryException(e.getMessage() + " with source " + javaSource, e); - } catch (ScanException e) { - throw new QueryException(e.getMessage() + " with source " + javaSource, e); + return new SimpleEvaluator(javaSource, projection.getType(), names, types, constArray); + } catch (IOException e) { + throw new QueryException(e); + } catch (SecurityException e) { + throw new QueryException(e); + } catch (ClassNotFoundException e) { + throw new QueryException(e); + } catch (NoSuchMethodException e) { + throw new QueryException(e); } } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorPredicate.java b/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorPredicate.java index fab492a79..8b3e0fd55 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorPredicate.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorPredicate.java @@ -1,10 +1,17 @@ -/** +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. * */ package com.mysema.query.collections; import org.apache.commons.collections15.Predicate; +/** + * @author tiwe + * + * @param + */ public final class EvaluatorPredicate implements Predicate { private final Evaluator ev; diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorTransformer.java b/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorTransformer.java index b620ccfe8..cf75ebf91 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorTransformer.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorTransformer.java @@ -1,10 +1,18 @@ -/** +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. * */ package com.mysema.query.collections; import org.apache.commons.collections15.Transformer; +/** + * @author tiwe + * + * @param + * @param + */ public final class EvaluatorTransformer implements Transformer { private final Evaluator ev; diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/IteratorFactory.java b/querydsl-collections/src/main/java/com/mysema/query/collections/IteratorFactory.java index a3fba50c1..b97c8d047 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/IteratorFactory.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/IteratorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ @@ -14,6 +14,7 @@ import org.apache.commons.collections15.IteratorUtils; import com.mysema.query.types.Expr; import com.mysema.query.types.expr.EBoolean; +import com.mysema.util.ArrayTransformer; /** * IteratorFactory provides Iterator utilities @@ -35,7 +36,7 @@ public class IteratorFactory { return multiArgFilter(source, ev); } - private Iterator multiArgFilter(Iterator source, final Evaluator ev) { + private Iterator multiArgFilter(Iterator source, Evaluator ev) { return IteratorUtils.filteredIterator(source, new EvaluatorPredicate(ev)); } @@ -44,11 +45,11 @@ public class IteratorFactory { return transform(source, ev); } - private Iterator transform(Iterator source, final Evaluator ev) { + private Iterator transform(Iterator source, Evaluator ev) { return IteratorUtils.transformedIterator(source, new EvaluatorTransformer(ev)); } - public Iterator singleArgFilter(Iterator source, final Evaluator ev) { + public Iterator singleArgFilter(Iterator source, Evaluator ev) { return IteratorUtils.filteredIterator(source, new SingleArgEvaluatorPredicate(ev)); } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/JaninoEvaluator.java b/querydsl-collections/src/main/java/com/mysema/query/collections/JaninoEvaluator.java deleted file mode 100644 index 46729f4b8..000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/JaninoEvaluator.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * - */ -package com.mysema.query.collections; - -import java.lang.reflect.InvocationTargetException; - -import org.codehaus.janino.ExpressionEvaluator; - -public final class JaninoEvaluator implements Evaluator { - - private final String javaSource; - - private final ExpressionEvaluator evaluator; - - private final String[] names; - - private final Object[] constArray; - - JaninoEvaluator(String javaSource, ExpressionEvaluator evaluator, String[] names, Object[] constArray) { - this.javaSource = javaSource; - this.evaluator = evaluator; - this.names = names.clone(); - this.constArray = constArray.clone(); - } - - @Override - public T evaluate(Object... args) { - try { - args = EvaluatorFactory.combine(constArray.length + args.length, constArray, args); - return (T) evaluator.evaluate(args); - } catch (InvocationTargetException e) { - StringBuilder builder = new StringBuilder(); - builder.append("Caught exception when evaluating '").append(javaSource); - builder.append("' with arguments "); - for (int i = 0; i < args.length; i++){ - builder.append(names[i]).append(" = ").append(args[i]); - if (i < args.length -1){ - builder.append(", "); - } - } - throw new RuntimeException(builder.toString(), e); - } - } -} \ No newline at end of file diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/LimitingIterator.java b/querydsl-collections/src/main/java/com/mysema/query/collections/LimitingIterator.java index a03b16f75..6472df453 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/LimitingIterator.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/LimitingIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ @@ -58,7 +58,7 @@ public class LimitingIterator implements Iterator { @Override public void remove() { - + throw new UnsupportedOperationException(); } } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/MiniApi.java b/querydsl-collections/src/main/java/com/mysema/query/collections/MiniApi.java index ad323c6c5..c8dd19f8f 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/MiniApi.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/MiniApi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/SimpleEvaluator.java b/querydsl-collections/src/main/java/com/mysema/query/collections/SimpleEvaluator.java new file mode 100644 index 000000000..1b717bc19 --- /dev/null +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/SimpleEvaluator.java @@ -0,0 +1,133 @@ +package com.mysema.query.collections; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; + +import org.apache.commons.io.FileUtils; + +import com.mysema.query.QueryException; +import com.mysema.util.JavaWriter; +import com.mysema.util.SimpleCompiler; + +/** + * @author tiwe + * + */ +public class SimpleEvaluator implements Evaluator{ + + private static final File dir; + + private static final ClassLoader loader; + + private static final String classpath; + + private static final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + static{ + try { + dir = new File(System.getProperty("java.io.tmpdir"), "files"); + dir.mkdirs(); + + URLClassLoader parent = (URLClassLoader) SimpleEvaluator.class.getClassLoader(); + classpath = SimpleCompiler.getClassPath(parent); + loader = new URLClassLoader(new URL[]{dir.toURI().toURL()}, parent); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + private final Method method; + + private final Object[] constants; + + public SimpleEvaluator( + String source, + Class projectionType, + String[] names, + Class[] types, + Object[] constants) + throws IOException, ClassNotFoundException, SecurityException, NoSuchMethodException { + this.constants = constants; + + // create id for evaluator + String id = toId(source, projectionType, types); + + // compile + File javaFile = new File(dir, id+".java"); + if (!new File(dir, id+".class").exists()){ +// long start = System.currentTimeMillis(); + // create source + StringWriter writer = new StringWriter(); + JavaWriter javaw = new JavaWriter(writer); + javaw.beginClass(id, null); + String[] params = new String[names.length]; + for (int i = 0; i < params.length; i++){ + params[i] = toName(types[i]) + " " + names[i]; + } + + javaw.beginStaticMethod(toName(projectionType), "eval", params); + javaw.line("return ", source, ";"); + javaw.end(); + javaw.end(); + + FileUtils.writeByteArrayToFile(javaFile, writer.toString().getBytes("ISO-8859-1")); + compiler.run(null, null, null, "-classpath", classpath, javaFile.getAbsolutePath()); + // source file is not needed anymore + javaFile.delete(); +// long duration = System.currentTimeMillis() - start; +// System.out.println("- " + duration + ": " + source); + } + + // load class + Class cl = loader.loadClass(id); + method = cl.getMethod("eval", types); + } + + private static String toId(String source, Class projectionType, Class[] types) { + StringBuilder b = new StringBuilder("Q"); + b.append("_").append(Math.abs(source.hashCode())); + b.append("_").append(Math.abs(projectionType.hashCode())); + for (Class type : types){ + b.append("_").append(Math.abs(type.hashCode())); + } + return b.toString(); + } + + private static String toName(Class cl){ + if (cl.isArray()){ + return toName(cl.getComponentType())+"[]"; + }else if (cl.getPackage() == null || cl.getPackage().getName().equals("java.lang")){ + return cl.getSimpleName(); + }else{ + return cl.getName().replace('$', '.'); + } + } + + @SuppressWarnings("unchecked") + @Override + public T evaluate(Object... args) { + try { + if (constants.length > 0){ + args = EvaluatorFactory.combine(constants.length + args.length, constants, args); + } + return (T) method.invoke(null, args); + } catch (IllegalAccessException e) { + throw new QueryException(e); + } catch (InvocationTargetException e) { + throw new QueryException(e); + } + } + +} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/SingleArgEvaluatorPredicate.java b/querydsl-collections/src/main/java/com/mysema/query/collections/SingleArgEvaluatorPredicate.java index 26897118c..f320bb290 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/SingleArgEvaluatorPredicate.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/SingleArgEvaluatorPredicate.java @@ -1,10 +1,17 @@ -/** +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. * */ package com.mysema.query.collections; import org.apache.commons.collections15.Predicate; +/** + * @author tiwe + * + * @param + */ public final class SingleArgEvaluatorPredicate implements Predicate { private final Evaluator ev; diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java b/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java index f35eb25d5..99c6b95c0 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java +++ b/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/ArrayTransformer.java b/querydsl-collections/src/main/java/com/mysema/util/ArrayTransformer.java similarity index 64% rename from querydsl-collections/src/main/java/com/mysema/query/collections/ArrayTransformer.java rename to querydsl-collections/src/main/java/com/mysema/util/ArrayTransformer.java index b2ad9fd74..e3fde01c6 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/ArrayTransformer.java +++ b/querydsl-collections/src/main/java/com/mysema/util/ArrayTransformer.java @@ -1,10 +1,17 @@ -/** +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. * */ -package com.mysema.query.collections; +package com.mysema.util; import org.apache.commons.collections15.Transformer; +/** + * @author tiwe + * + * @param + */ public final class ArrayTransformer implements Transformer { @SuppressWarnings("unchecked") diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/MultiComparator.java b/querydsl-collections/src/main/java/com/mysema/util/MultiComparator.java similarity index 86% rename from querydsl-collections/src/main/java/com/mysema/query/collections/MultiComparator.java rename to querydsl-collections/src/main/java/com/mysema/util/MultiComparator.java index 53c49e931..6e29e1530 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/MultiComparator.java +++ b/querydsl-collections/src/main/java/com/mysema/util/MultiComparator.java @@ -1,17 +1,17 @@ /* - * Copyright (c) 2009 Mysema Ltd. + * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ -package com.mysema.query.collections; +package com.mysema.util; import java.io.Serializable; import java.util.Comparator; -import net.jcip.annotations.Immutable; - import org.apache.commons.collections15.comparators.ComparableComparator; +import com.mysema.query.collections.Evaluator; + /** @@ -20,7 +20,6 @@ import org.apache.commons.collections15.comparators.ComparableComparator; * @author tiwe * @version $Id$ */ -@Immutable public class MultiComparator implements Comparator, Serializable { private static final long serialVersionUID = 1121416260773566299L; diff --git a/querydsl-collections/src/test/java/com/mysema/query/file/QFile.java b/querydsl-collections/src/test/java/com/mysema/query/file/QFile.java index 38dbf1706..31f8b560e 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/file/QFile.java +++ b/querydsl-collections/src/test/java/com/mysema/query/file/QFile.java @@ -26,10 +26,10 @@ public class QFile extends PComparable{ private static final long serialVersionUID = -7703329992523284173L; - private static final String GET_CONTENT = QFile.class.getName() + "Utils.readFileToString({0}, {1})"; - public static final QFile any = new QFile("any"); + private static final String GET_CONTENT = QFile.class.getName() + "Utils.readFileToString({0}, {1})"; + public static Iterable walk(File dir){ return new DirectoryWalk(dir); } diff --git a/querydsl-collections/src/test/java/com/mysema/query/file/QFileTest.java b/querydsl-collections/src/test/java/com/mysema/query/file/QFileTest.java index d267d6d2e..f41d55db2 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/file/QFileTest.java +++ b/querydsl-collections/src/test/java/com/mysema/query/file/QFileTest.java @@ -8,7 +8,6 @@ package com.mysema.query.file; import java.io.File; import java.util.Map; -import org.junit.Ignore; import org.junit.Test; import com.mysema.query.collections.MiniApi; @@ -39,7 +38,6 @@ public class QFileTest { } @Test - @Ignore public void getContent(){ QFile anyFile = QFile.any; Map rv = MiniApi diff --git a/querydsl-collections/src/test/java/com/mysema/query/file/QFileUtils.java b/querydsl-collections/src/test/java/com/mysema/query/file/QFileUtils.java index c05bc19ba..6d1192028 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/file/QFileUtils.java +++ b/querydsl-collections/src/test/java/com/mysema/query/file/QFileUtils.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ package com.mysema.query.file; import java.io.File; diff --git a/querydsl-collections/src/test/java/com/mysema/query/url/QURL.java b/querydsl-collections/src/test/java/com/mysema/query/url/QURL.java new file mode 100644 index 000000000..826144e33 --- /dev/null +++ b/querydsl-collections/src/test/java/com/mysema/query/url/QURL.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.mysema.query.url; + +import static com.mysema.query.types.path.PathMetadataFactory.forVariable; + +import java.net.URL; + +import com.mysema.query.types.PathMetadata; +import com.mysema.query.types.path.PEntity; +import com.mysema.query.types.path.PNumber; +import com.mysema.query.types.path.PSimple; +import com.mysema.query.types.path.PString; +import com.mysema.query.types.path.PathMetadataFactory; + +/** + * @author tiwe + * + */ +public class QURL extends PEntity{ + + private static final long serialVersionUID = 9048088068716893900L; + + public final PString authority = createString("authority"); + + public final PSimple content = createSimple("content",Object.class); + + public final PNumber defaultPort = createNumber("defaultPort",Integer.class); + + public final PString file = createString("file"); + + public final PString host = createString("host"); + + public final PString path = createString("path"); + + public final PNumber port = createNumber("port",Integer.class); + + public final PString protocol = createString("protocol"); + + public final PString query = createString("query"); + + public final PString ref = createString("ref"); + + public final PString userInfo = createString("userInfo"); + + public QURL(PathMetadata metadata) { + super(URL.class, metadata); + } + + public QURL(QURL parent, String property) { + super(URL.class, PathMetadataFactory.forProperty(parent, property)); + } + + public QURL(String variable) { + super(URL.class, forVariable(variable)); + } + +}