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

org.nuiton.topia.service.sql.internal.TopiaEntitySqlModelResourceImpl Maven / Gradle / Ivy

The newest version!
package org.nuiton.topia.service.sql.internal;

/*-
 * #%L
 * ToPIA Extension :: API
 * %%
 * Copyright (C) 2018 - 2022 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.ultreia.java4all.util.json.adapters.ClassAdapter;
import io.ultreia.java4all.util.SingletonSupplier;
import org.nuiton.topia.persistence.TopiaException;
import org.nuiton.topia.service.sql.TopiaEntitySqlModelResource;
import org.nuiton.topia.service.sql.blob.TopiaEntitySqlBlob;
import org.nuiton.topia.service.sql.blob.TopiaEntitySqlBlobAdapter;
import org.nuiton.topia.service.sql.blob.TopiaEntitySqlBlobModel;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataEntity;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataEntityAdapter;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataEntityPath;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataEntityPathAdapter;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataLink;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataLinkAdapter;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataModel;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataModelPaths;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataModelPathsAdapter;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlAssociationTable;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlDescriptor;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlDescriptorAdapter;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlModel;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlReverseAssociationTable;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlReverseCompositionTable;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlSelector;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlSelectorAdapter;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlSimpleAssociationTable;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlTable;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlTableAdapter;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlan;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlanAdapter;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlanModel;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlanTask;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlanTaskAdapter;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlan;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlanAdapter;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlanModel;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlanTask;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlanTaskAdapter;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlan;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlanAdapter;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlanModel;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlanTask;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlanTaskAdapter;
import org.nuiton.topia.service.sql.request.ReplicatePartialRequestCallback;
import org.nuiton.topia.service.sql.request.ReplicateRequestCallback;
import org.nuiton.topia.service.sql.usage.TopiaEntitySqlUsageModel;
import org.nuiton.topia.service.sql.usage.TopiaUsageReverseAssociation;
import org.nuiton.topia.service.sql.usage.TopiaUsageReverseComposition;
import org.nuiton.topia.service.sql.usage.TopiaUsageReverseManyToManyAssociation;
import org.nuiton.topia.service.sql.usage.TopiaUsageReverseOneToManyAssociation;
import org.nuiton.topia.service.sql.usage.TopiaUsageReverseOneToOneComposition;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Set;

import static org.nuiton.topia.service.sql.model.AbstractTopiaEntitySqlAssociationTableAdapter.TopiaEntitySqlAssociationTableAdapter;
import static org.nuiton.topia.service.sql.model.AbstractTopiaEntitySqlAssociationTableAdapter.TopiaEntitySqlReverseAssociationTableAdapter;
import static org.nuiton.topia.service.sql.model.AbstractTopiaEntitySqlAssociationTableAdapter.TopiaEntitySqlReverseCompositionTableAdapter;
import static org.nuiton.topia.service.sql.model.AbstractTopiaEntitySqlAssociationTableAdapter.TopiaEntitySqlSimpleAssociationTableAdapter;
import static org.nuiton.topia.service.sql.usage.TopiaUsageLinkAdapter.TopiaUsageReverseAssociationAdapter;
import static org.nuiton.topia.service.sql.usage.TopiaUsageLinkAdapter.TopiaUsageReverseCompositionAdapter;
import static org.nuiton.topia.service.sql.usage.TopiaUsageLinkAdapter.TopiaUsageReverseManyToManyAssociationAdapter;
import static org.nuiton.topia.service.sql.usage.TopiaUsageLinkAdapter.TopiaUsageReverseOneToManyAssociationAdapter;
import static org.nuiton.topia.service.sql.usage.TopiaUsageLinkAdapter.TopiaUsageReverseOneToOneCompositionAdapter;

/**
 * Created on 01/03/2022.
 *
 * @author Tony Chemit - [email protected]
 * @since 1.67
 */
public abstract class TopiaEntitySqlModelResourceImpl implements TopiaEntitySqlModelResource {

    private final SingletonSupplier metaModel;
    private final SingletonSupplier metaModelPaths;
    private final SingletonSupplier model;
    private final SingletonSupplier copyPlanModel;
    private final SingletonSupplier deletePlanModel;
    private final SingletonSupplier usageModel;
    private final SingletonSupplier blobModel;
    private final SingletonSupplier replicatePlanModel;
    private final SingletonSupplier> replicatePartialRequestCallbacks;
    private final SingletonSupplier> replicateRequestCallbacks;

    public static GsonBuilder getGsonBuilder() {
        return new GsonBuilder()
                .disableHtmlEscaping()
                .registerTypeAdapter(Class.class, new ClassAdapter())
                .registerTypeAdapter(TopiaEntitySqlBlob.class, new TopiaEntitySqlBlobAdapter())
                .registerTypeAdapter(TopiaUsageReverseOneToManyAssociation.class, new TopiaUsageReverseOneToManyAssociationAdapter())
                .registerTypeAdapter(TopiaUsageReverseOneToOneComposition.class, new TopiaUsageReverseOneToOneCompositionAdapter())
                .registerTypeAdapter(TopiaUsageReverseComposition.class, new TopiaUsageReverseCompositionAdapter())
                .registerTypeAdapter(TopiaUsageReverseManyToManyAssociation.class, new TopiaUsageReverseManyToManyAssociationAdapter())
                .registerTypeAdapter(TopiaUsageReverseAssociation.class, new TopiaUsageReverseAssociationAdapter())
                .registerTypeAdapter(TopiaEntitySqlDescriptor.class, new TopiaEntitySqlDescriptorAdapter())
                .registerTypeAdapter(TopiaEntitySqlTable.class, new TopiaEntitySqlTableAdapter())
                .registerTypeAdapter(TopiaEntitySqlSelector.class, new TopiaEntitySqlSelectorAdapter())
                .registerTypeAdapter(TopiaEntitySqlAssociationTable.class, new TopiaEntitySqlAssociationTableAdapter())
                .registerTypeAdapter(TopiaEntitySqlSimpleAssociationTable.class, new TopiaEntitySqlSimpleAssociationTableAdapter())
                .registerTypeAdapter(TopiaEntitySqlReverseAssociationTable.class, new TopiaEntitySqlReverseAssociationTableAdapter())
                .registerTypeAdapter(TopiaEntitySqlReverseCompositionTable.class, new TopiaEntitySqlReverseCompositionTableAdapter())
                .registerTypeAdapter(TopiaEntitySqlDeletePlan.class, new TopiaEntitySqlDeletePlanAdapter())
                .registerTypeAdapter(TopiaEntitySqlDeletePlanTask.class, new TopiaEntitySqlDeletePlanTaskAdapter())
                .registerTypeAdapter(TopiaEntitySqlCopyPlan.class, new TopiaEntitySqlCopyPlanAdapter())
                .registerTypeAdapter(TopiaEntitySqlCopyPlanTask.class, new TopiaEntitySqlCopyPlanTaskAdapter())
                .registerTypeAdapter(TopiaEntitySqlReplicatePlan.class, new TopiaEntitySqlReplicatePlanAdapter())
                .registerTypeAdapter(TopiaEntitySqlReplicatePlanTask.class, new TopiaEntitySqlReplicatePlanTaskAdapter())
                .setPrettyPrinting();
    }

    public static String toMetaModelLocation(String modelName) {
        return toLocation(TopiaMetadataModel.class, modelName);
    }

    public static String toMetaModelPathsLocation(String modelName) {
        return toLocation(TopiaMetadataModelPaths.class, modelName);
    }

    public static String toModelLocation(String modelName) {
        return toLocation(TopiaEntitySqlModel.class, modelName);
    }

    public static String toCopyPlanLocation(String modelName) {
        return toLocation(TopiaEntitySqlCopyPlanModel.class, modelName);
    }

    public static String toReplicatePlanLocation(String modelName) {
        return toLocation(TopiaEntitySqlReplicatePlanModel.class, modelName);
    }

    public static String toDeletePlanLocation(String modelName) {
        return toLocation(TopiaEntitySqlDeletePlanModel.class, modelName);
    }

    public static String toUsageModelLocation(String modelName) {
        return toLocation(TopiaEntitySqlUsageModel.class, modelName);
    }

    public static String toBlobModelLocation(String modelName) {
        return toLocation(TopiaEntitySqlBlobModel.class, modelName);
    }

    public static String toLocation(Class type, String modelName) {
        return String.format("META-INF/persistence/%s/%s.json", Objects.requireNonNull(modelName), type.getSimpleName());
    }

    public static  O load(Class type, String location, Gson gson) {
        URL resource = Objects.requireNonNull(type).getClassLoader().getResource(Objects.requireNonNull(location));
        try (Reader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(resource).openStream(), StandardCharsets.UTF_8))) {
            return Objects.requireNonNull(gson).fromJson(reader, type);
        } catch (IOException e) {
            throw new TopiaException(String.format("Could not load resource: %s (for type: %s)", resource, type.getName()), e);
        }
    }

    protected TopiaEntitySqlModelResourceImpl(String modelName, Gson gson) {
        this.metaModel = SingletonSupplier.of(() -> {
            TopiaMetadataModel result = load(TopiaMetadataModel.class, toMetaModelLocation(modelName), getGsonBuilder()
                    .registerTypeAdapter(TopiaMetadataEntity.class, new TopiaMetadataEntityAdapter())
                    .enableComplexMapKeySerialization().create());
            result.applyInheritance();
            return result;
        });
        this.metaModelPaths = SingletonSupplier.of(() -> load(TopiaMetadataModelPaths.class, toMetaModelPathsLocation(modelName), gson
                .newBuilder()
                .registerTypeAdapter(TopiaMetadataEntityPath.class, new TopiaMetadataEntityPathAdapter())
                .registerTypeAdapter(TopiaMetadataModelPaths.class, new TopiaMetadataModelPathsAdapter(getMetaModel()))
                .registerTypeHierarchyAdapter(TopiaMetadataLink.class, new TopiaMetadataLinkAdapter(getMetaModel()))
                .enableComplexMapKeySerialization()
                .create()));
        this.model = SingletonSupplier.of(() -> load(TopiaEntitySqlModel.class, toModelLocation(modelName), gson));
        this.copyPlanModel = SingletonSupplier.of(() -> load(TopiaEntitySqlCopyPlanModel.class, toCopyPlanLocation(modelName), gson));
        this.replicatePlanModel = SingletonSupplier.of(() -> load(TopiaEntitySqlReplicatePlanModel.class, toReplicatePlanLocation(modelName), gson));
        this.deletePlanModel = SingletonSupplier.of(() -> load(TopiaEntitySqlDeletePlanModel.class, toDeletePlanLocation(modelName), gson));
        this.usageModel = SingletonSupplier.of(() -> load(TopiaEntitySqlUsageModel.class, toUsageModelLocation(modelName), gson));
        this.blobModel = SingletonSupplier.of(() -> load(TopiaEntitySqlBlobModel.class, toBlobModelLocation(modelName), gson));
        this.replicatePartialRequestCallbacks = SingletonSupplier.of(() -> {
            Set callbacks = new LinkedHashSet<>();
            for (ReplicatePartialRequestCallback callback : ServiceLoader.load(ReplicatePartialRequestCallback.class)) {
                callbacks.add(callback);
            }
            return Collections.unmodifiableSet(callbacks);
        });this.replicateRequestCallbacks = SingletonSupplier.of(() -> {
            Set callbacks = new LinkedHashSet<>();
            for (ReplicateRequestCallback callback : ServiceLoader.load(ReplicateRequestCallback.class)) {
                callbacks.add(callback);
            }
            return Collections.unmodifiableSet(callbacks);
        });
    }

    @Override
    public TopiaMetadataModel getMetaModel() {
        return metaModel.get();
    }

    @Override
    public TopiaMetadataModelPaths getMetaModelPaths() {
        return metaModelPaths.get();
    }

    @Override
    public Set getReplicatePartialRequestCallbacks() {
        return replicatePartialRequestCallbacks.get();
    }

    @Override
    public Set getReplicateRequestCallbacks() {
        return replicateRequestCallbacks.get();
    }

    @Override
    public TopiaEntitySqlModel getModel() {
        return model.get();
    }

    @Override
    public TopiaEntitySqlCopyPlanModel getCopyPlanModel() {
        return copyPlanModel.get();
    }

    @Override
    public TopiaEntitySqlReplicatePlanModel getReplicatePlanModel() {
        return replicatePlanModel.get();
    }

    @Override
    public TopiaEntitySqlDeletePlanModel getDeletePlanModel() {
        return deletePlanModel.get();
    }

    @Override
    public TopiaEntitySqlUsageModel getUsageModel() {
        return usageModel.get();
    }

    @Override
    public TopiaEntitySqlBlobModel getBlobModel() {
        return blobModel.get();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy