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

com.github.molcikas.photon.Photon Maven / Gradle / Ivy

The newest version!
package com.github.molcikas.photon;

import com.github.molcikas.photon.blueprints.AggregateBlueprint;
import com.github.molcikas.photon.blueprints.entity.EntityBlueprint;
import com.github.molcikas.photon.blueprints.entity.EntityBlueprintBuilder;
import com.github.molcikas.photon.converters.Convert;
import com.github.molcikas.photon.converters.Converter;
import com.github.molcikas.photon.datasource.GenericDataSource;
import com.github.molcikas.photon.options.PhotonOptions;
import com.github.molcikas.photon.exceptions.PhotonException;
import org.apache.commons.lang3.StringUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

/**
 * The top-level class for Photon.
 */
public class Photon
{
    private final DataSource dataSource;
    private final Map registeredAggregates;
    private final Map registeredViewModelAggregates;

    private final PhotonOptions photonOptions;

    public DataSource getDataSource()
    {
        return dataSource;
    }

    public PhotonOptions getOptions()
    {
        return photonOptions;
    }

    public static void registerConverter(Class destinationClass, Converter converter)
    {
        Convert.registerConverter(destinationClass, converter);
    }

    /**
     * Constructs a new photon. Use this constructor if not using a connection pooler. Uses the default photon
     * options.
     *
     * @param url - the JDBC URL
     * @param user - the database user
     * @param password - the database password
     */
    public Photon(String url, String user, String password)
    {
        this(new GenericDataSource(url, user, password));
    }

    /**
     * Constructs a new photon. Use this constructor if not using a connection pooler.
     *
     * @param url - the JDBC URL
     * @param user - the database user
     * @param password - the database password
     * @param photonOptions - the photon options to use
     */
    public Photon(String url, String user, String password, PhotonOptions photonOptions)
    {
        this(new GenericDataSource(url, user, password), photonOptions);
    }

    /**
     * Constructs a new photon. The data source will be used for creating transactions. Uses the default photon
     * options.
     *
     * @param dataSource - the data source used for creating transactions
     */
    public Photon(DataSource dataSource)
    {
        this(dataSource, null);
    }

    /**
     * Constructs a new photon. The data source will be used for creating transactions.
     *
     * @param dataSource - the data source used for creating transactions
     * @param photonOptions - the photon options to use
     */
    public Photon(DataSource dataSource, PhotonOptions photonOptions)
    {
        this.dataSource = dataSource;
        this.registeredAggregates = new HashMap<>();
        this.registeredViewModelAggregates = new HashMap<>();
        this.photonOptions = photonOptions != null ? photonOptions : PhotonOptions.defaultOptions();
    }

    /**
     * Obtains a connection and starts a new transaction.
     * @return - the transaction
     */
    public PhotonTransaction beginTransaction()
    {
        return new PhotonTransaction(
            getConnection(),
            false,
            registeredAggregates,
            registeredViewModelAggregates,
            this
        );
    }

    /**
     * Obtains a connection and starts a new "transaction" where each statement is auto committed immediately.
     * @return - the transaction
     */
    public PhotonTransaction beginAutoCommitTransaction()
    {
        return new PhotonTransaction(
                getConnection(),
                true,
                registeredAggregates,
                registeredViewModelAggregates,
                this
        );
    }

    /**
     * Creates a builder for constructing an aggregate entity blueprint.
     *
     * @param aggregateRootClass - the aggregate root entity class
     * @return - the aggregate entity builder for the aggregate root
     */
    public EntityBlueprintBuilder registerAggregate(Class aggregateRootClass)
    {
        return new EntityBlueprintBuilder(aggregateRootClass, this);
    }

    /**
     * Creates a builder for constructing a view model aggregate blueprint.
     *
     * View model aggregate blueprints can be used for querying but cannot be used for inserting, updating, or deleting.
     * Unlike regular aggregate blueprints, you can register the same class multiple times as long as each view model
     * has a unique name. Set alsoRegisterBlueprintForSaving to true to have this blueprint aldo be used for inserting,
     * updating, and deleting the aggregate.
     *
     * @param aggregateRootClass - the aggregate root entity class
     * @param aggregateBlueprintName - the name for the aggregate blueprint
     * @return - the aggregate entity blueprint builder for the aggregate root
     */
    public EntityBlueprintBuilder registerViewModelAggregate(
        Class aggregateRootClass,
        String aggregateBlueprintName)
    {
        return registerViewModelAggregate(aggregateRootClass, aggregateBlueprintName, false);
    }

    /**
     * Creates a builder for constructing a view model aggregate blueprint.
     *
     * View model aggregate blueprints can be used for querying but cannot be used for inserting, updating, or deleting.
     * Unlike regular aggregate blueprints, you can register the same class multiple times as long as each view model
     * has a unique name. Set alsoRegisterBlueprintForSaving to true to have this blueprint aldo be used for inserting,
     * updating, and deleting the aggregate.
     *
     * @param aggregateRootClass - the aggregate root entity class
     * @param aggregateBlueprintName - the name for the aggregate blueprint
     * @param alsoRegisterBlueprintForSaving - Also register the blueprint as the one to use for inserting, updating,
     *                                       and deleting the aggregate class.
     * @return - the aggregate entity blueprint builder for the aggregate root
     */
    public EntityBlueprintBuilder registerViewModelAggregate(
        Class aggregateRootClass,
        String aggregateBlueprintName,
        boolean alsoRegisterBlueprintForSaving)
    {
        return new EntityBlueprintBuilder(aggregateRootClass, aggregateBlueprintName, alsoRegisterBlueprintForSaving, this);
    }

    /**
     * Do not call this method directly. Instead, call registerAggregate().
     *
     * @param aggregateBlueprintName - the name for the aggregate blueprint
     * @param registerBlueprintForSaving - register class as well so that queried aggregates can be inserted, updated,
     *                                   or deleted
     * @param aggregateRootEntityBlueprint - the built aggregate root entity blueprint
     */
    public void registerBuiltAggregateBlueprint(
        String aggregateBlueprintName,
        boolean registerBlueprintForSaving,
        EntityBlueprint aggregateRootEntityBlueprint)
    {
        if(aggregateRootEntityBlueprint == null)
        {
            throw new PhotonException("AggregateBlueprint root entityBlueprint cannot be null.");
        }

        AggregateBlueprint blueprint = new AggregateBlueprint(
            aggregateRootEntityBlueprint,
            photonOptions
        );

        if(StringUtils.isNotEmpty(aggregateBlueprintName))
        {
            registeredViewModelAggregates.put(aggregateBlueprintName, blueprint);
        }

        if(registerBlueprintForSaving)
        {
            if (registeredAggregates.containsKey(aggregateRootEntityBlueprint.getEntityClass()))
            {
                // TODO: Print warning that aggregate was already registered and old registration is being replaced.
            }
            registeredAggregates.put(aggregateRootEntityBlueprint.getEntityClass(), blueprint);
        }
    }

    private Connection getConnection()
    {
        try
        {
            return dataSource.getConnection();
        }
        catch(Exception ex)
        {
            throw new PhotonException(ex, "Error getting connection.");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy