com.querydsl.codegen.utils.JavaWriter Maven / Gradle / Ivy
/*
* Copyright 2010, 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.querydsl.codegen.utils;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import java.util.function.Function;
import com.querydsl.codegen.utils.model.Parameter;
import com.querydsl.codegen.utils.model.Type;
/**
* JavaWriter is the default implementation of the CodeWriter interface
*
* @author tiwe
*
*/
public final class JavaWriter extends AbstractCodeWriter {
private static final String EXTENDS = " extends ";
private static final String IMPLEMENTS = " implements ";
private static final String IMPORT = "import ";
private static final String IMPORT_STATIC = "import static ";
private static final String PACKAGE = "package ";
private static final String PRIVATE = "private ";
private static final String PRIVATE_FINAL = "private final ";
private static final String PRIVATE_STATIC_FINAL = "private static final ";
private static final String PROTECTED = "protected ";
private static final String PROTECTED_FINAL = "protected final ";
private static final String PUBLIC = "public ";
private static final String PUBLIC_CLASS = "public class ";
private static final String PUBLIC_FINAL = "public final ";
private static final String PUBLIC_INTERFACE = "public interface ";
private static final String PUBLIC_STATIC = "public static ";
private static final String PUBLIC_STATIC_FINAL = "public static final ";
private final Set classes = new HashSet();
private final Set packages = new HashSet();
private final Stack types = new Stack();
public JavaWriter(Appendable appendable) {
super(appendable, 4);
this.packages.add("java.lang");
}
@Override
public JavaWriter annotation(Annotation annotation) throws IOException {
beginLine().append("@").appendType(annotation.annotationType());
Method[] methods = annotation.annotationType().getDeclaredMethods();
if (methods.length == 1 && methods[0].getName().equals("value")) {
try {
Object value = methods[0].invoke(annotation);
append("(");
annotationConstant(value);
append(")");
} catch (IllegalArgumentException e) {
throw new CodegenException(e);
} catch (IllegalAccessException e) {
throw new CodegenException(e);
} catch (InvocationTargetException e) {
throw new CodegenException(e);
}
} else {
boolean first = true;
for (Method method : methods) {
try {
Object value = method.invoke(annotation);
if (value == null || value.equals(method.getDefaultValue())) {
continue;
} else if (value.getClass().isArray()
&& Arrays.equals((Object[]) value, (Object[]) method.getDefaultValue())) {
continue;
} else if (!first) {
append(Symbols.COMMA);
} else {
append("(");
}
append(method.getName()).append("=");
annotationConstant(value);
} catch (IllegalArgumentException e) {
throw new CodegenException(e);
} catch (IllegalAccessException e) {
throw new CodegenException(e);
} catch (InvocationTargetException e) {
throw new CodegenException(e);
}
first = false;
}
if (!first) {
append(")");
}
}
return nl();
}
@Override
public JavaWriter annotation(Class extends Annotation> annotation) throws IOException {
return beginLine().append("@").appendType(annotation).nl();
}
@SuppressWarnings("unchecked")
private void annotationConstant(Object value) throws IOException {
if (value.getClass().isArray()) {
append("{");
boolean first = true;
for (Object o : (Object[]) value) {
if (!first) {
append(", ");
}
annotationConstant(o);
first = false;
}
append("}");
} else if (value instanceof Class) {
appendType((Class) value).append(".class");
} else if (value instanceof Number || value instanceof Boolean) {
append(value.toString());
} else if (value instanceof Enum) {
Enum> enumValue = (Enum>) value;
if (classes.contains(enumValue.getClass().getName())
|| packages.contains(enumValue.getClass().getPackage().getName())) {
append(enumValue.name());
} else {
append(enumValue.getDeclaringClass().getName()).append(Symbols.DOT).append(enumValue.name());
}
} else if (value instanceof String) {
String escaped = StringUtils.escapeJava(value.toString());
append(Symbols.QUOTE).append(escaped.replace("\\/", "/")).append(Symbols.QUOTE);
} else {
throw new IllegalArgumentException("Unsupported annotation value : " + value);
}
}
private JavaWriter appendType(Class> type) throws IOException {
if (classes.contains(type.getName()) || packages.contains(type.getPackage().getName())) {
append(type.getSimpleName());
} else {
append(type.getName());
}
return this;
}
@Override
public JavaWriter beginClass(Type type) throws IOException {
return beginClass(type, null);
}
@Override
public JavaWriter beginClass(Type type, Type superClass, Type... interfaces) throws IOException {
packages.add(type.getPackageName());
beginLine(PUBLIC_CLASS, type.getGenericName(false, packages, classes));
if (superClass != null) {
append(EXTENDS).append(superClass.getGenericName(false, packages, classes));
}
if (interfaces.length > 0) {
append(IMPLEMENTS);
for (int i = 0; i < interfaces.length; i++) {
if (i > 0) {
append(Symbols.COMMA);
}
append(interfaces[i].getGenericName(false, packages, classes));
}
}
append(" {").nl().nl();
goIn();
types.push(type);
return this;
}
@Override
public JavaWriter beginConstructor(Collection parameters,
Function transformer) throws IOException {
types.push(types.peek());
beginLine(PUBLIC, types.peek().getSimpleName()).params(parameters, transformer)
.append(" {").nl();
return goIn();
}
@Override
public JavaWriter beginConstructor(Parameter... parameters) throws IOException {
types.push(types.peek());
beginLine(PUBLIC, types.peek().getSimpleName()).params(parameters).append(" {").nl();
return goIn();
}
@Override
public JavaWriter beginInterface(Type type, Type... interfaces) throws IOException {
packages.add(type.getPackageName());
beginLine(PUBLIC_INTERFACE, type.getGenericName(false, packages, classes));
if (interfaces.length > 0) {
append(EXTENDS);
for (int i = 0; i < interfaces.length; i++) {
if (i > 0) {
append(Symbols.COMMA);
}
append(interfaces[i].getGenericName(false, packages, classes));
}
}
append(" {").nl().nl();
goIn();
types.push(type);
return this;
}
private JavaWriter beginMethod(String modifiers, Type returnType, String methodName,
Parameter... args) throws IOException {
types.push(types.peek());
beginLine(
modifiers, returnType.getGenericName(true, packages, classes), Symbols.SPACE, methodName)
.params(args).append(" {").nl();
return goIn();
}
@Override
public JavaWriter beginPublicMethod(Type returnType, String methodName,
Collection parameters, Function transformer) throws IOException {
return beginMethod(PUBLIC, returnType, methodName, transform(parameters, transformer));
}
@Override
public JavaWriter beginPublicMethod(Type returnType, String methodName, Parameter... args)
throws IOException {
return beginMethod(PUBLIC, returnType, methodName, args);
}
@Override
public JavaWriter beginStaticMethod(Type returnType, String methodName,
Collection parameters, Function transformer) throws IOException {
return beginMethod(PUBLIC_STATIC, returnType, methodName,
transform(parameters, transformer));
}
@Override
public JavaWriter beginStaticMethod(Type returnType, String methodName, Parameter... args)
throws IOException {
return beginMethod(PUBLIC_STATIC, returnType, methodName, args);
}
@Override
public JavaWriter end() throws IOException {
types.pop();
goOut();
return line("}").nl();
}
@Override
public JavaWriter field(Type type, String name) throws IOException {
return line(type.getGenericName(true, packages, classes), Symbols.SPACE, name, Symbols.SEMICOLON).nl();
}
private JavaWriter field(String modifier, Type type, String name) throws IOException {
return line(
modifier, type.getGenericName(true, packages, classes), Symbols.SPACE, name, Symbols.SEMICOLON)
.nl();
}
private JavaWriter field(String modifier, Type type, String name, String value)
throws IOException {
return line(
modifier, type.getGenericName(true, packages, classes), Symbols.SPACE, name,
Symbols.ASSIGN, value, Symbols.SEMICOLON).nl();
}
@Override
public String getClassConstant(String className) {
return className + ".class";
}
@Override
public String getGenericName(boolean asArgType, Type type) {
return type.getGenericName(asArgType, packages, classes);
}
@Override
public String getRawName(Type type) {
return type.getRawName(packages, classes);
}
@Override
public JavaWriter imports(Class>... imports) throws IOException {
for (Class> cl : imports) {
classes.add(cl.getName());
line(IMPORT, cl.getName(), Symbols.SEMICOLON);
}
nl();
return this;
}
@Override
public JavaWriter imports(Package... imports) throws IOException {
for (Package p : imports) {
packages.add(p.getName());
line(IMPORT, p.getName(), ".*;");
}
nl();
return this;
}
@Override
public JavaWriter importClasses(String... imports) throws IOException {
for (String cl : imports) {
classes.add(cl);
line(IMPORT, cl, Symbols.SEMICOLON);
}
nl();
return this;
}
@Override
public JavaWriter importPackages(String... imports) throws IOException {
for (String p : imports) {
packages.add(p);
line(IMPORT, p, ".*;");
}
nl();
return this;
}
@Override
public JavaWriter javadoc(String... lines) throws IOException {
line("/**");
for (String line : lines) {
line(" * ", line);
}
return line(" */");
}
@Override
public JavaWriter packageDecl(String packageName) throws IOException {
packages.add(packageName);
return line(PACKAGE, packageName, Symbols.SEMICOLON).nl();
}
private JavaWriter params(Collection parameters, Function transformer)
throws IOException {
append("(");
boolean first = true;
for (T param : parameters) {
if (!first) {
append(Symbols.COMMA);
}
param(transformer.apply(param));
first = false;
}
append(")");
return this;
}
private JavaWriter params(Parameter... params) throws IOException {
append("(");
for (int i = 0; i < params.length; i++) {
if (i > 0) {
append(Symbols.COMMA);
}
param(params[i]);
}
append(")");
return this;
}
private JavaWriter param(Parameter parameter) throws IOException {
append(parameter.getType().getGenericName(true, packages, classes));
append(" ");
append(parameter.getName());
return this;
}
@Override
public JavaWriter privateField(Type type, String name) throws IOException {
return field(PRIVATE, type, name);
}
@Override
public JavaWriter privateFinal(Type type, String name) throws IOException {
return field(PRIVATE_FINAL, type, name);
}
@Override
public JavaWriter privateFinal(Type type, String name, String value) throws IOException {
return field(PRIVATE_FINAL, type, name, value);
}
@Override
public JavaWriter privateStaticFinal(Type type, String name, String value) throws IOException {
return field(PRIVATE_STATIC_FINAL, type, name, value);
}
@Override
public JavaWriter protectedField(Type type, String name) throws IOException {
return field(PROTECTED, type, name);
}
@Override
public JavaWriter protectedFinal(Type type, String name) throws IOException {
return field(PROTECTED_FINAL, type, name);
}
@Override
public JavaWriter protectedFinal(Type type, String name, String value) throws IOException {
return field(PROTECTED_FINAL, type, name, value);
}
@Override
public JavaWriter publicField(Type type, String name) throws IOException {
return field(PUBLIC, type, name);
}
@Override
public JavaWriter publicField(Type type, String name, String value) throws IOException {
return field(PUBLIC, type, name, value);
}
@Override
public JavaWriter publicFinal(Type type, String name) throws IOException {
return field(PUBLIC_FINAL, type, name);
}
@Override
public JavaWriter publicFinal(Type type, String name, String value) throws IOException {
return field(PUBLIC_FINAL, type, name, value);
}
@Override
public JavaWriter publicStaticFinal(Type type, String name, String value) throws IOException {
return field(PUBLIC_STATIC_FINAL, type, name, value);
}
@Override
public JavaWriter staticimports(Class>... imports) throws IOException {
for (Class> cl : imports) {
line(IMPORT_STATIC, cl.getName(), ".*;");
}
return this;
}
@Override
public JavaWriter suppressWarnings(String type) throws IOException {
return line("@SuppressWarnings(\"", type, "\")");
}
@Override
public CodeWriter suppressWarnings(String... types) throws IOException {
return annotation(new MultiSuppressWarnings(types));
}
private Parameter[] transform(Collection parameters,
Function transformer) {
Parameter[] rv = new Parameter[parameters.size()];
int i = 0;
for (T value : parameters) {
rv[i++] = transformer.apply(value);
}
return rv;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy