class Blufin::YmlJavaDaoWriter

Constants

PACKAGE
PLACEHOLDER_GET_DEPENDENTS
PLACEHOLDER_MAP_ONE_BODY
PLACEHOLDER_MAP_TWO_BODY
PLACEHOLDER_OBJECT
PLACEHOLDER_OBJECT_LOWER
PLACEHOLDER_PARENT_TABLE
PLACEHOLDER_POST_FIELDS
PLACEHOLDER_POST_VALUES
PLACEHOLDER_PREPARE_POST
PLACEHOLDER_PREPARE_PUT
PLACEHOLDER_PUT_FIELDS
PLACEHOLDER_SITE_DOMAIN
PLACEHOLDER_SITE_NAME
PLACEHOLDER_TABLE
SERVICE

Public Class Methods

new(site, schema_data, schema_resources, schema_fks) click to toggle source

@return void

# File lib/core/yml_writers/yml_java_dao_writer.rb, line 24
        def initialize(site, schema_data, schema_resources, schema_fks)

            @schema_data      = schema_data
            @schema_resources = schema_resources
            @schema_fks       = schema_fks

            raise RuntimeError, 'Could not find valid @schema_data.' if @schema_data.nil? || !@schema_data.is_a?(Hash)
            raise RuntimeError, 'Could not find valid @schema_resources.' if @schema_resources.nil? || !@schema_resources.is_a?(Hash)

            @site             = Blufin::SiteResolver::validate_site(site)
            @site_name        = Blufin::SiteResolver::get_site_name(@site)
            @site_domain      = Blufin::SiteResolver::get_site_domain(@site)
            @site_domain_gsub = @site_domain.strip == '' ? '' : "#{@site_domain}."
            @site_location    = "#{Blufin::SiteResolver::get_site_location(@site)}/"

            # Wipe out all previous files.
            Blufin::YmlSchemaValidator::VALID_SCHEMAS_GENERATE.each do |schema|
                path_to_wipe_out = "#{get_java_path(@site, schema, SERVICE, PACKAGE)}"
                if Blufin::Files::path_exists(path_to_wipe_out)
                    if Blufin::Files::get_files_in_dir(path_to_wipe_out).any?
                        Blufin::Terminal::command('rm *', path_to_wipe_out, false, false)
                    end
                end
            end

            @template = <<TEMPLATE
package #{PLACEHOLDER_SITE_DOMAIN}#{PLACEHOLDER_SITE_NAME}.api.#{PACKAGE};

import org.blufin.api.base.AbstractDao;
import org.blufin.base.utils.UtilsLogger;
import org.blufin.base.exceptions.BlufinClientException;
import org.blufin.base.exceptions.BlufinAlertDeveloperException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.blufin.base.helper.IdSet;
import org.blufin.sdk.rest.GetRequest;
import #{PLACEHOLDER_SITE_DOMAIN}#{PLACEHOLDER_SITE_NAME}.sdk.dto.#{PLACEHOLDER_OBJECT};
import lombok.Getter;
import org.blufin.sdk.enums.PayloadType;
import org.blufin.base.enums.DataType;
import org.blufin.base.helper.Pair;
import org.blufin.base.helper.Triplet;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import org.springframework.stereotype.Service;
import java.sql.SQLException;#{PLACEHOLDER_IMPORT}

@Service
public class #{PLACEHOLDER_OBJECT}Dao extends AbstractDao<#{PLACEHOLDER_OBJECT}> {

    @Getter
    private static final #{PLACEHOLDER_OBJECT}Dao instance = new #{PLACEHOLDER_OBJECT}Dao();

    private #{PLACEHOLDER_OBJECT}Dao() {

        super("#{PLACEHOLDER_TABLE}", #{PLACEHOLDER_PARENT_TABLE});
    }

    @Override
    public List<#{PLACEHOLDER_OBJECT}> map(ResultSet rs) throws SQLException {

        List<#{PLACEHOLDER_OBJECT}> #{PLACEHOLDER_OBJECT_LOWER}List = new ArrayList<>();

        while(rs.next()) {

            #{PLACEHOLDER_OBJECT} #{PLACEHOLDER_OBJECT_LOWER} = new #{PLACEHOLDER_OBJECT}();

#{PLACEHOLDER_MAP_ONE_BODY}

            #{PLACEHOLDER_OBJECT_LOWER}List.add(#{PLACEHOLDER_OBJECT_LOWER});
        }

        return #{PLACEHOLDER_OBJECT_LOWER}List;
    }

    @Override
    public List<Map<String, String>> map(ResultSet rs, List<String> fields) {

#{PLACEHOLDER_MAP_TWO_BODY}
    }

    @Override
    @SuppressFBWarnings
    protected PreparedStatement preparePostStatement(Connection connection, #{PLACEHOLDER_OBJECT} #{PLACEHOLDER_OBJECT_LOWER}) throws SQLException {

        PreparedStatement statement = connection.prepareStatement("INSERT INTO #{PLACEHOLDER_TABLE} (#{PLACEHOLDER_POST_FIELDS}) VALUES (#{PLACEHOLDER_POST_VALUES})", Statement.RETURN_GENERATED_KEYS);

#{PLACEHOLDER_PREPARE_POST}
        return statement;
    }

    @Override
    @SuppressFBWarnings
    protected PreparedStatement preparePutStatement(Connection connection, #{PLACEHOLDER_OBJECT} #{PLACEHOLDER_OBJECT_LOWER}) throws SQLException {

        PreparedStatement statement = connection.prepareStatement("UPDATE #{PLACEHOLDER_TABLE} SET #{PLACEHOLDER_PUT_FIELDS} WHERE `id` = ?", Statement.RETURN_GENERATED_KEYS);

#{PLACEHOLDER_PREPARE_PUT}
        return statement;
    }

    @Override
    protected List<Triplet<AbstractDao, String, DataType>> getDependents() {

#{PLACEHOLDER_GET_DEPENDENTS}
    }
}
TEMPLATE

        end

Public Instance Methods

write() click to toggle source

@return void

# File lib/core/yml_writers/yml_java_dao_writer.rb, line 142
def write

    @schema_data.each do |schema, schema_data|

        schema_data.each do |table, table_data|

            if table_data.length > 0

                contents = @template

                table_camel_case       = Blufin::Strings::snake_case_to_camel_case(table)
                table_camel_case_lower = Blufin::Strings::snake_case_to_camel_case_lower(table)

                dto_method_body   = []
                import_statements = []
                field_names_post  = []
                field_names_put   = []
                prepare_post      = []
                prepare_put       = []
                get_dependents    = []
                idx_post          = 0
                idx_put           = 0

                table_data.each do |column_name, column_data|

                    # Skip Placeholders
                    next if column_name =~ /\A(#{Blufin::YmlSchemaValidator::VALID_SCHEMAS_REGEX})\.[a-z_]+\[\]\z/ || column_name =~ /\A(#{Blufin::YmlSchemaValidator::VALID_SCHEMAS_REGEX})\.[a-z_]+\z/ || column_name =~ /\A[a-z_.]+\[#{Blufin::YmlSchemaValidator::LINK}\]/

                    @type     = column_data[Blufin::YmlSchemaValidator::TYPE]
                    @fkey     = column_data.has_key?(Blufin::YmlSchemaValidator::FKEY)
                    @is_child = column_data.has_key?(Blufin::YmlSchemaValidator::CHILD_OF) && column_data.has_key?(Blufin::YmlSchemaValidator::CHILD_TYPE)

                    # Skip Transient Objects.
                    next if [Blufin::ScannerJavaEmbeddedObjects::OBJECT].include?(@type)

                    # Handle ID column differently.
                    if column_name == Blufin::YmlSchemaValidator::ID
                        dto_method_body << "            #{table_camel_case_lower}.setId(rs.getInt(\"id\"));"
                        next
                    end

                    field_camel_case = Blufin::Strings.snake_case_to_camel_case(column_name.dup)

                    if [Blufin::YmlSchemaValidator::TYPE_DATETIME_INSERT].include?(@type)
                        idx_post += 1
                        field_names_post << column_name.dup
                    else
                        idx_post += 1
                        idx_put  += 1 unless @is_child
                        field_names_post << column_name.dup
                        field_names_put << column_name.dup unless @is_child
                    end

                    if @type == Blufin::YmlSchemaValidator::TYPE_BOOLEAN
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getBoolean(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.BOOLEAN, #{table_camel_case_lower}.is#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.BOOLEAN, #{table_camel_case_lower}.is#{field_camel_case}());"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_DATE
                        import_statements << 'import org.blufin.base.utils.UtilsDate;'
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(getLocalDate(rs.getDate(\"#{column_name}\")));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.DATE, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.DATE, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_DATETIME
                        import_statements << 'import org.blufin.core.auth.client.ClientData;'
                        import_statements << 'import org.blufin.base.utils.UtilsDate;'
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(getZonedDateTime(rs.getTimestamp(\"#{column_name}\"), ClientData.getTimeZone().getZoneId()));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.DATETIME, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.DATETIME, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_DATETIME_INSERT
                        import_statements << 'import java.time.ZonedDateTime;'
                        import_statements << 'import org.blufin.base.utils.UtilsDate;'
                        import_statements << 'import org.blufin.core.auth.client.ClientData;'
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(getZonedDateTime(rs.getTimestamp(\"#{column_name}\"), ClientData.getTimeZone().getZoneId()));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.DATETIME_INSERT, null);"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_DATETIME_UPDATE
                        import_statements << 'import java.time.ZonedDateTime;'
                        import_statements << 'import org.blufin.base.utils.UtilsDate;'
                        import_statements << 'import org.blufin.core.auth.client.ClientData;'
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(getZonedDateTime(rs.getTimestamp(\"#{column_name}\"), ClientData.getTimeZone().getZoneId()));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.DATETIME_UPDATE, null);"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.DATETIME_UPDATE, null);"
                    elsif @type =~ Blufin::YmlSchemaValidator::REGEX_DECIMAL
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getBigDecimal(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.DECIMAL, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.DECIMAL, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_INT_TINY
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getByte(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.INT_TINY, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.INT_TINY, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_INT_SMALL
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getShort(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.INT_SMALL, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.INT_SMALL, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_INT_BIG
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getLong(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.INT_BIG, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.INT_BIG, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif Blufin::YmlSchemaValidator::INT_TYPES.include?(@type)
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getInt(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.INT, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.INT, #{table_camel_case_lower}.get#{field_camel_case}());" unless @is_child
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_TEXT
                        if column_data[Blufin::YmlSchemaValidator::ENCRYPTED].nil?
                            dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getString(\"#{column_name}\"));"
                            prepare_post << "        setParameter(#{idx_post}, statement, DataType.TEXT, #{table_camel_case_lower}.get#{field_camel_case}());"
                            prepare_put << "        setParameter(#{idx_put}, statement, DataType.TEXT, #{table_camel_case_lower}.get#{field_camel_case}());"
                        else
                            dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(Encryptor.decryptWithoutException(rs.getString(\"#{column_name}\")));"
                            prepare_post << "        setParameter(#{idx_post}, statement, DataType.TEXT, Encryptor.encryptWithoutException(#{table_camel_case_lower}.get#{field_camel_case}()));"
                            prepare_put << "        setParameter(#{idx_put}, statement, DataType.TEXT, Encryptor.encryptWithoutException(#{table_camel_case_lower}.get#{field_camel_case}()));"
                            import_statements << 'import org.blufin.core.security.Encryptor;'
                        end
                    elsif @type == Blufin::YmlSchemaValidator::TYPE_TEXT_LONG
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.TEXT_LONG, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.TEXT_LONG, #{table_camel_case_lower}.get#{field_camel_case}());"
                    elsif @type =~ Blufin::YmlSchemaValidator::REGEX_ENUM
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(#{table_camel_case}#{field_camel_case}.get(rs.getString(\"#{column_name}\")));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.ENUM, #{table_camel_case_lower}.get#{field_camel_case}().toString());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.ENUM, #{table_camel_case_lower}.get#{field_camel_case}().toString());"
                        import_statements << "import #{get_package(@site, schema, 'enums', Blufin::SiteServices::SDK)}.#{table_camel_case}#{field_camel_case};"
                    elsif @type =~ Blufin::YmlSchemaValidator::REGEX_ENUM_CUSTOM
                        enum_class_name = Blufin::YmlCommon::enum_name_extractor(@type)
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(#{enum_class_name}.valueOf(rs.getString(\"#{column_name}\")));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.ENUM_CUSTOM, #{table_camel_case_lower}.get#{field_camel_case}().toString());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.ENUM_CUSTOM, #{table_camel_case_lower}.get#{field_camel_case}().toString());"
                        import_statements << "import #{get_package(@site, schema, 'enums', Blufin::SiteServices::SDK)}.#{enum_class_name};"
                    elsif @type =~ Blufin::YmlSchemaValidator::REGEX_ENUM_SYSTEM
                        enum_class_name = Blufin::YmlCommon::enum_name_extractor(@type)
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(#{enum_class_name}.valueOf(rs.getString(\"#{column_name}\")));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.ENUM_SYSTEM, #{table_camel_case_lower}.get#{field_camel_case}().toString());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.ENUM_SYSTEM, #{table_camel_case_lower}.get#{field_camel_case}().toString());"
                        import_statements << "import #{Blufin::SiteServices::PACKAGE_SYSTEM_ENUMS}.#{enum_class_name};"
                    elsif @type =~ Blufin::YmlSchemaValidator::REGEX_VARCHAR
                        dto_method_body << "            #{table_camel_case_lower}.set#{field_camel_case}(rs.getString(\"#{column_name}\"));"
                        prepare_post << "        setParameter(#{idx_post}, statement, DataType.VARCHAR, #{table_camel_case_lower}.get#{field_camel_case}());"
                        prepare_put << "        setParameter(#{idx_put}, statement, DataType.VARCHAR, #{table_camel_case_lower}.get#{field_camel_case}());"
                    else
                        raise RuntimeError, "Unrecognized type in #{__FILE__}: #{@type}"
                    end

                end

                last_post_idx = 0
                last_put_idx  = 0

                # Sanity check (POST). Makes sure there are no gaps in the indexes -- just to make me feel better :)
                prepare_post.each do |post|
                    matches = post.match(/\([0-9]{1,3},/)
                    raise RuntimeError, 'Unable to extract index.' unless matches.length == 1
                    matched_idx = matches[0].gsub(/\(/, '').gsub(',', '')
                    raise RuntimeError, "\n#{schema}.#{table} POST index(es) not in sequence:\n#{prepare_post.to_yaml}" unless matched_idx.to_i == (last_post_idx + 1).to_i
                    last_post_idx += 1
                end

                # Sanity check (PUT). Same as above.
                prepare_put.each do |put|
                    matches = put.match(/\([0-9]{1,3},/)
                    raise RuntimeError, 'Unable to extract index.' unless matches.length == 1
                    matched_idx = matches[0].gsub(/\(/, '').gsub(',', '')
                    raise RuntimeError, "\n#{schema}.#{table} PUT Index(es) not in sequence:\n#{prepare_put.to_yaml}" unless matched_idx.to_i == (last_put_idx + 1).to_i
                    last_put_idx += 1
                end

                # Must add the "WHERE `id` = ?" parameter for PUTs.
                prepare_put << "        setParameter(#{idx_put + 1}, statement, DataType.INT, #{table_camel_case_lower}.getId());"

                parent_table = @schema_resources["#{schema}.#{table}"][:parent]
                parent_table = parent_table.nil? ? 'null' : '"' + parent_table + '"'

                # Add getDependents() stuff (if any).
                schema_fks   = @schema_fks["#{schema}.#{table}.#{Blufin::YmlSchemaValidator::ID}"]
                if schema_fks && schema_fks.any?
                    get_dependents << '        List<Triplet<AbstractDao, String, DataType>> dependents = new ArrayList<>();'
                    get_dependents << ''
                    schema_fks.each do |schema_fk|
                        fk_split = schema_fk.split('.')
                        fk_table = fk_split[1]
                        fk_field = fk_split[2].split(':')[0]
                        fk_type  = @schema_data[schema][fk_table][fk_field][Blufin::YmlSchemaValidator::CHILD_TYPE]
                        get_dependents << "        dependents.add(Triplet.of(#{Blufin::Strings::snake_case_to_camel_case(fk_table)}Dao.getInstance(), \"#{fk_field}\", #{fk_type.nil? ? 'null' : fk_type}));"
                    end
                    get_dependents << ''
                    get_dependents << '        return dependents;'
                else
                    get_dependents << '        return null;'
                end

                import_statements.sort!
                import_statements.uniq!

                field_names_post.map! { |n| "`#{n}`" }
                field_names_put.map! { |n| "`#{n}`" }

                contents = contents.gsub(PLACEHOLDER_SITE_NAME, @site_name.gsub('-', '.'))
                contents = contents.gsub(PLACEHOLDER_SITE_DOMAIN, @site_domain_gsub)
                contents = contents.gsub(PLACEHOLDER_SCHEMA, schema)
                contents = contents.gsub(PLACEHOLDER_OBJECT, table_camel_case)
                contents = contents.gsub(PLACEHOLDER_OBJECT_LOWER, table_camel_case_lower)
                contents = contents.gsub(PLACEHOLDER_TABLE, table)
                contents = contents.gsub(PLACEHOLDER_PARENT_TABLE, parent_table)
                contents = contents.gsub(PLACEHOLDER_IMPORT, import_statements.any? ? "\n#{import_statements.join("\n")}" : '')
                contents = contents.gsub(PLACEHOLDER_PREPARE_POST, (prepare_post + ["\n"]).join("\n"))
                contents = contents.gsub(PLACEHOLDER_PREPARE_PUT, (prepare_put + ["\n"]).join("\n"))
                contents = contents.gsub(PLACEHOLDER_GET_DEPENDENTS, (get_dependents).join("\n"))
                contents = contents.gsub(PLACEHOLDER_MAP_ONE_BODY, dto_method_body.join("\n"))
                contents = contents.gsub(PLACEHOLDER_POST_FIELDS, field_names_post.join(', ').to_s)
                contents = contents.gsub(PLACEHOLDER_POST_VALUES, ('?, ' * field_names_post.length)[0...-2])
                contents = contents.gsub(PLACEHOLDER_PUT_FIELDS, field_names_put.any? ? "#{field_names_put.join(' = ?, ')} = ?" : 'id = id')
                contents = contents.gsub(PLACEHOLDER_MAP_TWO_BODY, '        return null;') # TODO - FINISH THIS

                write_file_java("#{get_java_path(@site, schema, SERVICE, PACKAGE)}/#{table_camel_case}Dao.java", Blufin::YmlCommon::convert_string_to_line_array(contents), schema == Blufin::YmlSchemaValidator::MOCK)

            end

        end

    end

end