Java tutorial
/* * polymap.org * Copyright (C) 2014, Falko Brutigam. All rights reserved. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3.0 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.polymap.model2.query; import com.google.common.collect.Lists; import org.polymap.model2.Association; import org.polymap.model2.CollectionProperty; import org.polymap.model2.Composite; import org.polymap.model2.Entity; import org.polymap.model2.ManyAssociation; import org.polymap.model2.Property; import org.polymap.model2.engine.TemplateInstanceBuilder; import org.polymap.model2.engine.TemplateProperty; import org.polymap.model2.query.grammar.AssociationEquals; import org.polymap.model2.query.grammar.BooleanExpression; import org.polymap.model2.query.grammar.CompositeCollectionQuantifier; import org.polymap.model2.query.grammar.Conjunction; import org.polymap.model2.query.grammar.Disjunction; import org.polymap.model2.query.grammar.IdPredicate; import org.polymap.model2.query.grammar.ManyAssociationQuantifier; import org.polymap.model2.query.grammar.Negation; import org.polymap.model2.query.grammar.PropertyEquals; import org.polymap.model2.query.grammar.PropertyEqualsAny; import org.polymap.model2.query.grammar.PropertyMatches; import org.polymap.model2.query.grammar.PropertyNotEquals; import org.polymap.model2.query.grammar.Quantifier; import org.polymap.model2.query.grammar.Quantifier.Type; import org.polymap.model2.query.grammar.TheAssociationQuantifier; import org.polymap.model2.query.grammar.TheCompositeQuantifier; import org.polymap.model2.runtime.EntityRepository; /** * Static factory methods to create query expressions. * * @author <a href="http://www.polymap.de">Falko Brutigam</a> */ public class Expressions { public static final BooleanExpression TRUE = new BooleanExpression() { @Override public boolean evaluate(Composite target) { return true; } }; public static final BooleanExpression FALSE = new BooleanExpression() { @Override public boolean evaluate(Composite target) { return false; } }; public static Conjunction and(BooleanExpression first, BooleanExpression second, BooleanExpression... more) { return new Conjunction(Lists.asList(first, second, more).toArray(new BooleanExpression[2 + more.length])); } public static Disjunction or(BooleanExpression first, BooleanExpression second, BooleanExpression... more) { return new Disjunction(Lists.asList(first, second, more).toArray(new BooleanExpression[2 + more.length])); } public static <T> PropertyEquals<T> eq(Property<T> prop, T value) { return new PropertyEquals((TemplateProperty) prop, value); } public static <T> PropertyNotEquals<T> notEq(Property<T> prop, T value) { return new PropertyNotEquals((TemplateProperty) prop, value); } public static <T> Negation not(BooleanExpression expression) { return new Negation(expression); } /** * Checks the value to see if it matches the specified wildcard matcher, always * testing case-sensitive. * <p/> * The wildcard matcher uses the characters '?' and '*' to represent a single or * multiple wildcard characters. This is the same as often found on Dos/Unix * command lines. The check is case-sensitive always. */ public static <T> PropertyMatches<T> matches(Property<T> prop, T value) { return new PropertyMatches((TemplateProperty) prop, value); } public static <T> PropertyEqualsAny<T> eqAny(Property<T> prop, T... values) { return new PropertyEqualsAny((TemplateProperty) prop, values); } // public static <T> PropertyEqualsAny<T> eqAny( Property<T> prop, Iterable<T> values ) { // ArrayList<T> l = Lists.newArrayList( values ); // T[] a = l.toArray( new T[ l.size() ] ); // return new PropertyEqualsAny( (TemplateProperty)prop, a ); // } public static <T extends Entity> AssociationEquals<T> is(Association<T> assoc, T entity) { return new AssociationEquals((TemplateProperty) assoc, id(entity)); } public static <T extends Entity> AssociationEquals<T> isAnyOf(Association<T> assoc, T... entities) { return new AssociationEquals((TemplateProperty) assoc, id(entities)); } // public static <T extends Entity> AssociationEquals<T> isAnyOf( Association<T> assoc, Iterable<T> entities ) { // ArrayList<T> l = Lists.newArrayList( entities ); // l.toArray( new T[] ); // return new AssociationEquals( (TemplateProperty)assoc, id( entities ) ); // } /** * True if {@link Entity#id()} of the target Entity of the {@link Query} is in * the given array of ids. */ public static <T extends Entity> IdPredicate<T> id(Object... ids) { return new IdPredicate(ids); } /** * True if {@link Entity#id()} of the target Entity of the {@link Query} equals * an id of one of the given Entities. */ public static <T extends Entity> IdPredicate<T> id(T... entities) { Object[] ids = new Object[entities.length]; for (int i = 0; i < entities.length; i++) { ids[i] = entities[i].id(); } return new IdPredicate(ids); } // Quantifiers **************************************** /** * Queries an {@link Association}. True if the associated {@link Entity} matches * the given sub-expression. */ public static <T extends Entity> Quantifier the(Association<T> prop, BooleanExpression subExp) { return new TheAssociationQuantifier(prop, subExp); } /** * Queries a single Composite property. True if the Composite matches the given * sub-expression. */ public static <T extends Composite> Quantifier the(Property<T> prop, BooleanExpression subExp) { return new TheCompositeQuantifier(prop, subExp); } /** * True if ANY member of the given Composite collection matches the given * sub-expression. */ public static <T extends Composite> Quantifier anyOf(CollectionProperty<T> prop, BooleanExpression subExp) { return new CompositeCollectionQuantifier(Type.ANY, prop, subExp); } /** * True if ANY member of the given association matches the given sub-expression. */ public static <T extends Entity> Quantifier anyOf(ManyAssociation<T> prop, BooleanExpression subExp) { return new ManyAssociationQuantifier(Type.ANY, prop, subExp); } // Template ******************************************* /** * Returns query template of the given {@link Composite} type. * * @param type * @param repo * @return Newly created query template instance. */ public static <T extends Composite> T template(Class<T> type, EntityRepository repo) { return new TemplateInstanceBuilder(repo).newComposite(type); } }