SearchKey.java

/*
 * SPDX-FileCopyrightText: 2025 kaumei.io
 * SPDX-License-Identifier: Apache-2.0
 */
package io.kaumei.jdbc.anno.store;

import io.kaumei.jdbc.anno.ctx.Context;
import io.kaumei.jdbc.anno.model.ConverterNameDV;
import org.jspecify.annotations.Nullable;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;

import static io.kaumei.jdbc.anno.ctx.JavaModelUtils.component;

public class SearchKey implements Comparable<SearchKey> {

    public static SearchKey of(Context ctx, RecordComponentElement element) {
        var name = ctx.JDBC_CONVERTER_NAME.getAnno(element, ConverterNameDV.unnamed());
        return new SearchKey(element.asType(), name);
    }

    public static SearchKey of(Context ctx, VariableElement element) {
        var name = ctx.JDBC_CONVERTER_NAME.getAnno(element, ConverterNameDV.unnamed());
        return new SearchKey(element.asType(), name);
    }

    public static SearchKey jdbcToJava(Context ctx, ExecutableElement element) {
        var name = ctx.JDBC_TO_JAVA.getAnno(element, ConverterNameDV.unnamed());
        return ctx.optionalFlag(element, element.getReturnType()).isOptionalType()
                ? new SearchKey(component(element.getReturnType()), name)
                : new SearchKey(element.getReturnType(), name);
    }

    public static SearchKey of(TypeMirror type) {
        return new SearchKey(type, ConverterNameDV.unnamed());
    }

    public static SearchKey of(TypeMirror type, ConverterNameDV name) {
        return new SearchKey(type, name);
    }

    // ------------------------------------------------------------------------

    private final StoreID storeId;
    private final ConverterNameDV name;
    private final TypeMirror type;

    private SearchKey(TypeMirror type, ConverterNameDV name) {
        this.type = type;
        this.name = name;
        this.storeId = StoreID.of(type, name);
    }

    public StoreID toStoreId() {
        return this.storeId;
    }

    public TypeMirror type() {
        return this.type;
    }

    public boolean hasName() {
        return this.name.hasName();
    }

    public ConverterNameDV name() {
        return this.name;
    }

    // ------------------------------------------------------------------------

    @Override
    public int compareTo(SearchKey o) {
        return this.storeId.compareTo(o.storeId);
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) {
            return true;
        } else if (o == null || getClass() != o.getClass()) {
            return false;
        }
        return this.storeId.equals(((SearchKey) o).storeId);
    }

    @Override
    public int hashCode() {
        return this.storeId.hashCode();
    }

    @Override
    public String toString() {
        return "{type=" + type + ", name=" + name + '}';
    }

}