com.speedment.generator.standard.entity.GeneratedEntityImplTranslator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tool-deploy Show documentation
Show all versions of tool-deploy Show documentation
A Speedment bundle that shades all dependencies into one jar. This is
useful when deploying an application on a server.
The newest version!
/*
*
* Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
*
* 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.speedment.generator.standard.entity;
import com.speedment.common.codegen.constant.DefaultAnnotationUsage;
import static com.speedment.common.codegen.constant.DefaultAnnotationUsage.OVERRIDE;
import com.speedment.common.codegen.constant.DefaultType;
import com.speedment.common.codegen.constant.SimpleParameterizedType;
import com.speedment.common.codegen.model.Class;
import com.speedment.common.codegen.model.Constructor;
import com.speedment.common.codegen.model.Field;
import com.speedment.common.codegen.model.File;
import com.speedment.common.codegen.model.Import;
import com.speedment.common.codegen.model.Method;
import static com.speedment.common.codegen.util.Formatting.block;
import com.speedment.common.injector.Injector;
import com.speedment.common.injector.annotation.Inject;
import static com.speedment.generator.standard.entity.GeneratedEntityTranslator.getterReturnType;
import static com.speedment.generator.standard.internal.util.ColumnUtil.optionalGetterName;
import static com.speedment.generator.standard.internal.util.ColumnUtil.usesOptional;
import com.speedment.generator.standard.internal.util.EntityTranslatorSupport;
import com.speedment.generator.standard.internal.util.FkHolder;
import com.speedment.generator.translator.AbstractEntityAndManagerTranslator;
import com.speedment.generator.translator.TranslatorSupport;
import com.speedment.generator.translator.component.TypeMapperComponent;
import com.speedment.runtime.config.Column;
import com.speedment.runtime.config.Table;
import com.speedment.runtime.config.trait.HasNullable;
import com.speedment.runtime.core.manager.Manager;
import com.speedment.runtime.core.util.OptionalUtil;
import java.lang.reflect.Type;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.StringJoiner;
/**
*
* @author Emil Forslund
* @author Per-Åke Minborg
*/
public final class GeneratedEntityImplTranslator extends AbstractEntityAndManagerTranslator {
@Inject private TypeMapperComponent typeMappers;
@Inject private Injector injector;
public GeneratedEntityImplTranslator(Table table) {
super(table, Class::of);
}
@Override
protected Class makeCodeGenModel(File file) {
requireNonNull(file);
return newBuilder(file, getSupport().generatedEntityImplName())
/**
* Class details
*/
.forEveryTable((clazz, table) ->
clazz.public_()
.abstract_()
.add(getSupport().entityType())
.add(Constructor.of().protected_())
)
/**
* Getters
*/
.forEveryColumn((clazz, col) -> {
final Type retType = getterReturnType(typeMappers, col);
final String getter;
if (usesOptional(col)) {
final String varName = getSupport().variableName(col);
if (retType.getTypeName().equals(Optional.class.getName())) {
getter = "Optional.ofNullable(" + varName + ")";
} else {
file.add(Import.of(OptionalUtil.class));
getter = "OptionalUtil.ofNullable(" + varName + ")";
}
} else {
getter = getSupport().variableName(col);
}
clazz
.add(fieldFor(col).private_())
.add(Method.of(GETTER_METHOD_PREFIX + getSupport().typeName(col), retType)
.public_().add(OVERRIDE)
.add("return " + getter + ";"));
})
/**
* Setters
*/
.forEveryColumn((clazz, col) ->
clazz
.add(Method.of(SETTER_METHOD_PREFIX + getSupport().typeName(col), getSupport().entityType())
.public_()
.add(OVERRIDE)
.add(fieldFor(col))
.add("this." + getSupport().variableName(col) + " = " + getSupport().variableName(col) + ";")
.add("return this;"))
)
/**
* Finders
*/
.forEveryColumn((clazz, col) -> {
EntityTranslatorSupport.getForeignKey(
getSupport().tableOrThrow(), col
).ifPresent(fkc -> {
final FkHolder fu = new FkHolder(injector, fkc.getParentOrThrow());
final TranslatorSupport fuSupport = fu.getForeignEmt().getSupport();
file.add(Import.of(fuSupport.entityType()));
final String isPresentName = usesOptional(col) ? ".isPresent()" : " != null";
final String getterName = optionalGetterName(typeMappers, col).orElse("");
clazz.add(Method.of(FINDER_METHOD_PREFIX + getSupport().typeName(col),
col.isNullable()
? DefaultType.optional(fuSupport.entityType())
: fuSupport.entityType())
.public_()
.add(DefaultAnnotationUsage.OVERRIDE)
.add(Field.of("foreignManager", SimpleParameterizedType.create(
Manager.class, fuSupport.entityType()
)))
.add(
col.isNullable() ?
"if (" + GETTER_METHOD_PREFIX + getSupport().namer().javaTypeName(col.getJavaName()) + "()" + isPresentName + ") " + block(
"return foreignManager.stream().filter(" + fuSupport.entityName() +
"." + fuSupport.namer().javaStaticFieldName(fu.getForeignColumn().getJavaName()) +
".equal(" + GETTER_METHOD_PREFIX + getSupport().namer().javaTypeName(col.getJavaName()) +
"()" + getterName + ")).findAny();"
) + " else " + block(
"return Optional.empty();"
)
:
"return foreignManager.stream().filter(" + fuSupport.entityName() +
"." + fuSupport.namer().javaStaticFieldName(fu.getForeignColumn().getJavaName()) +
".equal(" + GETTER_METHOD_PREFIX + getSupport().namer().javaTypeName(col.getJavaName()) +
"()" + getterName + ")).findAny().orElse(null);"
)
);
});
})
// We need to make it POST_MAKE because other plugins might add fields
.forEveryTable(Phase.POST_MAKE, (clazz, table) ->
clazz
.add(toStringMethod(file))
.add(equalsMethod())
.add(hashCodeMethod(file))
)
.build();
}
protected Method toStringMethod(File file) {
file.add(Import.of(StringJoiner.class));
file.add(Import.of(Objects.class));
final Method m = Method.of("toString", String.class)
.public_()
.add(OVERRIDE)
.add("final StringJoiner sj = new StringJoiner(\", \", \"{ \", \" }\");");
columns().forEachOrdered(col -> {
final String getter;
if (usesOptional(col)) {
file.add(Import.of(OptionalUtil.class));
getter = "OptionalUtil.unwrap(get" + getSupport().typeName(col) + "())";
} else {
getter = "get" + getSupport().typeName(col) + "()";
}
m.add("sj.add(\"" + getSupport().variableName(col) + " = \" \t+ Objects.toString(" + getter + "));");
});
m.add("return \"" + getSupport().entityImplName() + " \" + sj.toString();");
return m;
}
private Method equalsMethod() {
final String thatName = "that";
final String thatCastedName = thatName + getSupport().entityName();
final Method method = Method.of("equals", boolean.class)
.public_()
.add(OVERRIDE)
.add(Field.of(thatName, Object.class))
.add("if (this == that) { return true; }")
.add("if (!(" + thatName + " instanceof " + getSupport().entityName() + ")) { return false; }")
.add("final " + getSupport().entityName() + " " + thatCastedName + " = (" + getSupport().entityName() + ")" + thatName + ";");
columns().forEachOrdered(c -> {
final String getter = "get" + getSupport().typeName(c);
final Type type = typeMappers.get(c).getJavaType(c);
if (usesOptional(c) || !DefaultType.isPrimitive(type)) {
method.add("if (!Objects.equals(this." + getter + "(), " + thatCastedName + "." + getter + "())) { return false; }");
} else {
method.add("if (this." + getter + "() != " + thatCastedName + "." + getter + "()) { return false; }");
}
});
method.add("return true;");
return method;
}
private Method hashCodeMethod(File file) {
final Method method = Method.of("hashCode", int.class)
.public_()
.add(OVERRIDE)
.add("int hash = 7;");
columns().forEachOrdered(c -> {
final StringBuilder str = new StringBuilder();
str.append("hash = 31 * hash + ");
final Type type = typeMappers.get(c).getJavaType(c);
if (!usesOptional(c) && DefaultType.isPrimitive(type)) {
str.append(DefaultType.wrapperFor(type).getSimpleName());
} else {
str.append("Objects");
}
str.append(".hashCode(");
if (usesOptional(c)) {
file.add(Import.of(OptionalUtil.class));
str.append("OptionalUtil.unwrap(");
}
str.append("get").append(getSupport().typeName(c)).append("()");
if (usesOptional(c)) str.append(')');
str.append(");");
method.add(str.toString());
});
method.add("return hash;");
return method;
}
@Override
protected String getJavadocRepresentText() {
return "The generated base implementation of the {@link " +
getSupport().entityType().getTypeName() + "}-interface.";
}
@Override
protected String getClassOrInterfaceName() {
return getSupport().generatedEntityImplName();
}
@Override
public boolean isInGeneratedPackage() {
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy