mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-30 21:08:30 +08:00
added Eclipse JDT based compilation
This commit is contained in:
parent
92cbdaf867
commit
6bdaa71de4
12
pom.xml
12
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mysema.codegen</groupId>
|
||||
<artifactId>codegen</artifactId>
|
||||
<version>0.5.1</version>
|
||||
<version>0.5.2</version>
|
||||
<name>Codegen</name>
|
||||
<description>Code generation and compilation for Java</description>
|
||||
<parent>
|
||||
@ -20,6 +20,7 @@
|
||||
<commons.collections.version>4.01</commons.collections.version>
|
||||
<commons.lang.version>3.0.1</commons.lang.version>
|
||||
<guava.version>11.0.2</guava.version>
|
||||
<ecj.version>3.7.2</ecj.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -28,6 +29,12 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<version>11.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jdt.core.compiler</groupId>
|
||||
<artifactId>ecj</artifactId>
|
||||
<version>${ecj.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
@ -47,7 +54,8 @@
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.CR3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
119
src/main/java/com/mysema/codegen/AbstractEvaluatorFactory.java
Normal file
119
src/main/java/com/mysema/codegen/AbstractEvaluatorFactory.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Mysema Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
package com.mysema.codegen;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
|
||||
/**
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractEvaluatorFactory implements EvaluatorFactory{
|
||||
|
||||
protected ClassLoader loader;
|
||||
|
||||
/**
|
||||
* @param source
|
||||
* @param projection
|
||||
* @param names
|
||||
* @param types
|
||||
* @param id
|
||||
* @param constants
|
||||
* @throws IOException
|
||||
*/
|
||||
protected abstract void compile(String source, ClassType projection, String[] names, Type[] types,
|
||||
String id, Map<String, Object> constants) throws IOException;
|
||||
|
||||
|
||||
@Override
|
||||
public <T> Evaluator<T> createEvaluator(String source, Class<? extends T> projectionType,
|
||||
String[] names, Class<?>[] classes, Map<String, Object> constants) {
|
||||
Type[] types = new Type[classes.length];
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
types[i] = new ClassType(TypeCategory.SIMPLE, classes[i]);
|
||||
}
|
||||
return createEvaluator(source, new ClassType(TypeCategory.SIMPLE, projectionType), names,
|
||||
types, classes, constants);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Evaluator instance
|
||||
*
|
||||
* @param <T>
|
||||
* projection type
|
||||
* @param source
|
||||
* expression in Java source code form
|
||||
* @param projection
|
||||
* type of the source expression
|
||||
* @param names
|
||||
* names of the arguments
|
||||
* @param types
|
||||
* types of the arguments
|
||||
* @param constants
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> Evaluator<T> createEvaluator(String source, ClassType projection, String[] names,
|
||||
Type[] types, Class<?>[] classes, Map<String, Object> constants) {
|
||||
try {
|
||||
String id = toId(source, projection.getJavaClass(), types);
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = loader.loadClass(id);
|
||||
} catch (ClassNotFoundException e) {
|
||||
compile(source, projection, names, types, id, constants);
|
||||
// reload
|
||||
clazz = loader.loadClass(id);
|
||||
}
|
||||
|
||||
Object object = !constants.isEmpty() ? clazz.newInstance() : null;
|
||||
|
||||
for (Map.Entry<String, Object> entry : constants.entrySet()) {
|
||||
Field field = clazz.getField(entry.getKey());
|
||||
field.set(object, entry.getValue());
|
||||
}
|
||||
|
||||
Method method = clazz.getMethod("eval", classes);
|
||||
return new MethodEvaluator<T>(method, object, (Class) projection.getJavaClass());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (SecurityException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (IOException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new CodegenException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected String toId(String source, Class<?> returnType, Type... types) {
|
||||
StringBuilder b = new StringBuilder("Q");
|
||||
b.append("_").append(source.hashCode());
|
||||
b.append("_").append(returnType.getName().hashCode());
|
||||
for (Type type : types) {
|
||||
b.append("_").append(type.getFullName().hashCode());
|
||||
}
|
||||
return b.toString().replace('-', '0');
|
||||
}
|
||||
|
||||
}
|
||||
320
src/main/java/com/mysema/codegen/ECJEvaluatorFactory.java
Normal file
320
src/main/java/com/mysema/codegen/ECJEvaluatorFactory.java
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Mysema Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
package com.mysema.codegen;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import org.eclipse.jdt.core.compiler.CategorizedProblem;
|
||||
import org.eclipse.jdt.core.compiler.CharOperation;
|
||||
import org.eclipse.jdt.internal.compiler.ClassFile;
|
||||
import org.eclipse.jdt.internal.compiler.CompilationResult;
|
||||
import org.eclipse.jdt.internal.compiler.Compiler;
|
||||
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
|
||||
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
|
||||
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
|
||||
import org.eclipse.jdt.internal.compiler.IProblemFactory;
|
||||
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
|
||||
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
|
||||
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
|
||||
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
|
||||
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
|
||||
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
|
||||
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
|
||||
import org.eclipse.jdt.internal.compiler.tool.EclipseFileManager;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
import com.mysema.codegen.model.SimpleType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.support.ClassUtils;
|
||||
|
||||
/**
|
||||
* EvaluatorFactory is a factory implementation for creating Evaluator instances
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public class ECJEvaluatorFactory extends AbstractEvaluatorFactory {
|
||||
|
||||
private final MemFileManager fileManager;
|
||||
|
||||
private final ClassLoader parentClassLoader;
|
||||
|
||||
private final List<String> problemList = Lists.newArrayList();
|
||||
|
||||
private final CompilerOptions compilerOptions;
|
||||
|
||||
public static CompilerOptions getDefaultCompilerOptions() {
|
||||
String javaSpecVersion = System.getProperty("java.specification.version");
|
||||
Map<String, Object> settings = Maps.newHashMap();
|
||||
settings.put(CompilerOptions.OPTION_Source, javaSpecVersion);
|
||||
settings.put(CompilerOptions.OPTION_TargetPlatform, javaSpecVersion);
|
||||
settings.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
|
||||
return new CompilerOptions(settings);
|
||||
}
|
||||
|
||||
public ECJEvaluatorFactory(ClassLoader parent) {
|
||||
this(parent, getDefaultCompilerOptions());
|
||||
}
|
||||
|
||||
public ECJEvaluatorFactory(ClassLoader parent, CompilerOptions compilerOptions) {
|
||||
this.parentClassLoader = parent;
|
||||
this.fileManager = new MemFileManager(parent, new EclipseFileManager(Locale.getDefault(), Charset.defaultCharset()));
|
||||
this.loader = fileManager.getClassLoader(StandardLocation.CLASS_OUTPUT);
|
||||
this.compilerOptions = compilerOptions;
|
||||
}
|
||||
|
||||
protected void compile(String source, ClassType projectionType, String[] names, Type[] types,
|
||||
String id, Map<String, Object> constants) throws IOException {
|
||||
// create source
|
||||
StringWriter writer = new StringWriter();
|
||||
JavaWriter javaw = new JavaWriter(writer);
|
||||
SimpleType idType = new SimpleType(id, "", id);
|
||||
javaw.beginClass(idType, null);
|
||||
Parameter[] params = new Parameter[names.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
params[i] = new Parameter(names[i], types[i]);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : constants.entrySet()) {
|
||||
Type type = new ClassType(TypeCategory.SIMPLE, ClassUtils.normalize(entry.getValue().getClass()));
|
||||
javaw.publicField(type, entry.getKey());
|
||||
}
|
||||
|
||||
if (constants.isEmpty()) {
|
||||
javaw.beginStaticMethod(projectionType, "eval", params);
|
||||
} else {
|
||||
javaw.beginPublicMethod(projectionType, "eval", params);
|
||||
}
|
||||
javaw.append(source);
|
||||
javaw.end();
|
||||
javaw.end();
|
||||
|
||||
// compile
|
||||
final char[] targetContents = writer.toString().toCharArray();
|
||||
final String targetName = idType.getFullName();
|
||||
final ICompilationUnit[] targetCompilationUnits = new ICompilationUnit[] { new ICompilationUnit() {
|
||||
@Override
|
||||
public char[] getContents() {
|
||||
return targetContents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getMainTypeName() {
|
||||
int dot = targetName.lastIndexOf('.');
|
||||
if (dot > 0)
|
||||
return targetName.substring(dot + 1).toCharArray();
|
||||
else
|
||||
return targetName.toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getPackageName() {
|
||||
StringTokenizer tok = new StringTokenizer(targetName, ".");
|
||||
char[][] result = new char[tok.countTokens() - 1][];
|
||||
for (int j = 0; j < result.length; j++) {
|
||||
result[j] = tok.nextToken().toCharArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getFileName() {
|
||||
return CharOperation.concat(targetName.toCharArray(), ".java".toCharArray());
|
||||
}
|
||||
} };
|
||||
|
||||
INameEnvironment env = new INameEnvironment() {
|
||||
|
||||
private String join(char[][] compoundName, char separator) {
|
||||
if (compoundName == null) {
|
||||
return "";
|
||||
} else {
|
||||
List<String> parts = Lists.newArrayListWithCapacity(compoundName.length);
|
||||
for (char[] part: compoundName) {
|
||||
parts.add(new String(part));
|
||||
}
|
||||
return Joiner.on(separator).join(parts);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
|
||||
return findType(join(compoundTypeName, '.'));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
|
||||
return findType(CharOperation.arrayConcat(packageName, typeName));
|
||||
}
|
||||
|
||||
private boolean isClass(String result) {
|
||||
if (Strings.isNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
// if it's the class we're compiling, then of course it's a class
|
||||
if (result.equals(targetName)) {
|
||||
return true;
|
||||
}
|
||||
InputStream is = null;
|
||||
try {
|
||||
// if this is a class we've already compiled, it's a class
|
||||
is = loader.getResourceAsStream(result);
|
||||
if (is == null) {
|
||||
// use our normal class loader now...
|
||||
String resourceName = result.replace('.', '/') + ".class";
|
||||
is = parentClassLoader.getResourceAsStream(resourceName);
|
||||
if (is == null && !result.contains(".")) {
|
||||
// we couldn't find the class, and it has no package; is it a core class?
|
||||
is = parentClassLoader.getResourceAsStream("java/lang/" + resourceName);
|
||||
}
|
||||
}
|
||||
if (is == null) {
|
||||
return false; // if it's a class, we sure couldn't load it
|
||||
} else {
|
||||
return true; // we actually loaded the class, so it must be one
|
||||
}
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ex) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackage(char[][] parentPackageName, char[] packageName) {
|
||||
// if the parent is a class, the child can't be a package
|
||||
String parent = join(parentPackageName, '.');
|
||||
if (isClass(parent))
|
||||
return false;
|
||||
|
||||
// if the child is a class, it's not a package
|
||||
String qualifiedName = (parent.isEmpty() ? "" : parent + ".") + new String(packageName);
|
||||
return !isClass(qualifiedName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
private NameEnvironmentAnswer findType(String className) {
|
||||
String resourceName = className.replace('.', '/') + ".class";
|
||||
InputStream is = null;
|
||||
try {
|
||||
// we're only asking ECJ to compile a single class; we shouldn't need this
|
||||
if (className.equals(targetName)) {
|
||||
return new NameEnvironmentAnswer(targetCompilationUnits[0], null);
|
||||
}
|
||||
|
||||
is = loader.getResourceAsStream(resourceName);
|
||||
if (is == null) {
|
||||
is = parentClassLoader.getResourceAsStream(resourceName);
|
||||
}
|
||||
|
||||
if (is != null) {
|
||||
ClassFileReader cfr = new ClassFileReader(ByteStreams.toByteArray(is), className.toCharArray(), true);
|
||||
return new NameEnvironmentAnswer(cfr, null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassFormatException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
ICompilerRequestor requestor = new ICompilerRequestor() {
|
||||
|
||||
@Override
|
||||
public void acceptResult(CompilationResult result) {
|
||||
if (result.hasErrors()) {
|
||||
for (CategorizedProblem problem: result.getProblems()) {
|
||||
if (problem.isError()) {
|
||||
problemList.add(problem.getMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ClassFile clazz: result.getClassFiles()) {
|
||||
try {
|
||||
MemJavaFileObject jfo = (MemJavaFileObject) fileManager
|
||||
.getJavaFileForOutput(StandardLocation.CLASS_OUTPUT,
|
||||
new String(clazz.fileName()), JavaFileObject.Kind.CLASS, null);
|
||||
OutputStream os = jfo.openOutputStream();
|
||||
os.write(clazz.getBytes());
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
problemList.clear();
|
||||
|
||||
IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
|
||||
IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());
|
||||
|
||||
try {
|
||||
//Compiler compiler = new Compiler(env, policy, getCompilerOptions(), requestor, problemFactory, true);
|
||||
Compiler compiler = new Compiler(env, policy, compilerOptions, requestor, problemFactory);
|
||||
compiler.compile(targetCompilationUnits);
|
||||
if (!problemList.isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String problem: problemList) {
|
||||
sb.append("\t").append(problem).append("\n");
|
||||
}
|
||||
throw new CodegenException("Compilation of " + id + " failed:\n" + source + "\n" + sb.toString());
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
// if we encountered an IOException, unbox and throw it;
|
||||
// if we encountered a ClassFormatException, box it as an IOException and throw it
|
||||
// otherwise, it's a legit RuntimeException,
|
||||
// not one of our checked exceptions boxed as unchecked; just rethrow
|
||||
Throwable cause = ex.getCause();
|
||||
if (cause != null) {
|
||||
if (cause instanceof IOException)
|
||||
throw (IOException)cause;
|
||||
else if (cause instanceof ClassFormatException)
|
||||
throw new IOException(cause);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public CompilerOptions getCompilerOptions() {
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,180 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Mysema Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.mysema.codegen;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
import com.mysema.codegen.model.SimpleType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.support.ClassUtils;
|
||||
|
||||
/**
|
||||
* EvaluatorFactory is a factory implementation for creating Evaluator instances
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*
|
||||
* @author pgrant
|
||||
*/
|
||||
public class EvaluatorFactory {
|
||||
public interface EvaluatorFactory {
|
||||
|
||||
private final MemFileManager fileManager;
|
||||
|
||||
private final String classpath;
|
||||
|
||||
private final List<String> compilationOptions;
|
||||
|
||||
private final JavaCompiler compiler;
|
||||
|
||||
private final ClassLoader loader;
|
||||
|
||||
public EvaluatorFactory(URLClassLoader parent) {
|
||||
this(parent, ToolProvider.getSystemJavaCompiler());
|
||||
}
|
||||
|
||||
public EvaluatorFactory(URLClassLoader parent, JavaCompiler compiler) {
|
||||
this.fileManager = new MemFileManager(parent, compiler.getStandardFileManager(null, null, null));
|
||||
this.compiler = compiler;
|
||||
this.classpath = SimpleCompiler.getClassPath(parent);
|
||||
this.loader = fileManager.getClassLoader(StandardLocation.CLASS_OUTPUT);
|
||||
this.compilationOptions = Arrays.asList("-classpath", classpath, "-g:none");
|
||||
}
|
||||
|
||||
private void compile(String source, Type projectionType, String[] names, Type[] types,
|
||||
String id, Map<String, Object> constants) throws IOException {
|
||||
// create source
|
||||
StringWriter writer = new StringWriter();
|
||||
JavaWriter javaw = new JavaWriter(writer);
|
||||
SimpleType idType = new SimpleType(id, "", id);
|
||||
javaw.beginClass(idType, null);
|
||||
Parameter[] params = new Parameter[names.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
params[i] = new Parameter(names[i], types[i]);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : constants.entrySet()) {
|
||||
Type type = new ClassType(TypeCategory.SIMPLE, ClassUtils.normalize(entry.getValue().getClass()));
|
||||
javaw.publicField(type, entry.getKey());
|
||||
}
|
||||
|
||||
if (constants.isEmpty()) {
|
||||
javaw.beginStaticMethod(projectionType, "eval", params);
|
||||
} else {
|
||||
javaw.beginPublicMethod(projectionType, "eval", params);
|
||||
}
|
||||
javaw.append(source);
|
||||
javaw.end();
|
||||
javaw.end();
|
||||
|
||||
// compile
|
||||
SimpleJavaFileObject javaFileObject = new MemSourceFileObject(id, writer.toString());
|
||||
Writer out = new StringWriter();
|
||||
|
||||
CompilationTask task = compiler.getTask(out, fileManager, null, compilationOptions, null,
|
||||
Collections.singletonList(javaFileObject));
|
||||
if (!task.call().booleanValue()) {
|
||||
throw new CodegenException("Compilation of " + source + " failed.\n" + out.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public <T> Evaluator<T> createEvaluator(String source, Class<? extends T> projectionType,
|
||||
String[] names, Class<?>[] classes, Map<String, Object> constants) {
|
||||
Type[] types = new Type[classes.length];
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
types[i] = new ClassType(TypeCategory.SIMPLE, classes[i]);
|
||||
}
|
||||
return createEvaluator(source, new ClassType(TypeCategory.SIMPLE, projectionType), names,
|
||||
types, classes, constants);
|
||||
}
|
||||
<T> Evaluator<T> createEvaluator(String source, Class<? extends T> projectionType, String[] names, Class<?>[] classes, Map<String, Object> constants);
|
||||
|
||||
/**
|
||||
* Create a new Evaluator instance
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* projection type
|
||||
* projection type
|
||||
* @param source
|
||||
* expression in Java source code form
|
||||
* expression in Java source code form
|
||||
* @param projection
|
||||
* type of the source expression
|
||||
* type of the source expression
|
||||
* @param names
|
||||
* names of the arguments
|
||||
* names of the arguments
|
||||
* @param types
|
||||
* types of the arguments
|
||||
* types of the arguments
|
||||
* @param constants
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Evaluator<T> createEvaluator(String source, ClassType projection, String[] names,
|
||||
Type[] types, Class<?>[] classes, Map<String, Object> constants) {
|
||||
try {
|
||||
String id = toId(source, projection.getJavaClass(), types);
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = loader.loadClass(id);
|
||||
} catch (ClassNotFoundException e) {
|
||||
compile(source, projection, names, types, id, constants);
|
||||
// reload
|
||||
clazz = loader.loadClass(id);
|
||||
}
|
||||
|
||||
Object object = !constants.isEmpty() ? clazz.newInstance() : null;
|
||||
|
||||
for (Map.Entry<String, Object> entry : constants.entrySet()) {
|
||||
Field field = clazz.getField(entry.getKey());
|
||||
field.set(object, entry.getValue());
|
||||
}
|
||||
|
||||
Method method = clazz.getMethod("eval", classes);
|
||||
return new MethodEvaluator<T>(method, object, (Class) projection.getJavaClass());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (SecurityException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (IOException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new CodegenException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new CodegenException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String toId(String source, Class<?> returnType, Type... types) {
|
||||
StringBuilder b = new StringBuilder("Q");
|
||||
b.append("_").append(source.hashCode());
|
||||
b.append("_").append(returnType.getName().hashCode());
|
||||
for (Type type : types) {
|
||||
b.append("_").append(type.getFullName().hashCode());
|
||||
}
|
||||
return b.toString().replace('-', '0');
|
||||
}
|
||||
|
||||
@SuppressWarnings(value = "unchecked")
|
||||
<T> Evaluator<T> createEvaluator(String source, ClassType projection, String[] names, Type[] types, Class<?>[] classes, Map<String, Object> constants);
|
||||
|
||||
}
|
||||
|
||||
96
src/main/java/com/mysema/codegen/JDKEvaluatorFactory.java
Normal file
96
src/main/java/com/mysema/codegen/JDKEvaluatorFactory.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Mysema Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
package com.mysema.codegen;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
import com.mysema.codegen.model.SimpleType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.support.ClassUtils;
|
||||
|
||||
/**
|
||||
* JDKEvaluatorFactory is a factory implementation for creating Evaluator instances
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public class JDKEvaluatorFactory extends AbstractEvaluatorFactory {
|
||||
|
||||
private final MemFileManager fileManager;
|
||||
|
||||
private final String classpath;
|
||||
|
||||
private final List<String> compilationOptions;
|
||||
|
||||
private final JavaCompiler compiler;
|
||||
|
||||
public JDKEvaluatorFactory(URLClassLoader parent) {
|
||||
this(parent, ToolProvider.getSystemJavaCompiler());
|
||||
}
|
||||
|
||||
public JDKEvaluatorFactory(URLClassLoader parent, JavaCompiler compiler) {
|
||||
this.fileManager = new MemFileManager(parent, compiler.getStandardFileManager(null, null, null));
|
||||
this.compiler = compiler;
|
||||
this.classpath = SimpleCompiler.getClassPath(parent);
|
||||
this.loader = fileManager.getClassLoader(StandardLocation.CLASS_OUTPUT);
|
||||
this.compilationOptions = Arrays.asList("-classpath", classpath, "-g:none");
|
||||
}
|
||||
|
||||
protected void compile(String source, ClassType projectionType, String[] names, Type[] types,
|
||||
String id, Map<String, Object> constants) throws IOException {
|
||||
// create source
|
||||
StringWriter writer = new StringWriter();
|
||||
JavaWriter javaw = new JavaWriter(writer);
|
||||
SimpleType idType = new SimpleType(id, "", id);
|
||||
javaw.beginClass(idType, null);
|
||||
Parameter[] params = new Parameter[names.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
params[i] = new Parameter(names[i], types[i]);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : constants.entrySet()) {
|
||||
Type type = new ClassType(TypeCategory.SIMPLE, ClassUtils.normalize(entry.getValue().getClass()));
|
||||
javaw.publicField(type, entry.getKey());
|
||||
}
|
||||
|
||||
if (constants.isEmpty()) {
|
||||
javaw.beginStaticMethod(projectionType, "eval", params);
|
||||
} else {
|
||||
javaw.beginPublicMethod(projectionType, "eval", params);
|
||||
}
|
||||
javaw.append(source);
|
||||
javaw.end();
|
||||
javaw.end();
|
||||
|
||||
// compile
|
||||
SimpleJavaFileObject javaFileObject = new MemSourceFileObject(id, writer.toString());
|
||||
Writer out = new StringWriter();
|
||||
|
||||
CompilationTask task = compiler.getTask(out, fileManager, null, compilationOptions, null,
|
||||
Collections.singletonList(javaFileObject));
|
||||
if (!task.call().booleanValue()) {
|
||||
throw new CodegenException("Compilation of " + source + " failed.\n" + out.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,7 +7,6 @@ package com.mysema.codegen;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -18,11 +17,11 @@ import com.mysema.codegen.model.ClassType;
|
||||
import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.codegen.model.Types;
|
||||
import com.mysema.codegen.support.Cat;
|
||||
|
||||
public class ComplexEvaluationTest {
|
||||
|
||||
private EvaluatorFactory factory = new EvaluatorFactory((URLClassLoader) getClass()
|
||||
.getClassLoader());
|
||||
private EvaluatorFactory factory = new ECJEvaluatorFactory(getClass().getClassLoader());
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -49,4 +48,116 @@ public class ComplexEvaluationTest {
|
||||
assertEquals(Arrays.asList("2", "4"), evaluator.evaluate(a_, b_));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void ComplexClassLoading() {
|
||||
ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.OBJECTS);
|
||||
StringBuilder source = new StringBuilder();
|
||||
source.append("java.util.List<Object[]> rv = new java.util.ArrayList<Object[]>();\n");
|
||||
source.append("for (com.mysema.codegen.support.Cat cat : (java.util.List<com.mysema.codegen.support.Cat>)cat_){\n");
|
||||
source.append("for (com.mysema.codegen.support.Cat otherCat : (java.util.List<com.mysema.codegen.support.Cat>)otherCat_){\n");
|
||||
source.append("rv.add(new Object[]{cat,otherCat});\n");
|
||||
source.append("}\n");
|
||||
source.append("}\n");
|
||||
source.append("return rv;\n");
|
||||
|
||||
Cat fuzzy = new Cat("fuzzy");
|
||||
Cat spot = new Cat("spot");
|
||||
Cat mittens = new Cat("mittens");
|
||||
Cat sparkles = new Cat("sparkles");
|
||||
|
||||
List<Cat> a_ = Arrays.asList(fuzzy, spot);
|
||||
List<Cat> b_ = Arrays.asList(mittens, sparkles);
|
||||
|
||||
ClassType argType = new ClassType(TypeCategory.LIST, List.class, new ClassType(Cat.class));
|
||||
Evaluator<List> evaluator = factory.createEvaluator(source.toString(), resultType,
|
||||
new String[] { "cat_", "otherCat_" }, new Type[] { argType, argType }, new Class[] {
|
||||
List.class, List.class }, Collections.<String, Object> emptyMap());
|
||||
|
||||
Object[][] expResults = { {fuzzy, mittens}, {fuzzy, sparkles}, {spot, mittens}, {spot, sparkles} };
|
||||
List<Object[]> result = evaluator.evaluate(a_, b_);
|
||||
assertEquals(expResults.length, result.size());
|
||||
|
||||
for (int i = 0; i < expResults.length; i++) {
|
||||
assertEquals(expResults[i].length, result.get(i).length);
|
||||
for (int j = 0; j < expResults[i].length; j++) {
|
||||
assertEquals(expResults[i][j], result.get(i)[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=CodegenException.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void ComplexClassLoadingFailure() {
|
||||
ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.STRING);
|
||||
StringBuilder source = new StringBuilder();
|
||||
source.append("java.util.List<String> rv = (java.util.List<String>) new java.util.ArrayList<Franklin>();\n");
|
||||
source.append("for (String a : a_){\n");
|
||||
source.append(" for (String b : b_){\n");
|
||||
source.append(" if (a.equals(b)){\n");
|
||||
source.append(" rv.add(a);\n");
|
||||
source.append(" }\n");
|
||||
source.append(" }\n");
|
||||
source.append("}\n");
|
||||
source.append("return rv;");
|
||||
|
||||
Evaluator<List> evaluator = factory.createEvaluator(source.toString(), resultType,
|
||||
new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] {
|
||||
List.class, List.class }, Collections.<String, Object> emptyMap());
|
||||
|
||||
List<String> a_ = Arrays.asList("1", "2", "3", "4");
|
||||
List<String> b_ = Arrays.asList("2", "4", "6", "8");
|
||||
|
||||
assertEquals(Arrays.asList("2", "4"), evaluator.evaluate(a_, b_));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void ComplexPrimitiveType() {
|
||||
ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.BOOLEAN);
|
||||
StringBuilder source = new StringBuilder();
|
||||
source.append("java.util.List<Boolean> rv = new java.util.ArrayList<Boolean>();\n");
|
||||
source.append("for (boolean a : a_){\n");
|
||||
source.append(" for (boolean b : b_){\n");
|
||||
source.append(" if (a == b){\n");
|
||||
source.append(" rv.add(a);\n");
|
||||
source.append(" }\n");
|
||||
source.append(" }\n");
|
||||
source.append("}\n");
|
||||
source.append("return rv;");
|
||||
|
||||
Evaluator<List> evaluator = factory.createEvaluator(source.toString(), resultType,
|
||||
new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] {
|
||||
List.class, List.class }, Collections.<String, Object> emptyMap());
|
||||
|
||||
List<Boolean> a_ = Arrays.asList(true, true, true);
|
||||
List<Boolean> b_ = Arrays.asList(false, false, true);
|
||||
|
||||
assertEquals(Arrays.asList(true, true, true), evaluator.evaluate(a_, b_));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void ComplexEmbeddedClass() {
|
||||
ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.BOOLEAN);
|
||||
StringBuilder source = new StringBuilder();
|
||||
source.append("java.util.List<Boolean> rv = new java.util.ArrayList<Boolean>();\n");
|
||||
source.append("for (boolean a : a_){\n");
|
||||
source.append(" for (boolean b : b_){\n");
|
||||
source.append(" if (a == b && new TestEmbedded().DO_RETURN()){\n");
|
||||
source.append(" rv.add(a);\n");
|
||||
source.append(" }\n");
|
||||
source.append(" }\n");
|
||||
source.append("}\n");
|
||||
source.append("return rv;} private static class TestEmbedded { public TestEmbedded() {} public boolean DO_RETURN() { return true; } ");
|
||||
|
||||
Evaluator<List> evaluator = factory.createEvaluator(source.toString(), resultType,
|
||||
new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] {
|
||||
List.class, List.class }, Collections.<String, Object> emptyMap());
|
||||
|
||||
List<Boolean> a_ = Arrays.asList(true, true, true);
|
||||
List<Boolean> b_ = Arrays.asList(false, false, true);
|
||||
|
||||
assertEquals(Arrays.asList(true, true, true), evaluator.evaluate(a_, b_));
|
||||
}
|
||||
}
|
||||
|
||||
123
src/test/java/com/mysema/codegen/ECJEvaluatorFactoryTest.java
Normal file
123
src/test/java/com/mysema/codegen/ECJEvaluatorFactoryTest.java
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Mysema Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
package com.mysema.codegen;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ECJEvaluatorFactoryTest {
|
||||
|
||||
public static class TestEntity {
|
||||
|
||||
private final String name;
|
||||
|
||||
public TestEntity(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private EvaluatorFactory factory;
|
||||
|
||||
private List<String> names = Arrays.asList("a", "b");
|
||||
|
||||
private List<Class<?>> ints = Arrays.<Class<?>> asList(int.class, int.class);
|
||||
|
||||
private List<Class<?>> strings = Arrays.<Class<?>> asList(String.class, String.class);
|
||||
|
||||
private List<Class<?>> string_int = Arrays.<Class<?>> asList(String.class, int.class);
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
factory = new ECJEvaluatorFactory(getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Simple() {
|
||||
for (String expr : Arrays.asList("a.equals(b)", "a.startsWith(b)", "a.equalsIgnoreCase(b)")) {
|
||||
long start = System.currentTimeMillis();
|
||||
evaluate(expr, boolean.class, names, strings, Arrays.asList("a", "b"),
|
||||
Collections.<String, Object> emptyMap());
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
System.err.println(expr + " took " + duration + "ms\n");
|
||||
}
|
||||
|
||||
for (String expr : Arrays.asList("a != b", "a < b", "a > b", "a <= b", "a >= b")) {
|
||||
long start = System.currentTimeMillis();
|
||||
evaluate(expr, boolean.class, names, ints, Arrays.asList(0, 1),
|
||||
Collections.<String, Object> emptyMap());
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
System.err.println(expr + " took " + duration + "ms\n");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Results() {
|
||||
// String + String
|
||||
test("a + b", String.class, names, strings, Arrays.asList("Hello ", "World"), "Hello World");
|
||||
|
||||
// String + int
|
||||
test("a.substring(b)", String.class, names, string_int,
|
||||
Arrays.<Object> asList("Hello World", 6), "World");
|
||||
|
||||
// int + int
|
||||
test("a + b", int.class, names, ints, Arrays.asList(1, 2), 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void WithConstants() {
|
||||
Map<String, Object> constants = new HashMap<String, Object>();
|
||||
constants.put("x", "Hello World");
|
||||
List<Class<?>> types = Arrays.<Class<?>> asList(String.class);
|
||||
List<String> names = Arrays.asList("a");
|
||||
assertEquals(
|
||||
Boolean.TRUE,
|
||||
evaluate("a.equals(x)", boolean.class, names, types, Arrays.asList("Hello World"),
|
||||
constants));
|
||||
assertEquals(
|
||||
Boolean.FALSE,
|
||||
evaluate("a.equals(x)", boolean.class, names, types, Arrays.asList("Hello"),
|
||||
constants));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CustomType() {
|
||||
test("a.getName()", String.class, Collections.singletonList("a"),
|
||||
Collections.<Class<?>> singletonList(TestEntity.class),
|
||||
Arrays.asList(new TestEntity("Hello World")), "Hello World");
|
||||
}
|
||||
|
||||
private void test(String source, Class<?> projectionType, List<String> names,
|
||||
List<Class<?>> types, List<?> args, Object expectedResult) {
|
||||
Assert.assertEquals(
|
||||
expectedResult,
|
||||
evaluate(source, projectionType, names, types, args,
|
||||
Collections.<String, Object> emptyMap()));
|
||||
}
|
||||
|
||||
private Object evaluate(String source, Class<?> projectionType, List<String> names,
|
||||
List<Class<?>> types, List<?> args, Map<String, Object> constants) {
|
||||
Evaluator<?> evaluator = factory.createEvaluator("return " + source + ";", projectionType,
|
||||
names.toArray(new String[names.size()]), types.toArray(new Class[types.size()]),
|
||||
constants);
|
||||
return evaluator.evaluate(args.toArray());
|
||||
}
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EvaluatorFactoryTest {
|
||||
public class JDKEvaluatorFactoryTest {
|
||||
|
||||
public static class TestEntity {
|
||||
|
||||
@ -47,7 +47,7 @@ public class EvaluatorFactoryTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
factory = new EvaluatorFactory((URLClassLoader) getClass().getClassLoader());
|
||||
factory = new JDKEvaluatorFactory((URLClassLoader) getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Test
|
||||
159
src/test/java/com/mysema/codegen/support/Cat.java
Normal file
159
src/test/java/com/mysema/codegen/support/Cat.java
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2011, Mysema Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mysema.codegen.support;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Cat {
|
||||
|
||||
private int breed;
|
||||
|
||||
private java.sql.Date dateField;
|
||||
|
||||
public enum Color {
|
||||
BLUE, GREEN, BROWN
|
||||
}
|
||||
private Color eyecolor;
|
||||
|
||||
private List<Cat> kittens;
|
||||
|
||||
private Cat[] kittenArray;
|
||||
|
||||
private Map<String, Cat> kittensByName;
|
||||
|
||||
private Cat mate;
|
||||
|
||||
private String stringAsSimple;
|
||||
|
||||
private java.sql.Time timeField;
|
||||
|
||||
private String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private Date birthdate;
|
||||
private int id;
|
||||
|
||||
public Cat() {
|
||||
this.kittensByName = Collections.emptyMap();
|
||||
}
|
||||
|
||||
public Cat(String name) {
|
||||
Cat kitten = new Cat();
|
||||
this.kittens = Arrays.asList(kitten);
|
||||
this.kittenArray = new Cat[]{kitten};
|
||||
this.kittensByName = Collections.singletonMap("Kitty", kitten);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Cat(String name, String kittenName){
|
||||
this(name);
|
||||
kittens.get(0).setName(kittenName);
|
||||
}
|
||||
|
||||
public Cat(String name, int id) {
|
||||
this(name);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Cat(String name, int id, Date birthdate) {
|
||||
this(name, id);
|
||||
this.birthdate = new Date(birthdate.getTime());
|
||||
this.dateField = new java.sql.Date(birthdate.getTime());
|
||||
this.timeField = new java.sql.Time(birthdate.getTime());
|
||||
}
|
||||
|
||||
public int getBreed() {
|
||||
return breed;
|
||||
}
|
||||
|
||||
public java.sql.Date getDateField() {
|
||||
return dateField;
|
||||
}
|
||||
|
||||
public Color getEyecolor() {
|
||||
return eyecolor;
|
||||
}
|
||||
|
||||
public List<Cat> getKittens() {
|
||||
return kittens;
|
||||
}
|
||||
|
||||
public Map<String, Cat> getKittensByName() {
|
||||
return kittensByName;
|
||||
}
|
||||
|
||||
public Cat getMate() {
|
||||
return mate;
|
||||
}
|
||||
|
||||
public String getStringAsSimple() {
|
||||
return stringAsSimple;
|
||||
}
|
||||
|
||||
public java.sql.Time getTimeField() {
|
||||
return timeField;
|
||||
}
|
||||
|
||||
public void setBreed(int breed) {
|
||||
this.breed = breed;
|
||||
}
|
||||
|
||||
public void setDateField(java.sql.Date dateField) {
|
||||
this.dateField = new java.sql.Date(dateField.getTime());
|
||||
}
|
||||
|
||||
public void setEyecolor(Color eyecolor) {
|
||||
this.eyecolor = eyecolor;
|
||||
}
|
||||
|
||||
public void setKittens(List<Cat> kittens) {
|
||||
this.kittens = kittens;
|
||||
}
|
||||
|
||||
public void setKittensByName(Map<String, Cat> kittensByName) {
|
||||
this.kittensByName = kittensByName;
|
||||
}
|
||||
|
||||
public void setMate(Cat mate) {
|
||||
this.mate = mate;
|
||||
}
|
||||
|
||||
public void setStringAsSimple(String stringAsSimple) {
|
||||
this.stringAsSimple = stringAsSimple;
|
||||
}
|
||||
|
||||
public void setTimeField(java.sql.Time timeField) {
|
||||
this.timeField = timeField;
|
||||
}
|
||||
|
||||
public Cat[] getKittenArray() {
|
||||
return kittenArray;
|
||||
}
|
||||
|
||||
public void setKittenArray(Cat[] kittenArray) {
|
||||
this.kittenArray = kittenArray.clone();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,4 +5,5 @@ Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
javax.annotation.*;version="0",
|
||||
javax.tools.*;version="0",
|
||||
org.eclipse.jdt.*;version="3.7.2",
|
||||
com.google.common.*;version="${guava.version}"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user