package com.breeze.hib;
import java.util.HashMap;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import com.breeze.metadata.IEntityType;
import com.breeze.metadata.INavigationProperty;
import com.breeze.metadata.IProperty;
import com.breeze.metadata.MetadataHelper;
class CriteriaAliasBuilder {
private HashMap<String, String> _cache = new HashMap<String, String>();
private int _offset = 0;
private boolean _containsNavPropertyProxy = false;
public CriteriaAliasBuilder() {
}
public String getPropertyName(CriteriaWrapper crit, String propertyPath) {
IProperty property = MetadataHelper.getPropertyFromPath(propertyPath, crit.entityType);
if (property == null) {
throw new RuntimeException("Unable to locate property: " + propertyPath + " on entityType: " + crit.entityType.getName());
}
String[] propNames = propertyPath.split("\\.");
boolean isNavPath = property instanceof INavigationProperty;
if (propNames.length == 1 && !isNavPath) {
return propNames[0];
} else {
String nextPropName = propNames[0];
String nextAlias = "";
for (int i = 0; i < propNames.length - 1; i = i + 1) {
nextPropName = nextAlias == "" ? propNames[i] : nextAlias + "." + propNames[i];
nextAlias = newAlias(crit, nextPropName, propNames[i]);
}
String lastPropName = propNames[propNames.length - 1];
if (isNavPath) {
INavigationProperty navProp = (INavigationProperty) property;
if (navProp.isScalar()) {
// do not assign to nextAlias;
String alias = newAlias(crit, nextPropName, lastPropName);
// HACK - because we can't get NavProperties to Eagerly load
// when they are the 'projected' item.
_containsNavPropertyProxy = true;
// TODO: AARGH.... doesn't seem to do anything...
((Criteria) crit.criteria).setFetchMode(alias, FetchMode.JOIN);
((Criteria) crit.criteria).setFetchMode(lastPropName, FetchMode.JOIN);
} else {
// String alias = getAlias(crit, nextPropName, lastPropName);
// HACK - because we can't get NavProperties to Eagerly load
// when they are the 'projected' item.
// _containsNavPropertyProxy = true;
// TODO: AARGH.... doesn't seem to do anything...
// crit.setFetchMode(alias, FetchMode.JOIN);
// crit.setFetchMode(lastPropName, FetchMode.JOIN);
throw new RuntimeException("Hibernate does not provide a mechanism to project entity collections");
}
}
nextPropName = nextAlias == "" ? lastPropName : nextAlias + "." + lastPropName;
return nextPropName;
}
}
private String newAlias(CriteriaWrapper crit, String nextPropName, String aliasRoot) {
String nextAlias;
String key = buildCacheKey(crit.entityType, nextPropName);
nextAlias = _cache.get(key);
if (nextAlias == null) {
nextAlias = aliasRoot + "_" + _offset++;
crit.createAlias(nextPropName, nextAlias); // , JoinType.LEFT_OUTER_JOIN);
_cache.put(key, nextAlias);
}
return nextAlias;
}
// Used by any/all to get initial expression alias
public String getSimpleAlias(CriteriaWrapper crit, String propName) {
String key = buildCacheKey(crit.entityType, propName);
String alias = _cache.get(key);
if (alias == null) {
alias = propName + "_" + _offset++;
crit.createAlias(propName, alias);
}
return alias;
}
public boolean containsNavPropertyProxy() {
return _containsNavPropertyProxy;
}
private String buildCacheKey(IEntityType entityType, String propName) {
return propName + "::" + entityType.getName();
}
}