package org.simpleflatmapper.jdbc.spring;
import org.simpleflatmapper.jdbc.JdbcColumnKey;
import org.simpleflatmapper.map.MapperConfig;
import org.simpleflatmapper.map.property.FieldMapperColumnDefinition;
import org.simpleflatmapper.reflect.meta.ClassMeta;
import java.util.concurrent.atomic.AtomicReference;
public class DynamicPlaceHolderValueGetterSource<T> implements PlaceHolderValueGetterSource<T> {
private final AtomicReference<PlaceHolderValueGetterSource<T>> delegate;
private final ClassMeta<T> classMeta;
private final MapperConfig<JdbcColumnKey, FieldMapperColumnDefinition<JdbcColumnKey>> mapperConfig;
@SuppressWarnings("unchecked")
public DynamicPlaceHolderValueGetterSource(ClassMeta<T> classMeta, MapperConfig<JdbcColumnKey, FieldMapperColumnDefinition<JdbcColumnKey>> mapperConfig) {
this.classMeta = classMeta;
this.mapperConfig = mapperConfig;
this.delegate = new AtomicReference<PlaceHolderValueGetterSource<T>>(new ArrayPlaceHolderValueGetterSource<T>(new PlaceHolderValueGetter[0]));
}
@Override
public PlaceHolderValueGetter<T> getPlaceHolderValueGetter(String column) {
do {
PlaceHolderValueGetterSource<T> ssp = delegate.get();
PlaceHolderValueGetter<T> parameter = ssp.getPlaceHolderValueGetter(column);
if (parameter != null) {
return parameter;
} else {
PlaceHolderValueGetterSource<T> nssp = addColumn(ssp, column);
if (delegate.compareAndSet(ssp, nssp)) {
return nssp.getPlaceHolderValueGetter(column);
}
}
} while(true);
}
@Override
public Iterable<PlaceHolderValueGetter<T>> getParameters() {
return delegate.get().getParameters();
}
private PlaceHolderValueGetterSource<T> addColumn(PlaceHolderValueGetterSource<T> ssp, String column) {
SqlParameterSourceBuilder<T> builder = new SqlParameterSourceBuilder<T>(classMeta, mapperConfig);
for(PlaceHolderValueGetter<T> ph : ssp.getParameters()) {
builder.add(ph.getColumn());
}
builder.add(column);
return builder.buildSource();
}
}