private TableAlias getTableAlias(String aPath, boolean useOuterJoins, UserAlias aUserAlias, String[] fieldRef, Map pathClasses)
{
TableAlias curr, prev, indirect;
String attr, attrPath = null;
ObjectReferenceDescriptor ord;
CollectionDescriptor cod;
ClassDescriptor cld = null;
Object[] prevKeys = null;
Object[] keys = null;
ArrayList descriptors;
boolean outer = useOuterJoins;
int pathLength;
String pathAlias = aUserAlias == null ? null : aUserAlias.getAlias(aPath);
curr = getTableAliasForPath(aPath, pathAlias);
if (curr != null)
{
return curr;
}
descriptors = getRoot().cld.getAttributeDescriptorsForPath(aPath, pathClasses);
prev = getRoot();
if (descriptors == null || descriptors.size() == 0)
{
if (prev.hasJoins())
{
for (Iterator itr = prev.iterateJoins(); itr.hasNext();)
{
prev = ((Join) itr.next()).left;
descriptors = prev.cld.getAttributeDescriptorsForPath(aPath, pathClasses);
if (descriptors.size() > 0)
{
break;
}
}
}
}
pathLength = descriptors.size();
for (int i = 0; i < pathLength; i++)
{
if (!(descriptors.get(i) instanceof ObjectReferenceDescriptor))
{
// only use Collection- and ObjectReferenceDescriptor
continue;
}
ord = (ObjectReferenceDescriptor) descriptors.get(i);
attr = ord.getAttributeName();
if (attrPath == null)
{
attrPath = attr;
}
else
{
attrPath = attrPath + "." + attr;
}
// look for outer join hint
outer = outer || getQuery().isPathOuterJoin(attr);
// look for 1:n or m:n
if (ord instanceof CollectionDescriptor)
{
cod = (CollectionDescriptor) ord;
cld = getItemClassDescriptor(cod, attrPath, pathClasses);
if (!cod.isMtoNRelation())
{
prevKeys = prev.cld.getPkFields();
keys = cod.getForeignKeyFieldDescriptors(cld);
}
else
{
String mnAttrPath = attrPath + "*";
String mnUserAlias = (aUserAlias == null ? null : aUserAlias + "*");
indirect = getTableAliasForPath(mnAttrPath, mnUserAlias);
if (indirect == null)
{
indirect = createTableAlias(cod.getIndirectionTable(), mnAttrPath, mnUserAlias);
// we need two Joins for m:n
// 1.) prev class to indirectionTable
prevKeys = prev.cld.getPkFields();
keys = cod.getFksToThisClass();
addJoin(prev, prevKeys, indirect, keys, outer, attr + "*");
}
// 2.) indirectionTable to the current Class
prev = indirect;
prevKeys = cod.getFksToItemClass();
keys = cld.getPkFields();
}
}
else
{