TableMapping.java

/*
 * Copyright 2025 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package io.github.simplejdbcmapper.core;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import io.github.simplejdbcmapper.exception.MapperException;

/**
 * The database table mapping details on an object
 *
 * @author Antony Joseph
 */
class TableMapping {
	private String mappedObjClassName;

	private String tableName;

	private String schemaName;

	private String catalogName;

	private String idPropertyName;

	private boolean idAutoGenerated = false;

	private String versionPropertyName = null;

	private String createdOnPropertyName = null;

	private String createdByPropertyName = null;

	private String updatedOnPropertyName = null;

	private String updatedByPropertyName = null;

	private boolean autoAssignProperties = false;

	private List<PropertyMapping> propertyMappings;

	// key: column name, value: property mapping
	private Map<String, PropertyMapping> columnNameMap;

	// key: property name, value: property mapping
	private Map<String, PropertyMapping> propertyNameMap;

	public TableMapping(Class<?> mappedObjType, String tableName, String schemaName, String catalogName,
			IdPropertyInfo idPropertyInfo, List<PropertyMapping> propertyMappings) {
		Assert.notNull(mappedObjType, "mappedObjType must not be null");
		Assert.notNull(tableName, "tableName must not be null");
		Assert.notNull(idPropertyInfo, "idPropertyInfo must not be null");
		if (ObjectUtils.isEmpty(propertyMappings)) {
			throw new IllegalArgumentException("propertyMappings cannot be null or empty");
		}
		this.mappedObjClassName = mappedObjType.getName();
		this.tableName = tableName;
		this.schemaName = StringUtils.hasText(schemaName) ? schemaName : null;
		this.catalogName = StringUtils.hasText(catalogName) ? catalogName : null;
		this.idPropertyName = idPropertyInfo.getPropertyName();
		this.idAutoGenerated = idPropertyInfo.isIdAutoGenerated();
		this.propertyMappings = propertyMappings;
		columnNameMap = new HashMap<>();
		propertyNameMap = new HashMap<>();
		for (PropertyMapping propMapping : propertyMappings) {
			if (propMapping.isVersionAnnotation()) {
				versionPropertyName = propMapping.getPropertyName();
				autoAssignProperties = true;
			}
			if (propMapping.isCreatedOnAnnotation()) {
				createdOnPropertyName = propMapping.getPropertyName();
				autoAssignProperties = true;
			}
			if (propMapping.isCreatedByAnnotation()) {
				createdByPropertyName = propMapping.getPropertyName();
				autoAssignProperties = true;
			}
			if (propMapping.isUpdatedOnAnnotation()) {
				updatedOnPropertyName = propMapping.getPropertyName();
				autoAssignProperties = true;
			}
			if (propMapping.isUpdatedByAnnotation()) {
				updatedByPropertyName = propMapping.getPropertyName();
				autoAssignProperties = true;
			}
			columnNameMap.put(propMapping.getColumnName(), propMapping);
			propertyNameMap.put(propMapping.getPropertyName(), propMapping);
		}
	}

	public String getMappedObjClassName() {
		return mappedObjClassName;
	}

	public String getTableName() {
		return tableName;
	}

	public String getCatalogName() {
		return catalogName;
	}

	public String getSchemaName() {
		return schemaName;
	}

	public String getIdPropertyName() {
		return getIdPropertyMapping().getPropertyName();
	}

	public int getIdColumnSqlType() {
		return getIdPropertyMapping().getColumnSqlType();
	}

	public String getIdColumnName() {
		return getIdPropertyMapping().getColumnName();
	}

	public boolean isIdAutoGenerated() {
		return idAutoGenerated;
	}

	public PropertyMapping getIdPropertyMapping() {
		PropertyMapping propMapping = propertyNameMap.get(idPropertyName);
		if (propMapping != null) {
			return propMapping;
		} else {
			throw new MapperException("For @Id property " + idPropertyName
					+ " could not find corresponding column in database table " + tableName);
		}
	}

	public List<PropertyMapping> getPropertyMappings() {
		return propertyMappings;
	}

	public PropertyMapping getPropertyMappingByColumnName(String columnName) {
		return columnNameMap.get(columnName);
	}

	public PropertyMapping getPropertyMappingByPropertyName(String propertyName) {
		return propertyNameMap.get(propertyName);
	}

	public String fullyQualifiedTableName() {
		String prefix = "";
		if (StringUtils.hasText(catalogName)) {
			prefix = prefix + catalogName + ".";
		}
		if (StringUtils.hasText(schemaName)) {
			prefix = prefix + schemaName + ".";
		}
		return prefix + tableName;
	}

	public PropertyMapping getVersionPropertyMapping() {
		return versionPropertyName != null ? propertyNameMap.get(versionPropertyName) : null;
	}

	public PropertyMapping getCreatedOnPropertyMapping() {
		return createdOnPropertyName != null ? propertyNameMap.get(createdOnPropertyName) : null;
	}

	public PropertyMapping getCreatedByPropertyMapping() {
		return createdByPropertyName != null ? propertyNameMap.get(createdByPropertyName) : null;
	}

	public PropertyMapping getUpdatedOnPropertyMapping() {
		return updatedOnPropertyName != null ? propertyNameMap.get(updatedOnPropertyName) : null;
	}

	public PropertyMapping getUpdatedByPropertyMapping() {
		return updatedByPropertyName != null ? propertyNameMap.get(updatedByPropertyName) : null;
	}

	public boolean hasAutoAssignProperties() {
		return autoAssignProperties;
	}
}