* @return The attributes being queried, in Object'read attribute list form.
*/
public static Pair getAttributes(Query query)
{
Pair attributes = null;
Lookup polymorphicAttrMap = null;
// Add primitive output attributes
for (Field field = query.getFirstOutputField(); field != null; field = field.getNext())
{
Attribute attribute = field.getAttribute();
Metaclass metaclass = attribute.getMetaclass();
if (metaclass.isUpcast(query.getMetaclass()))
{
attributes = new Pair(attribute.getSymbol(), attributes);
}
else
{
// Attribute defined in subclass, add to polymorphic attribute list
assert query.getMetaclass().isUpcast(metaclass);
if (polymorphicAttrMap == null)
{
polymorphicAttrMap = new HashTab(2);
}
Pair subclassAttrs = (Pair)polymorphicAttrMap.get(metaclass);
subclassAttrs = new Pair(attribute.getSymbol(), subclassAttrs);
polymorphicAttrMap.put(metaclass, subclassAttrs);
}
}
// Add non-primitive output attributes
for (Iterator itr = query.getAssocIterator(Query.ASSOC_QUERY); itr.hasNext(); )
{
Query subQuery = (Query)itr.next();
Attribute attribute = subQuery.getAttribute();
Pair subQueryAttrs = getAttributes(subQuery);
Metaclass metaclass = attribute.getMetaclass();
Object itemToAdd = (subQueryAttrs == null) ? (Object)attribute.getSymbol() : new Pair(attribute.getSymbol(), subQueryAttrs);
if (metaclass.isUpcast(query.getMetaclass()))
{
attributes = new Pair(itemToAdd, attributes);
}
else
{
// Attribute defined in subclass, add to polymorphic attribute list
assert query.getMetaclass().isUpcast(metaclass);
if (polymorphicAttrMap == null)
{
polymorphicAttrMap = new HashTab(2);
}
Pair subclassAttrs = (Pair)polymorphicAttrMap.get(metaclass);
subclassAttrs = new Pair(itemToAdd, subclassAttrs);
polymorphicAttrMap.put(metaclass, subclassAttrs);
}
}
// Merge the polymorphic attributes
if (polymorphicAttrMap != null)
{
for (Lookup.Iterator itr = (Lookup.Iterator)polymorphicAttrMap.iterator(); itr.hasNext(); )
{
Metaclass subClass = (Metaclass)itr.next();
Pair subclassAttrs = (Pair)itr.getValue();
attributes = new Pair(