/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.ogm.util.configurationreader.impl;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.ogm.util.configurationreader.spi.ClassPropertyReaderContext;
import org.hibernate.ogm.util.configurationreader.spi.PropertyReaderContext;
import org.hibernate.ogm.util.configurationreader.spi.PropertyValidator;
import org.hibernate.ogm.util.impl.Contracts;
import org.hibernate.ogm.util.impl.Log;
import org.hibernate.ogm.util.impl.LoggerFactory;
import org.hibernate.ogm.util.impl.StringHelper;
/**
* A context for retrieving the value of a given property.
*
* @author Gunnar Morling
* @param <T> the expected type of the property
*/
abstract class PropertyReaderContextBase<T> implements PropertyReaderContext<T> {
private static final Log log = LoggerFactory.make();
private final Object configuredValue;
private final String propertyName;
private final Class<T> targetType;
private final ClassLoaderService classLoaderService;
private T defaultValue;
private boolean isRequired;
private final List<PropertyValidator<T>> validators;
PropertyReaderContextBase(ClassLoaderService classLoaderService, Object configuredValue, String propertyName, Class<T> targetType) {
this.classLoaderService = classLoaderService;
this.configuredValue = configuredValue;
this.propertyName = propertyName;
this.targetType = targetType;
this.validators = new ArrayList<PropertyValidator<T>>();
}
PropertyReaderContextBase(ClassLoaderService classLoaderService, Object configuredValue, String propertyName, Class<T> targetType, T defaultValue, boolean isRequired,
List<PropertyValidator<T>> validators) {
this.classLoaderService = classLoaderService;
this.configuredValue = configuredValue;
this.propertyName = propertyName;
this.targetType = targetType;
this.defaultValue = defaultValue;
this.isRequired = isRequired;
this.validators = validators;
}
@Override
public PropertyReaderContext<T> withDefault(T defaultValue) {
this.defaultValue = defaultValue;
return this;
}
@Override
public PropertyReaderContext<T> required() {
this.isRequired = true;
return this;
}
@Override
public PropertyReaderContext<T> withValidator(PropertyValidator<T> validator) {
validators.add( validator );
return this;
}
@Override
public ClassPropertyReaderContext<T> instantiate() {
Contracts.assertNotNull( classLoaderService, "classLoaderService" );
return new DefaultClassPropertyReaderContext<T>( classLoaderService, configuredValue, propertyName, targetType, defaultValue, isRequired, validators );
}
@Override
public T getValue() {
if ( isRequired && StringHelper.isNullOrEmptyString( configuredValue ) ) {
throw log.missingConfigurationProperty( propertyName );
}
T typedValue = getTypedValue();
for ( PropertyValidator<T> validator : validators ) {
validator.validate( typedValue );
}
return typedValue;
}
/**
* To be implemented in sub-classes to convert the configured value into an object of the property target type.
*
* @return the configured property as instance of the given target type; May be {@code null}
*/
protected abstract T getTypedValue();
protected Object getConfiguredValue() {
return configuredValue;
}
protected String getPropertyName() {
return propertyName;
}
protected Class<T> getTargetType() {
return targetType;
}
protected T getDefaultValue() {
return defaultValue;
}
}