
com.moon.mapping.processing.BaseDefinition Maven / Gradle / Ivy
package com.moon.mapping.processing;
import com.moon.mapping.BeanMapping;
import com.moon.mapping.annotation.MappingFor;
import javax.lang.model.element.TypeElement;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import static com.moon.mapping.processing.PropertyAttr.DFT;
/**
* @author benshaoye
*/
abstract class BaseDefinition> extends LinkedHashMap
implements Completable, CanonicalNameable {
private final MapMethodFactory methodFactory = new MapMethodFactory();
private final MapFieldFactory fieldFactory = new MapFieldFactory();
private final Set sorts = new LinkedHashSet<>();
{ sorts.add("id"); }
private final Map> fieldAttrMap = new HashMap<>();
private final Map> setterAttrMap = new HashMap<>();
private final Map> getterAttrMap = new HashMap<>();
/**
* 声明注解{@link com.moon.mapping.annotation.MappingFor}的类
*/
private final TypeElement thisElement;
public BaseDefinition(TypeElement enclosingElement) { this.thisElement = enclosingElement; }
public final TypeElement getThisElement() { return thisElement; }
public final boolean isInterface() { return getThisElement().getKind().isInterface(); }
public final MapMethodFactory getMethodFactory() { return methodFactory; }
public final MapFieldFactory getFieldFactory() { return fieldFactory; }
@Override
public final String getCanonicalName() { return ElementUtils.getQualifiedName(getThisElement()); }
final void addFieldAttr(String name, PropertyAttr attr) {
getFieldAttrMap().computeIfAbsent(attr.getTargetCls(), k -> new HashMap<>(4)).put(name, attr);
}
final void addSetterAttr(String name, PropertyAttr attr) {
getSetterAttrMap().computeIfAbsent(attr.getTargetCls(), k -> new HashMap<>(4)).put(name, attr);
}
final void addGetterAttr(String name, PropertyAttr attr) {
getGetterAttrMap().computeIfAbsent(attr.getTargetCls(), k -> new HashMap<>(4)).put(name, attr);
}
public Map> getFieldAttrMap() { return fieldAttrMap; }
public Map> getGetterAttrMap() { return getterAttrMap; }
public Map> getSetterAttrMap() { return setterAttrMap; }
/**
* 声明{@link MappingFor}的类{@link #getThisElement()}所在包的完整名
*
* @return 包名
*/
public final String getPackageName() { return ElementUtils.getPackageName(getThisElement()); }
/**
* {@link #getThisElement()}的类名,如果是内部类,也只返回最后一部分
*
* @return
*/
@Override
public final String getSimpleName() { return ElementUtils.getSimpleName(getThisElement()); }
/**
* {@link #getThisElement()}的完整合法名称
*
* @return
*/
public final String getQualifiedName() { return ElementUtils.getQualifiedName(getThisElement()); }
@Override
public void onCompleted() { forEach((name, prop) -> prop.onCompleted()); }
/**
* 实现{@link BeanMapping}的公共方法
*/
public StringAdder implMappingSharedMethods(final Manager manager) {
final StringAdder adder = new StringAdder();
addMapMapping(adder, manager);
addObjectMapping(adder);
return adder;
}
final void addBeanMapping(StringAdder adder, BaseDefinition thatDef, Manager manager) {
adder.add("TO_" + StringUtils.underscore(thatDef.getCanonicalName())).add(" {");
final String thisCls = manager.onImported(getCanonicalName());
final String thatCls = manager.onImported(thatDef.getCanonicalName());
final boolean emptyForward = unsafeConvert(adder, thatDef, manager, ConvertStrategy.FORWARD);
final boolean emptyBackward = unsafeConvert(adder, thatDef, manager, ConvertStrategy.BACKWARD);
adder.add(getMethodFactory().newThatOnEmptyConstructor(thisCls, thatCls, emptyForward));
adder.add(getMethodFactory().newThisOnEmptyConstructor(thisCls, thatCls, emptyBackward));
adder.add("},");
}
private static PropertyAttr findPropertyAttr(
BaseDefinition thatDef, Mappable thisProp, Map> propertiesMap
) {
final String targetClass = thatDef.getCanonicalName();
Map attrMap = propertiesMap.get(targetClass);
PropertyAttr attr;
if (attrMap == null) {
attrMap = propertiesMap.getOrDefault("void", Collections.emptyMap());
attr = attrMap.get(thisProp.getName());
} else {
attr = attrMap.get(thisProp.getName());
if (attr == null) {
attrMap = propertiesMap.getOrDefault("void", Collections.emptyMap());
attr = attrMap.get(thisProp.getName());
}
}
return attr;
}
private PropertyAttr getPropertyAttr(BaseDefinition thatDef, Mappable thisProp, ConvertStrategy strategy) {
Map propertiesMap = strategy.getMethodAttrMap(this);
PropertyAttr attr = findPropertyAttr(thatDef, thisProp, propertiesMap);
if (attr == null) {
attr = findPropertyAttr(thatDef, thisProp, getFieldAttrMap());
}
return attr == null ? DFT : attr;
}
private boolean unsafeConvert(
StringAdder adder, final BaseDefinition thatDef, Manager manager, ConvertStrategy strategy
) {
manager.ofScoped().onStartScoped();
Collection fields = reducing(thisProp -> {
PropertyAttr attr = getPropertyAttr(thatDef, thisProp, strategy);
if (strategy.isIgnore(attr)) {
return null;
}
String targetName = attr.getField(thisProp.getName());
Mappable thatProp = (Mappable) thatDef.get(targetName);
if (manager.canUsableModel(thisProp, thatProp, attr, strategy)) {
return getFieldFactory().doConvertField(manager);
}
return null;
});
return forMethod(adder, fields, this, thatDef, manager, strategy);
}
private static boolean forMethod(
StringAdder adder,
Collection fields,
BaseDefinition thisDef,
BaseDefinition thatDef,
Manager manager,
ConvertStrategy strategy
) {
if (fields.isEmpty()) {
return true;
} else {
String thisClass = manager.onImported(thisDef.getCanonicalName());
String thatClass = manager.onImported(thatDef.getCanonicalName());
MapMethodFactory factory = thisDef.getMethodFactory();
adder.add(strategy.forMethod(factory, thisClass, thatClass, fields));
return false;
}
}
private void addMapMapping(final StringAdder adder, final Manager manager) {
final String name = getSimpleName();
final MapMethodFactory f = getMethodFactory();
// fromMap(Object,Map)
adder.add(f.fromMapMethod(name, reducing(mappable -> f.fromMapField(mappable, manager))));
// toMap(Object,Map)
adder.add(f.toMapMethod(name, reducing(f::toMapField)));
// newThis(Map)
adder.add(f.newThisAsMapMethod(name));
}
private void addObjectMapping(final StringAdder adder) {
final String name = getSimpleName();
final MapMethodFactory f = getMethodFactory();
// clone(Object)
adder.add(f.cloneMethod(name, name, reducing(f::cloneField)));
// toString(Object)
adder.add(f.toStringMethod(name, reducing((list, property) ->//
f.toStringField(property, list.isEmpty()))));
}
private Collection reducing(Function serializer) {
return reducing((m, prop) -> serializer.apply(prop));
}
private Collection reducing(BiFunction
© 2015 - 2025 Weber Informatics LLC | Privacy Policy