/** Modifies the instance */ void addFilter(String condition, Object value) { String[] parts = condition.trim().split(" "); if (parts.length < 1 || parts.length > 2) throw new IllegalArgumentException("'" + condition + "' is not a legal filter condition"); String prop = parts[0].trim(); FilterOperator op = (parts.length == 2) ? this.translate(parts[1]) : FilterOperator.EQUAL; // If we have a class restriction, check to see if the property is the @Parent or @Id if (this.classRestriction != null) { KeyMetadata<?> meta = Keys.getMetadataSafe(this.classRestriction); if (prop.equals(meta.getParentFieldName())) { throw new IllegalArgumentException( "@Parent fields cannot be filtered on. Perhaps you wish to use filterKey() or ancestor() instead?"); } else if (prop.equals(meta.getIdFieldName())) { if (meta.hasParentField()) throw new IllegalArgumentException( "@Id fields cannot be filtered on classes that have @Parent fields. Perhaps you wish to use filterKey() instead?"); String kind = Key.getKind(this.classRestriction); if (value instanceof Number) { value = DatastoreUtils.createKey( null, kind, ((Number) value).longValue()); // accept non-long values } else if (value instanceof String) { value = DatastoreUtils.createKey(null, kind, value); } else { throw new IllegalArgumentException("Id filter values must be Long or String"); } prop = "__key__"; } } // Convert to something filterable, possibly extracting/converting keys value = loader.getObjectifyImpl().makeFilterable(value); this.actual.addFilter(prop, op, value); if (op == FilterOperator.IN || op == FilterOperator.NOT_EQUAL) hasMulti = true; }
/* (non-Javadoc) * @see java.lang.Object#clone() */ @SuppressWarnings("unchecked") public QueryImpl<T> clone() { try { QueryImpl<T> impl = (QueryImpl<T>) super.clone(); impl.actual = DatastoreUtils.cloneQuery(this.actual); return impl; } catch (CloneNotSupportedException e) { // impossible throw new RuntimeException(e); } }