package pl.net.bluesoft.rnd.processtool.hibernate.transform;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.Setter;
import org.hibernate.transform.ResultTransformer;
import pl.net.bluesoft.util.lang.Lang;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
/**
* @author: amichalak@bluesoft.net.pl
*/
public class NestedAliasToBeanResultTransformer implements ResultTransformer, Serializable {
private final Class resultClass;
private boolean isInitialized;
private String[] aliases;
private Setter[] setters;
private PropertyInstantiationPolicy instantiationPolicy;
public NestedAliasToBeanResultTransformer(Class resultClass) {
if (resultClass == null) {
throw new IllegalArgumentException("resultClass cannot be null");
}
isInitialized = false;
this.resultClass = resultClass;
}
public NestedAliasToBeanResultTransformer setInstantiationPolicy(PropertyInstantiationPolicy instantiationPolicy) {
if (isInitialized) {
throw new IllegalStateException("Cannot set instantiation policy after initialization");
}
this.instantiationPolicy = instantiationPolicy;
return this;
}
public Object transformTuple(Object[] tuple, String[] aliases) {
if (!isInitialized) {
initialize(aliases);
}
else {
check(aliases);
}
Object result = instantiationPolicy.instantiate(null, null, resultClass);
for (int i = 0; i < aliases.length; ++i) {
if (setters[i] != null) {
setters[i].set(result, tuple[i], null);
}
}
return result;
}
private void initialize(String[] aliases) {
if (instantiationPolicy == null) {
instantiationPolicy = new DefaultPropertyInstantiationPolicy();
}
PropertyAccessor propertyAccessor = new NestedPropertyAccessor(resultClass, instantiationPolicy);
this.aliases = new String[aliases.length];
setters = new Setter[aliases.length];
for (int i = 0; i < aliases.length; ++i) {
String alias = aliases[i];
if (alias != null) {
this.aliases[i] = alias;
setters[i] = propertyAccessor.getSetter(resultClass, alias);
}
}
isInitialized = true;
}
private void check(String[] aliases) {
if (!Arrays.equals(aliases, this.aliases)) {
throw new IllegalStateException("aliases are different from what is cached; aliases=" + Arrays.asList(aliases)
+ " cached=" + Arrays.asList(this.aliases));
}
}
public List transformList(List collection) {
return collection;
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
NestedAliasToBeanResultTransformer that = (NestedAliasToBeanResultTransformer) o;
if (!resultClass.equals(that.resultClass)) {
return false;
}
if (!Arrays.equals(aliases, that.aliases)) {
return false;
}
if (!Lang.equals(instantiationPolicy, that.instantiationPolicy)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = resultClass != null ? resultClass.hashCode() : 0;
result = 31 * result + (aliases != null ? Arrays.hashCode(aliases) : 0);
result = 31 * result + (instantiationPolicy != null ? instantiationPolicy.hashCode() : 0);
return result;
}
}