@Override
public PropertyInfo parsePropertyExp(String keyString, String exp, List<String> filePaths) throws YaacException {
try {
// property can also be used during evaluation
Evaluator e = EGQLUtil.parser(exp).bool_exp().e;
if (!e.aggregationChildren().isEmpty()) {
// aggregation function is not allowed here
throw new YaacException(ErrorCode.E301, null);
}
// load targeting entity
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
final Entity entity = datastore.get(KeyFactory.stringToKey(keyString));
// file context
final List<FileDownloadPath> files = filePaths == null ? new ArrayList<FileDownloadPath>() :
transform(filePaths, new Function<String, FileDownloadPath>(){
@Override
public FileDownloadPath apply(String pathStr) {
return AutoBeanUtil.decode(FileDownloadPath.class, pathStr);
}
});
EvaluationResult r = e.evaluate(new ProcessDataRecord() {
@Override
public FileDownloadPath lookupFileReference(Integer index) {
return files.get(index);
}
@Override
public EvaluationResult lookup(String name) {
if (isNullOrEmpty(name)) {
return null;
} else { // normal case, include key selection and property selection
Object payload = Datastore.KEY_RESERVED_NAME.equals(name) ? entity.getKey() : entity.getProperty(name);
return new EvaluationResult(entity.getKey(), name, null, payload);
}
}
@Override
public Iterable<EvaluationResult> asIterable() {
// should not be called
throw new IllegalArgumentException();
}
});
PropertyInfo info = DatastoreUtil.convert(keyString, null, null, r.getPayload(), r.getWarnings());
return info;
} catch (RecognitionException e) {
// can't parse input
logger.log(Level.SEVERE, e.getMessage(), e);
throw new YaacException(null, e.getMessage());
} catch (EntityNotFoundException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
throw new YaacException(ErrorCode.E302, null);
}
}