*/
private JDOFieldDescriptor checkProjection( ParseTreeNode projection,
boolean topLevel,
boolean onlySimple )
throws QueryException {
JDOFieldDescriptor field = null;
if ( projection.getChildCount() == 0 ) {
if ( topLevel ) {
_projectionType = PARENT_OBJECT;
_projectionName = projection.getToken().getTokenValue();
if ( ! _projectionName.equals(_fromClassAlias) )
throw new QueryException( "Object name not the same in SELECT and FROM - select: " + _projectionName + ", from: " + _fromClassAlias );
}
else
if ( onlySimple )
throw new QueryException( "Only primitive values are allowed to be passed as parameters to Aggregate and SQL functions." );
else
return null;
}
else {
int tokenType = projection.getToken().getTokenType();
switch( tokenType ) {
case IDENTIFIER:
//a SQL function call -- check the arguments
_projectionType = FUNCTION;
for (Enumeration e = projection.getChild(0).children();
e.hasMoreElements(); )
checkProjection( (ParseTreeNode) e.nextElement(), false, true );
break;
case DOT:
//a path expression -- check if it is valid, and create a paramInfo
Enumeration e = projection.children();
ParseTreeNode curNode = null;
String curName = null;
StringBuffer projectionName = new StringBuffer();
Vector projectionInfo = new Vector();
//check that the first word before the dot is our class
if ( e.hasMoreElements() ) {
curNode = (ParseTreeNode) e.nextElement();
curName = curNode.getToken().getTokenValue();
if ( ( ! curName.equals(_projectionName) ) &&
( ! curName.equals(_projectionAlias) ) &&
( ! curName.equals(_fromClassName) ) &&
( ! curName.equals(_fromClassAlias) ) ) {
// reset the enumeration
e = projection.children();
curName = _fromClassAlias;
}
projectionName.append(curName);
projectionInfo.addElement(curName);
}
//use the ClassDescriptor to check that the rest of the path is valid.
JDOClassDescriptor curClassDesc = _clsDesc;
JDOFieldDescriptor curField = null;
int count = 0;
String curToken;
while ( e.hasMoreElements() ) {
// there may be nested attribute name
curField = null;
curName = null;
while ( curField == null && e.hasMoreElements() ) {
curNode = (ParseTreeNode) e.nextElement();
curToken = curNode.getToken().getTokenValue();
if ( curName == null ) {
curName = curToken;
} else {
curName = curName + "." + curToken;
}
curField = getFieldDesc(curName, curClassDesc);
}
if ( curField == null )
throw new QueryException( "An unknown field was requested: " + curName + " (" + curClassDesc + ")" );
projectionName.append(".").append(curName);
projectionInfo.addElement(curName);
curClassDesc = (JDOClassDescriptor) curField.getClassDescriptor();
if ( curClassDesc == null && e.hasMoreElements() )
throw new QueryException( "An non-reference field was requested: " + curName + " (" + curClassDesc + ")" );
count++;
}
field = curField;
_pathInfo.put( projection, projectionInfo );
_fieldInfo.put( projection, curField );
Class theClass = curField.getFieldType();
// is it actually a Java primitive, or String,
// or a subclass of Number
boolean isSimple = Types.isSimpleType(theClass);
if ( topLevel ) {