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;
        Object[] prevKeys;
        Object[] keys;
        ArrayList descriptors;
        boolean outer = useOuterJoins;
        int pathLength;
        List hintClasses = null;       
        String pathAlias = aUserAlias == null ? null : aUserAlias.getAlias(aPath);
        
        if (pathClasses != null)
        {
            hintClasses = (List) pathClasses.get(aPath);
        }    
        
        curr = getTableAliasForPath(aPath, pathAlias, hintClasses);
        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;
			}

            // use clas hints for path
            if (pathClasses != null)
            {
                hintClasses = (List) pathClasses.get(attrPath);     
            }    

			// look for outer join hint
			outer = outer || getQuery().isPathOuterJoin(attrPath);

			// look for 1:n or m:n
			if (ord instanceof CollectionDescriptor)
			{
				cod = (CollectionDescriptor) ord;
				cld = getItemClassDescriptor(cod, hintClasses);

				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, null);
					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
			{
				// must be n:1 or 1:1
				cld = getItemClassDescriptor(ord, hintClasses);

			    // BRJ : if ord is taken from 'super' we have to change prev accordingly
				if (!prev.cld.equals(ord.getClassDescriptor()))
				{
					TableAlias ordAlias = getTableAliasForClassDescriptor(ord.getClassDescriptor());
					Join join = prev.getJoin(ordAlias);
                    if (join != null)
                    {
                        join.isOuter = join.isOuter || outer;
                    }    
				    prev = ordAlias;
				}	

				prevKeys = ord.getForeignKeyFieldDescriptors(prev.cld);
				keys = cld.getPkFields();

				// [olegnitz]
				// a special case: the last element of the path is
				// reference and the field is one of PK fields =>
				// use the correspondent foreign key field, don't add the join
				if ((fieldRef != null) && (i == (pathLength - 1)))
				{
					FieldDescriptor[] pk = cld.getPkFields();

					for (int j = 0; j < pk.length; j++)
					{
						if (pk[j].getAttributeName().equals(fieldRef[0]))
						{
							fieldRef[0] = ((FieldDescriptor) prevKeys[j]).getAttributeName();
							return prev;
						}
					}
				}
			}

			pathAlias = aUserAlias == null ? null : aUserAlias.getAlias(attrPath);
			curr = getTableAliasForPath(attrPath, pathAlias, hintClasses);

			if (curr == null)
			{
				curr = createTableAlias(cld, attrPath, pathAlias, hintClasses);

				outer = outer || (curr.cld == prev.cld) || curr.hasExtents() || useOuterJoins;
				addJoin(prev, prevKeys, curr, keys, outer, attr);

				buildSuperJoinTree(curr, cld, aPath, outer);
			}

			prev = curr;
		}

		m_logger.debug("Result of getTableAlias(): " + curr);
		return curr;
	}
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 ; Object [ ] prevKeys ; Object [ ] keys ; ArrayList descriptors ; boolean outer = useOuterJoins ; int pathLength ; List hintClasses = null ; String pathAlias = aUserAlias == null ? null : aUserAlias . getAlias ( aPath ) ; if ( pathClasses != null ) { hintClasses = ( List ) pathClasses . get ( aPath ) ; } curr = getTableAliasForPath ( aPath , pathAlias , hintClasses ) ; 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 ) ) { continue ; } ord = ( ObjectReferenceDescriptor ) descriptors . get ( i ) ; attr = ord . getAttributeName ( ) ; if ( attrPath == null ) { attrPath = attr ; } else { attrPath = attrPath + "." + attr ; } if ( pathClasses != null ) { hintClasses = ( List ) pathClasses . get ( attrPath ) ; } outer = outer || getQuery ( ) . isPathOuterJoin ( attrPath ) ; if ( ord instanceof CollectionDescriptor ) { cod = ( CollectionDescriptor ) ord ; cld = getItemClassDescriptor ( cod , hintClasses ) ; 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 , null ) ; if ( indirect == null ) { indirect = createTableAlias ( cod . getIndirectionTable ( ) , mnAttrPath , mnUserAlias ) ; prevKeys = prev . cld . getPkFields ( ) ; keys = cod . getFksToThisClass ( ) ; addJoin ( prev , prevKeys , indirect , keys , outer , attr + "*" ) ; } prev = indirect ; prevKeys = cod . getFksToItemClass ( ) ; keys = cld . getPkFields ( ) ; } } else { cld = getItemClassDescriptor ( ord , hintClasses ) ; if ( ! prev . cld . equals ( ord . getClassDescriptor ( ) ) ) { TableAlias ordAlias = getTableAliasForClassDescriptor ( ord . getClassDescriptor ( ) ) ; Join join = prev . getJoin ( ordAlias ) ; if ( join != null ) { join . isOuter = join . isOuter || outer ; } prev = ordAlias ; } prevKeys = ord . getForeignKeyFieldDescriptors ( prev . cld ) ; keys = cld . getPkFields ( ) ; if ( ( fieldRef != null ) && ( i == ( pathLength - 1 ) ) ) { FieldDescriptor [ ] pk = cld . getPkFields ( ) ; for ( int j = 0 ; j < pk . length ; j ++ ) { if ( pk [ j ] . getAttributeName ( ) . equals ( fieldRef [ 0 ] ) ) { fieldRef [ 0 ] = ( ( FieldDescriptor ) prevKeys [ j ] ) . getAttributeName ( ) ; return prev ; } } } } pathAlias = aUserAlias == null ? null : aUserAlias . getAlias ( attrPath ) ; curr = getTableAliasForPath ( attrPath , pathAlias , hintClasses ) ; if ( curr == null ) { curr = createTableAlias ( cld , attrPath , pathAlias , hintClasses ) ; outer = outer || ( curr . cld == prev . cld ) || curr . hasExtents ( ) || useOuterJoins ; addJoin ( prev , prevKeys , curr , keys , outer , attr ) ; buildSuperJoinTree ( curr , cld , aPath , outer ) ; } prev = curr ; } m_logger . debug ( "Result of getTableAlias(): " + curr ) ; return curr ; }
Get TableAlias by the path from the target table of the query.
@param aPath the path from the target table of the query to this TableAlias.
@param useOuterJoins use outer join to join this table with the previous
table in the path.
@param aUserAlias if specified, overrides alias in crit
@param fieldRef String[1] contains the field name.
In the case of related table's primary key the "related.pk" attribute
must not add new join, but use the value of foreign key
@param pathClasses the hints