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.");
}
return null;
}
} else {
int tokenType = projection.getToken().getTokenType();
switch (tokenType) {
case TokenType.IDENTIFIER:
//a SQL function call -- check the arguments
_projectionType = FUNCTION;
for (Iterator iter = projection.getChild(0).children(); iter.hasNext(); ) {
checkProjection((ParseTreeNode) iter.next(), false, true);
}
break;
case TokenType.DOT:
//a path expression -- check if it is valid, and create a paramInfo
Iterator iter = 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 (iter.hasNext()) {
curNode = (ParseTreeNode) iter.next();
curName = curNode.getToken().getTokenValue();
if ((!curName.equals(_projectionName))
&& (!curName.equals(_projectionAlias))
&& (!curName.equals(_fromClassName))
&& (!curName.equals(_fromClassAlias))) {
// reset the enumeration
iter = projection.children();
curName = _fromClassAlias;
}
projectionName.append(curName);
projectionInfo.addElement(curName);
}
//use the ClassDescriptor to check that the rest of the path is valid.
ClassDescriptor curClassDesc = _clsDesc;
FieldDescriptor curField = null;
int count = 0;
String curToken;
while (iter.hasNext()) {
// there may be nested attribute name
curField = null;
curName = null;
while ((curField == null) && iter.hasNext()) {
curNode = (ParseTreeNode) iter.next();
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 = curField.getClassDescriptor();
if ((curClassDesc == null) && iter.hasNext()) {
throw new QueryException("An non-reference field was requested: "
+ curName + " (" + curClassDesc + ")");
}
count++;
}
field = curField;
getPathInfo().put(projection, projectionInfo);
getFieldInfo().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) {
_projectionName = projectionName.toString();
if (!isSimple) {
_projectionType = DEPENDANT_OBJECT;
} else if (count > 1) {
_projectionType = DEPENDANT_OBJECT_VALUE;
} else if (field.getContainingClassDescriptor() != _clsDesc) {
_projectionType = DEPENDANT_OBJECT_VALUE;
} else {
_projectionType = DEPENDANT_VALUE;
}
} else {
if (!isSimple && onlySimple) {
throw new QueryException("Only primitive values are allowed "
+ "to be passed as parameters to Aggregate and SQL "
+ "functions.");
}
}
break;