org.killbill.billing.util.validation.ValidationManager Maven / Gradle / Ivy
/*
* Copyright 2010-2011 Ning, Inc.
*
* Ning licenses this file to you 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.killbill.billing.util.validation;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Types;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.killbill.billing.util.validation.dao.DatabaseSchemaDao;
import com.google.inject.Inject;
public class ValidationManager {
private final DatabaseSchemaDao dao;
// table name, string name, column info
private final Map> columnInfoMap = new HashMap>();
private final Map configurations = new HashMap();
@Inject
public ValidationManager(final DatabaseSchemaDao dao) {
this.dao = dao;
}
// replaces existing schema information with the information for the specified schema
public void loadSchemaInformation(final String schemaName) {
columnInfoMap.clear();
// get schema information and map it to columnInfo
final List columnInfoList = dao.getColumnInfoList(schemaName);
for (final DefaultColumnInfo columnInfo : columnInfoList) {
final String tableName = columnInfo.getTableName();
if (!columnInfoMap.containsKey(tableName)) {
columnInfoMap.put(tableName, new HashMap());
}
columnInfoMap.get(tableName).put(columnInfo.getColumnName(), columnInfo);
}
}
public Collection getTableInfo(final String tableName) {
return columnInfoMap.get(tableName).values();
}
public DefaultColumnInfo getColumnInfo(final String tableName, final String columnName) {
return (columnInfoMap.get(tableName) == null) ? null : columnInfoMap.get(tableName).get(columnName);
}
public boolean validate(final Object o) {
final ValidationConfiguration configuration = getConfiguration(o.getClass());
// if no configuration exists for this class, the object is valid
if (configuration == null) {
return true;
}
final Class clazz = o.getClass();
for (final String propertyName : configuration.keySet()) {
try {
final Field field = clazz.getDeclaredField(propertyName);
if (!field.isAccessible()) {
field.setAccessible(true);
}
final Object value = field.get(o);
final DefaultColumnInfo columnInfo = configuration.get(propertyName);
if (columnInfo == null) {
// no column info means the property hasn't been properly mapped; suppress validation
return true;
}
if (!hasValidNullability(columnInfo, value)) {
return false;
}
if (!isValidLengthString(columnInfo, value)) {
return false;
}
if (!isValidLengthChar(columnInfo, value)) {
return false;
}
if (!hasValidPrecision(columnInfo, value)) {
return false;
}
if (!hasValidScale(columnInfo, value)) {
return false;
}
} catch (NoSuchFieldException e) {
// if the field doesn't exist, assume the configuration is faulty and skip this property
} catch (IllegalAccessException e) {
// TODO: something? deliberate no op?
}
}
return true;
}
private boolean hasValidNullability(final DefaultColumnInfo columnInfo, final Object value) {
if (!columnInfo.getIsNullable()) {
if (value == null) {
return false;
}
}
return true;
}
private boolean isValidLengthString(final DefaultColumnInfo columnInfo, final Object value) {
if (columnInfo.getMaximumLength() != 0) {
// H2 will report a character_maximum_length for decimal
if (value != null && value instanceof String) {
if (value.toString().length() > columnInfo.getMaximumLength()) {
return false;
}
}
}
return true;
}
private boolean isValidLengthChar(final DefaultColumnInfo columnInfo, final Object value) {
// MySQL and PostgreSQL report data_type as Strings, H2 as SQLTypes
if ("char".equals(columnInfo.getDataType()) || "character".equals(columnInfo.getDataType()) || String.valueOf(Types.CHAR).equals(columnInfo.getDataType())) {
if (value == null) {
return false;
} else {
if (value.toString().length() != columnInfo.getMaximumLength()) {
return false;
}
}
}
return true;
}
private boolean hasValidPrecision(final DefaultColumnInfo columnInfo, final Object value) {
if (columnInfo.getPrecision() != 0) {
// H2 will report a numeric precision for varchar columns
if (value != null && !(value instanceof String)) {
final BigDecimal bigDecimalValue = new BigDecimal(value.toString());
if (bigDecimalValue.precision() > columnInfo.getPrecision()) {
return false;
}
}
}
return true;
}
private boolean hasValidScale(final DefaultColumnInfo columnInfo, final Object value) {
if (columnInfo.getScale() != 0) {
if (value != null) {
final BigDecimal bigDecimalValue = new BigDecimal(value.toString());
if (bigDecimalValue.scale() > columnInfo.getScale()) {
return false;
}
}
}
return true;
}
public boolean hasConfiguration(final Class clazz) {
return configurations.containsKey(clazz);
}
public ValidationConfiguration getConfiguration(final Class clazz) {
return configurations.get(clazz);
}
public void setConfiguration(final Class clazz, final String propertyName, final DefaultColumnInfo columnInfo) {
if (!configurations.containsKey(clazz)) {
configurations.put(clazz, new ValidationConfiguration());
}
configurations.get(clazz).addMapping(propertyName, columnInfo);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy