All Downloads are FREE. Search and download functionalities are using the official Maven repository.

one.xingyi.optics.annotations.processors.ClassOpticsWithTraversals Maven / Gradle / Ivy

There is a newer version: 1.5.9
Show newest version
package one.xingyi.optics.annotations.processors;

import lombok.*;
import one.xingyi.optics.annotations.serialise.IAnnotationProcessorLoader;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@EqualsAndHashCode
@Getter
@ToString
@RequiredArgsConstructor
public class ClassOpticsWithTraversals {
    private final String packageName;
    private final String className;
    private final boolean addListTraversal;
    private final List fieldDetails;
    private final List traversalDetails;
    private final boolean debug;

    public static ClassOpticsWithTraversals from(IAnnotationProcessorLoader, RecordedTraversals> store, ClassOpticsDetails details, Consumer log) throws IOException {
        List tds = Utils.map(details.getTraversalDetails(), td -> TraversalWithFullDetails.from(details, td, store, log));
        return new ClassOpticsWithTraversals(details.getPackageName(), details.getClassName(), details.isAddListTraversal(), details.getFieldDetails(),
                tds, details.isDebug());
    }

}

@EqualsAndHashCode
@Getter
@RequiredArgsConstructor
class TraversalWithFullDetails {
    protected final String name;
    protected final List path;

    public PackageAndClass getClassAtEnd() {
        return path.get(path.size() - 1).field.getFieldType();
    }
    static TraversalWithFullDetails from(ClassOpticsDetails recordDetails, TraversalDetails details, IAnnotationProcessorLoader, RecordedTraversals> store, Consumer log) throws IOException {
        var debug = recordDetails.isDebug();
        var path = details.path;
        if (path.size() == 0) throw new RuntimeException("No traversals for " + recordDetails.getClassName());
        String first = path.get(0);
        var rest = path.subList(1, path.size());
        log.accept("record details for " + recordDetails.getClassName() + " are " + recordDetails.getFieldDetails());
        Optional firstField = recordDetails.getFieldDetails().stream().filter(fd -> fd.name.equals(first)).findFirst();
        if (!firstField.isPresent())
            throw new RuntimeException("Could not find field" + first + " in the class " + recordDetails.getCanonicalName());
        var firstPart = new TraversalPathPart(recordDetails.getPackageAndClass(), new NameAndType(firstField.get().name, firstField.get().containedFieldType));

        List tds = Utils.foldLeft(rest, Collections.singletonList(firstPart), (acc, v) -> {
            var last = acc.get(acc.size() - 1);
            PackageAndClass lastFieldType = last.field.getFieldType();
            RecordedTraversals loaded = store.load(WithDebug.of(lastFieldType, recordDetails.isDebug()));
            if (debug) log.accept("Loaded for path (" + v + ") => " + loaded);
            var found = loaded.classAndFields.stream().filter(nat -> nat.getFieldName().equals(v)).findFirst();
            if (!found.isPresent())
                throw new RuntimeException("Could not find " + v + " in " + lastFieldType + " for " + recordDetails.getClassName() + ":" + path);
            return Utils.append(acc, new TraversalPathPart(lastFieldType, found.get()));
        });
        return new TraversalWithFullDetails(details.name, tds);
    }


    @Override
    public String toString() {
        return "TraversalWithFullDetails(" + this.name + ", " + this.path.stream().map(TraversalPathPart::toString).collect(Collectors.joining(",")) + ")";
    }
}

@EqualsAndHashCode
@Getter
@ToString
@RequiredArgsConstructor
class TraversalPathPart {
    final PackageAndClass main;
    final NameAndType field;

}






© 2015 - 2025 Weber Informatics LLC | Privacy Policy