gaeCtx.useCursor = false;
query.option(QueryOptionOffset.ID).activate();
}
if (value != null && ClassInfo.isModel(value.getClass())) {
Key key = GaeMappingUtils.getKey(value);
q.addFilter(propertyName, op, key);
} else {
if (ClassInfo.isId(f)) {
Id id = f.getAnnotation(Id.class);
switch(id.value()) {
case NONE:
if(value != null){
if(!Collection.class.isAssignableFrom(value.getClass())){
// long or string goes toString
Key key;
if(parentKey == null){
key = KeyFactory.createKey(
q.getKind(),
value.toString());
}else {
key = KeyFactory.createKey(
parentKey,
q.getKind(),
value.toString());
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, key);
}else {
List<Key> keys = new ArrayList<Key>();
for(Object val: (Collection<?>)value) {
if(parentKey == null){
keys.add(KeyFactory.createKey(q.getKind(), val.toString()));
}else {
keys.add(KeyFactory.createKey(parentKey, q.getKind(), val.toString()));
}
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, keys);
}
}
break;
case AUTO_INCREMENT:
if(value != null){
if(!Collection.class.isAssignableFrom(value.getClass())){
Key key;
Class<?> type = f.getType();
if(Long.TYPE == type || Long.class.isAssignableFrom(type)){
if(parentKey == null){
key = KeyFactory.createKey(
q.getKind(),
(Long)value);
}else {
key = KeyFactory.createKey(
parentKey,
q.getKind(),
(Long)value);
}
} else {
if(parentKey == null){
key = KeyFactory.createKey(
q.getKind(),
value.toString());
}else {
key = KeyFactory.createKey(
parentKey,
q.getKind(),
value.toString());
}
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, key);
}else {
List<Key> keys = new ArrayList<Key>();
for(Object val: (Collection<?>)value) {
if (value instanceof String)
val = Long.parseLong((String) val);
if(parentKey == null){
keys.add(KeyFactory.createKey(q.getKind(), (Long)val));
}else {
keys.add(KeyFactory.createKey(parentKey, q.getKind(), (Long)val));
}
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, keys);
}
}
break;
case UUID:
if(value != null) {
if(!Collection.class.isAssignableFrom(value.getClass())){
// long or string goes toString
Key key;
if(parentKey == null){
key = KeyFactory.createKey(
q.getKind(),
value.toString());
}else {
key = KeyFactory.createKey(
parentKey,
q.getKind(),
value.toString());
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, key);
}else {
List<Key> keys = new ArrayList<Key>();
for(Object val: (Collection<?>)value) {
keys.add(KeyFactory.createKey(q.getKind(), val.toString()));
}
q.addFilter(Entity.KEY_RESERVED_PROPERTY, op, keys);
}
}
break;
default:
throw new SienaException("Id Generator "+id.value()+ " not supported");
}
} else if (Enum.class.isAssignableFrom(f.getType())) {
value = value.toString();
q.addFilter(propertyName, op, value);
} else {
q.addFilter(propertyName, op, value);
}
}
}else if(QueryFilterSearch.class.isAssignableFrom(filter.getClass())){
Class<T> clazz = query.getQueriedClass();
QueryFilterSearch qf = (QueryFilterSearch)filter;
if(qf.fields.length>1)
throw new SienaException("Search not possible for several fields in GAE: only one field");
try {
Field field = Util.getField(clazz, qf.fields[0]);
if(field.isAnnotationPresent(Unindexed.class)){
throw new SienaException("Cannot search the @Unindexed field "+field.getName());
}
// cuts match into words
String[] words = qf.match.split("\\s");
// if several words, then only OR operator represented by IN GAE
Pattern pNormal = Pattern.compile("[^\\*](\\w+)[^\\*]");
if(words.length>1){
for(String word:words){
if(!pNormal.matcher(word).matches()){
throw new SienaException("Cannot do a multiwords search with the * operator");
}
}
List<String> wordList = new ArrayList<String>();
Collections.addAll(wordList, words);
addSearchFilterIn(q, field, wordList);
}else {
// searches for pattern such as "alpha*" or "*alpha" or "alpha"
Pattern pStart = Pattern.compile("(\\w+)\\*");
String word = words[0];
Matcher matcher = pStart.matcher(word);
if(matcher.matches()){
String realWord = matcher.group(1);
addSearchFilterBeginsWith(q, field, realWord);
continue;
}
matcher = pNormal.matcher(word);
if(matcher.matches()){
addSearchFilterEquals(q, field, word);
continue;
}
Pattern pEnd = Pattern.compile("\\*(\\w+)");
matcher = pEnd.matcher(word);
if(matcher.matches()){
throw new SienaException("Cannot do a \"*word\" search in GAE");
}
}
}catch(Exception e){
throw new SienaException(e);
}
break;
}else if(QueryFilterEmbedded.class.isAssignableFrom(filter.getClass())){
QueryFilterEmbedded qf = (QueryFilterEmbedded)filter;
String propName = "";
int sz = qf.fields.size();
for(int i=0; i<sz; i++){
propName += ClassInfo.getSingleColumnName(qf.fields.get(i));
if(i < sz-1){
propName += qf.fieldSeparator;
}
}
Object value = qf.value;
FilterOperator op = operators.get(qf.operator);
// IN and NOT_EQUAL doesn't allow to use cursors
if(op == FilterOperator.IN || op == FilterOperator.NOT_EQUAL){
QueryOptionGaeContext gaeCtx = (QueryOptionGaeContext)query.option(QueryOptionGaeContext.ID);
if(gaeCtx==null){
gaeCtx = new QueryOptionGaeContext();
query.options().put(gaeCtx.type, gaeCtx);
}
gaeCtx.useCursor = false;
query.option(QueryOptionOffset.ID).activate();
}
q.addFilter(propName, op, value);
}
}
// adds filter on owners
List<QueryOwned> ownees = query.getOwnees();
for (QueryOwned ownee : ownees) {
String propertyName = ClassInfo.getSimplestColumnName(ownee.field);
FilterOperator op = operators.get("=");
Key key = GaeMappingUtils.getKey(ownee.owner);
q.addFilter(propertyName, op, key);
}
List<QueryOrder> orders = query.getOrders();
for (QueryOrder order : orders) {