/*
* Copyright 2004-2005 Revolution Systems Inc.
*
* 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 com.revolsys.ui.web.config;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.PreDestroy;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.util.ObjectUtils;
import com.revolsys.jdbc.JdbcUtils;
public abstract class DatabaseConfigurer implements BeanFactoryPostProcessor, Ordered {
/** The LOG for the instance. */
private static final Logger LOG = Logger.getLogger(DatabaseConfigurer.class);
/** The data source used to load properties from. */
private DataSource dataSource;
/** The name of the column containing property keys. */
private String keyColumnName = "key";
/**
* The order value of this object, higher value meaning greater in terms of
* sorting.
*/
private int order = Integer.MAX_VALUE;
/** The name of the table containing configuration properties. */
private String tableName;
/** The name of the column containing property values. */
private String valueColumnName = "value";
/**
* <p>
* Convert the given merged properties, converting property values if
* necessary. The result will then be processed.
* </p>
* <p>
* Default implementation will invoke <code>convertPropertyValue</code> for
* each property value, replacing the original with the converted value.
* </p>
*
* @param properties The properties to convert.
* @see #convertPropertyValue
* @see #processProperties
*/
protected void convertProperties(final Map properties) {
final Iterator propertyNames = properties.keySet().iterator();
while (propertyNames.hasNext()) {
final String propertyName = (String)propertyNames.next();
final String propertyValue = (String)properties.get(propertyName);
final String convertedValue = convertPropertyValue(propertyValue);
if (!ObjectUtils.nullSafeEquals(propertyValue, convertedValue)) {
properties.put(propertyName, convertedValue);
}
}
}
/**
* <p>
* Convert the given property value from the properties source to the value
* that should be applied.
* </p>
* <p>
* Default implementation simply returns the original value. Can be overridden
* in subclasses, for example to detect encrypted values and decrypt them
* accordingly.
* </p>
*
* @param originalValue the original value from the properties source
* (properties file or local "properties")
* @return the converted value, to be used for processing
*/
protected String convertPropertyValue(final String originalValue) {
return originalValue;
}
@PreDestroy
public void destroy() {
this.dataSource = null;
this.keyColumnName = null;
this.tableName = null;
this.valueColumnName = null;
}
/**
* Get the name of the column containing property keys.
*
* @return The name of the column containing property keys.
*/
public final String getKeyColumnName() {
return this.keyColumnName;
}
/**
* Get the LOG.
*
* @return The LOG.
*/
protected Logger getLog() {
return LOG;
}
/**
* Get the order value of this object, higher value meaning greater in terms
* of sorting.
*
* @return The order value of this object, higher value meaning greater in
* terms of sorting.
*/
@Override
public int getOrder() {
return this.order;
}
/**
* Get the name of the table containing configuration properties.
*
* @return The name of the table containing configuration properties.
*/
public final String getTableName() {
return this.tableName;
}
/**
* Get The name of the column containing property values.
*
* @return The name of the column containing property values.
*/
public final String getValueColumnName() {
return this.valueColumnName;
}
/**
* @param beanFactory The bean factory the bean is loaded from.
*/
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) {
final Map<String, String> properties = new HashMap<>();
Connection connection = null;
try {
connection = JdbcUtils.getConnection(this.dataSource);
final String sql = "SELECT " + this.keyColumnName + ", " + this.valueColumnName + " FROM "
+ this.tableName;
final Statement statement = connection.createStatement();
final ResultSet results = statement.executeQuery(sql);
while (results.next()) {
final String key = results.getString(1);
final String value = results.getString(2);
properties.put(key, value);
}
} catch (final SQLException e) {
throw new BeanInitializationException(e.getMessage(), e);
} finally {
JdbcUtils.release(connection, this.dataSource);
}
processProperties(beanFactory, properties);
}
/**
* Apply the given Properties to the bean factory.
*
* @param beanFactory the bean factory used by the application context
* @param properties the Properties to apply
*/
protected abstract void processProperties(ConfigurableListableBeanFactory beanFactory,
Map properties);
/**
* Set the data source used to load properties from.
*
* @param dataSource The data source used to load properties from.
*/
public final void setDataSource(final DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Set the name of the column containing property keys.
*
* @param keyColumnName The name of the column containing property keys.
*/
public final void setKeyColumnName(final String keyColumnName) {
this.keyColumnName = keyColumnName;
}
/**
* Set the order value of this object, higher value meaning greater in terms
* of sorting.
*
* @param order The order value of this object, higher value meaning greater
* in terms of sorting.
*/
public void setOrder(final int order) {
this.order = order;
}
/**
* Set the name of the table containing configuration properties.
*
* @param tableName The name of the table containing configuration properties.
*/
public final void setTableName(final String tableName) {
this.tableName = tableName;
}
/**
* Set the name of the column containing property values.
*
* @param valueColumnName The name of the column containing property values.
*/
public final void setValueColumnName(final String valueColumnName) {
this.valueColumnName = valueColumnName;
}
}