/** * Add a filter condition to the builder. * @param name The attribute to filter. * @param obj The object to test for equality. * @param <A> The attribute type. * @return The query builder (for chaining). */ public <A> EntityQueryBuilder addFilterField(TypedName<A> name, @Nonnull A obj) { return this.addFilterField(Attribute.create(name, obj)); }
/** * Create a new attribute pair. * @param name The attribute name. * @param val The value. * @param <T> The attribute type. * @return The attribute-value object. */ public static <T> Attribute<T> create(@Nonnull TypedName<T> name, @Nonnull T val) { return new Attribute<>(name, val); }
/** * Set an attribute in the entity. * @param attr The attribute to set. * @param <T> The attribute type. * @return The entity builder (for chaining). * @throws NoSuchAttributeException if the specified attribute is not supported by this entity. */ public <T> EntityBuilder setAttribute(Attribute<T> attr) { setAttribute(attr.getTypedName(), attr.getValue()); return this; }
@Override @Nonnull public <T> List<Entity> find(Attribute<T> attr) { return find(attr.getTypedName(), attr.getValue()); }
@Nonnull @Override public <T> List<Entity> find(Attribute<T> attr) { return find(attr.getTypedName(), attr.getValue()); }
@Nullable @Override public Attribute<?> apply(@Nullable TypedName<?> input) { assert input != null; return Attribute.create((TypedName) input, get(input)); } });
/** * Create a new attribute pair. * @param name The attribute name. * @param val The value. * @param <T> The attribute type. * @return The attribute-value object. */ public static <T> Attribute<T> create(@Nonnull TypedName<T> name, @Nonnull T val) { return new Attribute<>(name, val); }
@Override public String toString() { ToStringBuilder tsb = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); tsb.append("type", getType()); for (Attribute<?> av: getAttributes()) { tsb.append(av.getTypedName().toString(), av.getValue()); } return tsb.toString(); }
@Override public Iterator<Attribute<?>> iterator() { return (Iterator) IntStream.range(0, attributeNames.size()) .mapToObj(i -> { if (i == 0) { return Attribute.create(CommonAttributes.ENTITY_ID, getId()); } Object val = attributeValues[i-1]; if (val == null) { return null; } else { return Attribute.create((TypedName) attributeNames.getAttribute(i), val); } }) .filter(Predicates.notNull()) .iterator(); }
/** * Determine whether this query matches the specified entity. * @param entity The entity to test. * @return The entity. */ public boolean matches(Entity entity) { if (!entity.getType().equals(entityType)) { return false; } for (Attribute<?> attr: filterFields) { Object val = entity.maybeGet(attr.getTypedName()); if (!attr.getValue().equals(val)) { return false; } } return true; } }
@Override public Iterator<Attribute<?>> iterator() { return (Iterator) IntStream.range(0, layout.attributes.size()) .mapToObj(i -> { Object val = layout.getters.get(i).get(AbstractBeanEntity.this); if (val == null) { return null; } else { return Attribute.create((TypedName) layout.attributes.getAttribute(i), val); } }) .filter(Predicates.notNull()) .iterator(); }
@Override public Entity build() { Preconditions.checkState(type != null, "Entity type not set"); Preconditions.checkState(idSet, "ID not set"); if (attributes.isEmpty() || attributes.keySet().equals(Collections.singleton(CommonAttributes.ENTITY_ID))) { return new BareEntity(type, id); } else { List<TypedName<?>> names = new ArrayList<>(attributes.size()); names.add(CommonAttributes.ENTITY_ID); for (Attribute<?> a: attributes.values()) { names.add(a.getTypedName()); } assert names.lastIndexOf(CommonAttributes.ENTITY_ID) == 0; AttributeSet aset = AttributeSet.create(names); Object[] values = new Object[aset.size()]; for (Attribute<?> a: attributes.values()) { int i = aset.lookup(a.getTypedName()); values[i-1] = a.getValue(); } return new BasicEntity(type, id, aset, values); } } }
@Override public <T> EntityBuilder setAttribute(TypedName<T> name, T val) { Preconditions.checkNotNull(name, "attribute"); Preconditions.checkNotNull(val, "value"); Preconditions.checkArgument(name.getRawType().isInstance(val), "value %s not of type %s", val, name.getType()); if (name == CommonAttributes.ENTITY_ID) { return setId(((Long) val).longValue()); } else { attributes.put(name.getName(), Attribute.create(name, val)); return this; } }
@Override public void describeTo(DescriptionWriter writer) { writer.putField("type", getType()); for (Attribute<?> av: getAttributes()) { writer.putField(av.getTypedName().toString(), av.getValue()); } }
@Test public void testTwoAttrFilter() { EntityQuery<Entity> q = EntityQuery.newBuilder(CommonTypes.RATING) .addFilterField(CommonAttributes.ITEM_ID, 42L) .addFilterField(CommonAttributes.USER_ID, 29L) .build(); assertThat(q.getEntityType(), equalTo(CommonTypes.RATING)); assertThat(q.getFilterFields(), (Matcher) containsInAnyOrder(Attribute.create(CommonAttributes.ITEM_ID, 42L), Attribute.create(CommonAttributes.USER_ID, 29L))); assertThat(q.getSortKeys(), hasSize(0)); assertThat(q.getViewType(), equalTo(Entity.class)); }
int ap = attributes.lookup(a.getTypedName()); if (ap >= 0) { storeBuilders[ap].add(a.getValue());