alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (TableMetaDataContext.java)

This example Spring Framework source code file (TableMetaDataContext.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

arraylist, arraylist, hashmap, invaliddataaccessapiusageexception, list, list, map, object, sql, string, string, stringbuilder, tableparametermetadata, tableparametermetadata, unable, util

The Spring Framework TableMetaDataContext.java source code

/*
 * Copyright 2002-2007 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
 *
 *      http://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 org.springframework.jdbc.core.metadata;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.core.SqlTypeValue;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;

/**
 * Class to manage context metadata used for the configuration
 * and execution of operations on a database table.
 *
 * @author Thomas Risberg
 * @since 2.5
 */
public class TableMetaDataContext {

	/** Logger available to subclasses */
	protected final Log logger = LogFactory.getLog(getClass());

	/** name of procedure to call **/
	private String tableName;

	/** name of catalog for call **/
	private String catalogName;

	/** name of schema for call **/
	private String schemaName;

	/** List of columns objects to be used in this context */
	private List<String> tableColumns = new ArrayList();

	/** should we access insert parameter meta data info or not */
	private boolean accessTableParameterMetaData = true;

	/** the provider of call meta data */
	private TableMetaDataProvider metaDataProvider;

	/** are we using generated key columns */
	private boolean generatedKeyColumnsUsed = false;


	/**
	 * Set the name of the table for this context.
	 */
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	/**
	 * Get the name of the table for this context.
	 */
	public String getTableName() {
		return this.tableName;
	}

	/**
	 * Set the name of the catalog for this context.
	 */
	public void setCatalogName(String catalogName) {
		this.catalogName = catalogName;
	}

	/**
	 * Get the name of the catalog for this context.
	 */
	public String getCatalogName() {
		return this.catalogName;
	}

	/**
	 * Set the name of the schema for this context.
	 */
	public void setSchemaName(String schemaName) {
		this.schemaName = schemaName;
	}

	/**
	 * Get the name of the schema for this context.
	 */
	public String getSchemaName() {
		return this.schemaName;
	}

	/**
	 * Specify whether we should access table column meta data.
	 */
	public void setAccessTableParameterMetaData(boolean accessTableParameterMetaData) {
		this.accessTableParameterMetaData = accessTableParameterMetaData;
	}

	/**
	 * Are we accessing table meta data?
	 */
	public boolean isAccessTableParameterMetaData() {
		return this.accessTableParameterMetaData;
	}


	/**
	 * Get a List of the table column names.
	 */
	public List<String> getTableColumns() {
		return this.tableColumns;
	}

	/**
	 * Does this database support the JDBC 3.0 feature of retreiving generated keys
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
	 */
	public boolean isGetGeneratedKeysSupported() {
		return this.metaDataProvider.isGetGeneratedKeysSupported();
	}

	/**
	 * Does this database support simple query to retrieve generated keys
	 * when the JDBC 3.0 feature is not supported
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
	 */
	public boolean isGetGeneratedKeysSimulated() {
		return this.metaDataProvider.isGetGeneratedKeysSimulated();
	}

	/**
	 * Does this database support simple query to retrieve generated keys
	 * when the JDBC 3.0 feature is not supported
	 * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
	 */
	public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) {
		return this.metaDataProvider.getSimpleQueryForGetGeneratedKey(tableName, keyColumnName);
	}

	/**
	 * Is a column name String array for retreiving generated keys supported
	 * {@link java.sql.Connection#createStruct(String, Object[])}?
	 */
	public boolean isGeneratedKeysColumnNameArraySupported() {
		return this.metaDataProvider.isGeneratedKeysColumnNameArraySupported();
	}


	/**
	 * Process the current meta data with the provided configuration options
	 * @param dataSource the DataSource being used
	 * @param declaredColumns any coluns that are declared
	 * @param generatedKeyNames name of generated keys
	 */
	public void processMetaData(DataSource dataSource, List<String> declaredColumns, String[] generatedKeyNames) {
		this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
		this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames);
	}

	/**
	 * Compare columns created from metadata with declared columns and return a reconciled list.
	 * @param declaredColumns declared column names
	 * @param generatedKeyNames names of generated key columns
	 */
	private List<String> reconcileColumnsToUse(List declaredColumns, String[] generatedKeyNames) {
		if (generatedKeyNames.length > 0) {
			generatedKeyColumnsUsed = true;
		}
		if (declaredColumns.size() > 0) {
			return new ArrayList<String>(declaredColumns);
		}
		Set keys = new HashSet(generatedKeyNames.length);
		for (String key : generatedKeyNames) {
			keys.add(key.toUpperCase());
		}
		List<String> columns = new ArrayList();
		for (TableParameterMetaData meta : metaDataProvider.getTableParameterMetaData()) {
			if (!keys.contains(meta.getParameterName().toUpperCase())) {
				columns.add(meta.getParameterName());
			}
		}
		return columns;
	}

	/**
	 * Match the provided column names and values with the list of columns used.
	 * @param parameterSource the parameter names and values
	 */
	public List<Object> matchInParameterValuesWithInsertColumns(SqlParameterSource parameterSource) {
		List<Object> values = new ArrayList();
		// for parameter source lookups we need to provide caseinsensitive lookup support since the
		// database metadata is not necessarily providing case sensitive column names
		Map caseInsensitiveParameterNames =
				SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource);
		for (String column : tableColumns) {
			if (parameterSource.hasValue(column)) {
				values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, column));
			}
			else {
				String lowerCaseName = column.toLowerCase();
				if (parameterSource.hasValue(lowerCaseName)) {
					values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, lowerCaseName));
				}
				else {
					String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(column);
					if (parameterSource.hasValue(propertyName)) {
						values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, propertyName));
					}
					else {
						if (caseInsensitiveParameterNames.containsKey(lowerCaseName)) {
							values.add(
									SqlParameterSourceUtils.getTypedValue(parameterSource,
											(String) caseInsensitiveParameterNames.get(lowerCaseName)));
						}
						else {
							values.add(null);
						}
					}
				}
			}
		}
		return values;
	}

	/**
	 * Match the provided column names and values with the list of columns used.
	 * @param inParameters the parameter names and values
	 */
	public List<Object> matchInParameterValuesWithInsertColumns(Map inParameters) {
		List<Object> values = new ArrayList();
		Map<String, Object> source = new HashMap();
		for (String key : inParameters.keySet()) {
			source.put(key.toLowerCase(), inParameters.get(key));
		}
		for (String column : tableColumns) {
			values.add(source.get(column.toLowerCase()));
		}
		return values;
	}


	/**
	 * Build the insert string based on configuration and metadata information
	 * @return the insert string to be used
	 */
	public String createInsertString(String[] generatedKeyNames) {
		HashSet<String> keys = new HashSet(generatedKeyNames.length);
		for (String key : generatedKeyNames) {
			keys.add(key.toUpperCase());
		}
		StringBuilder insertStatement = new StringBuilder();
		insertStatement.append("INSERT INTO ");
		if (this.getSchemaName() != null) {
			insertStatement.append(this.getSchemaName());
			insertStatement.append(".");
		}
		insertStatement.append(this.getTableName());
		insertStatement.append(" (");
		int columnCount = 0;
		for (String columnName : this.getTableColumns()) {
			if (!keys.contains(columnName.toUpperCase())) {
				columnCount++;
				if (columnCount > 1) {
					insertStatement.append(", ");
				}
				insertStatement.append(columnName);
			}
		}
		insertStatement.append(") VALUES(");
		if (columnCount < 1) {
			if (generatedKeyColumnsUsed) {
				logger.info("Unable to locate non-key columns for table '" +
						this.getTableName() + "' so an empty insert statement is generated");
			}
			else {
				throw new InvalidDataAccessApiUsageException("Unable to locate columns for table '" +
						this.getTableName() + "' so an insert statement can't be generated");
			}
		}
		for (int i = 0; i < columnCount; i++) {
			if (i > 0) {
				insertStatement.append(", ");
			}
			insertStatement.append("?");
		}
		insertStatement.append(")");
		return insertStatement.toString();
	}

	/**
	 * Build the array of {@link java.sql.Types} based on configuration and metadata information
	 * @return the array of types to be used
	 */
	public int[] createInsertTypes() {

		int[] types = new int[this.getTableColumns().size()];

		List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData();
		Map<String, TableParameterMetaData> parameterMap = new HashMap(parameters.size());
		for (TableParameterMetaData tpmd : parameters) {
			parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd);
		}

		int typeIndx = 0;
		for (String column : this.getTableColumns()) {
			if (column == null) {
				types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN;
			}
			else {
				TableParameterMetaData tpmd = parameterMap.get(column.toUpperCase());
				if (tpmd != null) {
					types[typeIndx] = tpmd.getSqlType();
				}
				else {
					types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN;
				}
			}
			typeIndx++;
		}

		return types;
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework TableMetaDataContext.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.