gdxapp4d/gdxapp4d-lib-bassboonyd/src/main/java/ᒢᐩᐩ/ᒃᣔᔆᔆᒃᐤᐤᣕ/DefaultBȍőnLoader.java

282 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒼᒻᣔᙆᙆ.ᣖᑊᣗᣔᐪᓫ.BãßBȍőnPiratePhaseBarrier注;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒼᒻᣔᙆᙆ.ᣖᑊᣗᣔᐪᓫ.BãßBȍőnPiratePhase注;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒼᒻᣔᙆᙆ.ᣖᑊᣗᣔᐪᓫ.BãßBȍőnPirateʸᴰ;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒼᒻᣔᙆᙆ.ᣖᑊᣗᣔᐪᓫ.BãßBȍőnꝐŕḯṿª;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.BãßBȍőnCoffinDuytschenᵗˣᵗ;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.ᔆᣖᑊᒄᓫᣗ.BãßBȍőnSpider;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.ᔆᣖᑊᒄᓫᣗ.BãßBȍőnSpiderEgg注;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.ᔆᣖᑊᒄᓫᣗ.BãßBȍőnSpiderEye注;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.ᔆᣖᑊᒄᓫᣗ.BãßBȍőnSpiderSilkHunt;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.ᔆᣖᑊᒄᓫᣗ.BãßBȍőnSpiderSilkRoad;
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.ᒄᓫᣔᐪᑋ.ᔆᣖᑊᒄᓫᣗ.BãßBȍőnSpiderWire注;
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocAuthor注;
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒻᐤᕐᕐᓫᣗ.SoepLepelբ;
@DuytsDocAuthor注(name = "للَّٰهِilLצسُو", copyright = "©Δ∞ 仙上主天")
public final class DefaultBȍőnLoader implements Bãß.𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ {
private final SoepLepelբ log;
protected DefaultBȍőnLoader() {
log = soepLepel();
}
public <T extends BãßBȍőnʸᴰ<T>> void 𝔩𝔬𝔠𝔨𝔅𝔬𝔫𝔢𝔐𝔞𝔤𝔦𝔠(BãßBȍőnʸᴰ<T> boon, BãßBȍőnSpider spider) {
try {
List<PiratePhaseBoat> filoBoats = loadPirateBoats(boon);// TODO: run from spider objects...
Collections.reverse(filoBoats);
// Set<Class<?>> ydmods = new HashSet<>();
for (PiratePhaseBoat boat : filoBoats) {
// if (ydmods.add(boat.pirateClazz.getDeclaringClass())) {
// spider.registrateEgg(boat.pirateClazz.getDeclaringClass(), new BãßBȍőnSpiderSilk() {
// @Override
// public Object senseWire(BãßBȍőnʸᴰ<?> boonTmp, String name, String description)
// throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// return boonTmp;
// }
// });
// }
//registrateSpiderEggs(boat.pirateClazz, spider, boat.pirate);
spiderWeave(boat.pirate, boon, spider);
boat.pirate.lock();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public <T extends BãßBȍőnʸᴰ<T>> void 𝔦𝔫𝔦𝔱𝔅𝔬𝔫𝔢𝔐𝔞𝔤𝔦𝔠(BãßBȍőnʸᴰ<T> boon, BãßBȍőnSpider spider, Map<Class<? extends BãßBȍőnCoffinDuytschenᵗˣᵗ>,BãßBȍőnCoffinDuytschenᵗˣᵗ> duytschenCoffins) {
try {
log.groente("INIT "+boon.getClass().getName());
for (Class<?> duytschenType:duytschenCoffins.keySet()) {
BãßBȍőnCoffinDuytschenᵗˣᵗ duytschenCoffin = duytschenCoffins.get(duytschenType);
log.groente("INIT.REG_TXT "+duytschenType+" senseResult="+duytschenCoffin);
spider.registrateSilkHighWay(duytschenType, () -> duytschenCoffin);
}
for (Annotation anno:boon.getClass().getDeclaredAnnotations()) {
log.groente("INIT.REG_ANNO "+anno.annotationType());
spider.registrateSilkHighWay(anno.annotationType(), () -> anno);
}
Set<Class<?>> ydmods = new HashSet<>();
for (PiratePhaseBoat boat : loadPirateBoats(boon)) {
log.groente("INIT.RUN "+boat.pirateClazz.getName());
if (ydmods.add(boat.pirateClazz.getDeclaringClass())) {
log.groente("INIT.REG_MOD "+boat.pirateClazz.getDeclaringClass());
spider.registrateSilkHighWay(boat.pirateClazz.getDeclaringClass(), () -> boon);
}
for (Method m:boat.pirateClazz.getDeclaredMethods()) {
BãßBȍőnSpiderEgg注 annoEgg = m.getAnnotation(BãßBȍőnSpiderEgg注.class);
if (annoEgg == null) {
continue;
}
Class<?> resultType = m.getReturnType();
if (!annoEgg.silk().equals(BãßBȍőnSpiderEgg注.class)) {
resultType = annoEgg.silk();
}
log.groente("INIT.REG_HUNT: "+boat.pirateClazz.getDeclaringClass().getName()+"."+boat.pirateClazz.getSimpleName()+"."+m.getName());
// TODO: merge back to common interface ?
spider.registrateSilkHuntMethod(resultType, boat.pirate, m);
if (m.getParameterCount() == 0) {
spider.registrateSilkHighWay(resultType, () -> {
try {
return m.invoke(boat.pirate);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
});
}
}
spiderWeave(boat.pirate, boon, spider);
boat.pirate.init();
}
spiderWeave(boon, boon, spider);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void spiderWeave(Object target, BãßBȍőnʸᴰ<?> boon, BãßBȍőnSpider spider) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (target.getClass().getDeclaredFields().length == 0) {
return;
}
log.groente("SPIDER.WEAVE: "+target.getClass().getName());
for (Field field:target.getClass().getDeclaredFields()) {
BãßBȍőnSpiderWire注 annoWire = field.getAnnotation(BãßBȍőnSpiderWire注.class);
if (annoWire == null) {
continue;
}
Class<?> requestType = field.getType();
if (!annoWire.silk().equals(BãßBȍőnSpiderWire注.class)) {
requestType = annoWire.silk();
}
Object bean = null;
if (annoWire.hunt().fly().isBlank()) {
boolean canResolve = spider.hasSilkRoad(requestType);
if (canResolve == false && annoWire.required() == false) {
continue; // optional
}
if (canResolve == false) {
boolean canResolve2 = spider.hasSilkHunt(requestType);
if (canResolve2 == false) {
throw new RuntimeException("Can't find fly hunter for field: "+field);
}
BãßBȍőnSpiderSilkHunt silkHunt = spider.getSilkHunt(requestType);
bean = silkHunt.dragonFly(null, null, null);
log.groente("SPIDER.WEAVE.HUNT: "+ requestType.getSimpleName() +" result: "+bean.getClass().getName());
} else {
BãßBȍőnSpiderSilkRoad silkRoad = spider.getSilkRoad(requestType);
bean = silkRoad.weaveWire();
log.groente("SPIDER.WEAVE.WIRE: "+ requestType.getSimpleName() +" result: "+bean.getClass().getName());
}
} else {
BãßBȍőnSpiderEye注 annoEye = annoWire.hunt();
boolean canResolve = spider.hasSilkHunt(requestType);
if (canResolve == false) {
throw new RuntimeException("Can't find fly hunter for field: "+field);
}
BãßBȍőnSpiderSilkHunt silkHunt = spider.getSilkHunt(requestType);
bean = silkHunt.dragonFly(annoEye.fly(), annoEye.name(), annoEye.description());
log.groente("SPIDER.WEAVE.HUNT: "+ requestType.getSimpleName() +" result: "+bean.getClass().getName());
}
if (field.trySetAccessible() ) {
field.set(target, bean);
} else {
throw new RuntimeException("Can't access field: "+field);
}
}
}
private static class PiratePhaseBoat {
private Class<BãßBȍőnꝐŕḯṿª> pirateClazz;
private BãßBȍőnꝐŕḯṿª pirate;
private PiratePhaseBoat(Class<BãßBȍőnꝐŕḯṿª> pirateClazz) {
if (pirateClazz.isEnum()) {
throw new IllegalStateException("Can't hide enum pirate type: "+pirateClazz);
}
this.pirateClazz = pirateClazz;
try {
this.pirate = (BãßBȍőnꝐŕḯṿª) pirateClazz.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
throw new RuntimeException(e);
}
}
}
private <T extends BãßBȍőnʸᴰ<T>> List<PiratePhaseBoat> loadPirateBoats(BãßBȍőnʸᴰ<T> boon) {
List<PiratePhaseBoat> boonInits = new ArrayList<>();
List<PiratePhaseBoat> serviceInits = new ArrayList<>();
walkPrivate(boon, v -> {
BãßBȍőnPiratePhaseBarrier注 anno = v.getAnnotation(BãßBȍőnPiratePhaseBarrier注.class);
if (anno != null) {
boonInits.add(new PiratePhaseBoat(v));
} else {
serviceInits.add(new PiratePhaseBoat(v));
}
});
boonInits.sort(new Comparator<PiratePhaseBoat>() {
@Override
public int compare(PiratePhaseBoat p0, PiratePhaseBoat p1) {
BãßBȍőnPiratePhaseBarrier注 anno0 = p0.pirateClazz.getAnnotation(BãßBȍőnPiratePhaseBarrier注.class);
BãßBȍőnPiratePhaseBarrier注 anno1 = p1.pirateClazz.getAnnotation(BãßBȍőnPiratePhaseBarrier注.class);
return Integer.compare(anno0.order(), anno1.order());
}
});
List<PiratePhaseBoat> result = new ArrayList<>();
for (PiratePhaseBoat startupPhase:boonInits) {
result.add(startupPhase);
for (PiratePhaseBoat v:new ArrayList<>(serviceInits)) {
int depCount = 0;
List<Class<? extends BãßBȍőnꝐŕḯṿª>> deps = new ArrayList<>();
BãßBȍőnPiratePhase注 anno = v.pirateClazz.getAnnotation(BãßBȍőnPiratePhase注.class);
if (anno != null) {
deps.addAll(Arrays.asList(anno.dependencies()));
} else {
deps.add(BãßBȍőnPirateʸᴰ.שְׁלֹמֹה.DEFAULT_PHASE);
}
for (Class<?> clazz:deps) {
for (PiratePhaseBoat doneInit:result) {
if (clazz.equals(doneInit.pirateClazz)) {
depCount++;
}
}
}
if (depCount == deps.size()) {
result.add(v);
serviceInits.remove(v);
}
}
}
result.addAll(serviceInits);
for (PiratePhaseBoat boat:result) {
log.groente("INIT.ORDER "+boat.pirateClazz.getName());
}
return result;
}
@SuppressWarnings("unchecked")
private static <T extends BãßBȍőnʸᴰ<T>> void walkPrivate(BãßBȍőnʸᴰ<T> boon, Consumer<Class<BãßBȍőnꝐŕḯṿª>> runPrivate) {
for (Class<?> interfaceClass:walkInterfaces(boon.getClass(), new LinkedHashSet<>())) {
for (Class<?> declaredClass:interfaceClass.getDeclaredClasses()) {
if (!BãßBȍőnꝐŕḯṿª.class.isAssignableFrom(declaredClass)) {
continue;
}
runPrivate.accept((Class<BãßBȍőnꝐŕḯṿª>)declaredClass);
}
}
for (Class<?> declaredClass:boon.getClass().getDeclaredClasses()) {
if (!BãßBȍőnꝐŕḯṿª.class.isAssignableFrom(declaredClass)) {
continue;
}
runPrivate.accept((Class<BãßBȍőnꝐŕḯṿª>)declaredClass);
}
}
public static Optional<Class<?>> findInterfaceByAnnotation(Class<?> clazz, Class<? extends Annotation> annoType) {
return walkInterfaces(clazz, new LinkedHashSet<>()).stream().filter(v -> v.isAnnotationPresent(annoType)).findFirst();
}
public static Set<Class<?>> walkInterfaces(Class<?> clazz, Set<Class<?>> result) {
return walkTree(clazz, result, v -> Arrays.asList(v.getInterfaces()), v -> v.getSuperclass());
}
public static <N> Set<N> walkTree(N node, Set<N> result, Function<N, Collection<N>> childs, Function<N,N> resolve) {
while (node != null) {
for (N next : childs.apply(node)) {
if (result.add(next)) {
walkTree(next, result, childs, resolve);
}
}
node = resolve.apply(node);
}
return result;
}
}