package com.mysema.rdfbean.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import com.mysema.query.BooleanBuilder;
import com.mysema.query.types.Constant;
import com.mysema.query.types.ConstantImpl;
import com.mysema.query.types.Expression;
import com.mysema.query.types.Predicate;
/**
* @author tiwe
*
*/
@SuppressWarnings("unchecked")
public final class Blocks {
private static final Map<UID, Constant<UID>> CACHE = new HashMap<UID, Constant<UID>>(1024);
static {
for (UID uid : Nodes.all) {
CACHE.put(uid, new ConstantImpl<UID>(UID.class, uid));
}
}
public static final PatternBlock S_TYPE = pattern(QNODE.s, RDF.type, QNODE.type, QNODE.typeContext);
public static final PatternBlock S_FIRST = pattern(QNODE.s, RDF.first, QNODE.first);
public static final PatternBlock S_REST = pattern(QNODE.s, RDF.rest, QNODE.rest);
public static final PatternBlock SPO = pattern(QNODE.s, QNODE.p, QNODE.o);
public static final PatternBlock SPOC = pattern(QNODE.s, QNODE.p, QNODE.o, QNODE.c);
public static PatternBlock pattern(Object subject, Object predicate, Object object, @Nullable Object context) {
return new PatternBlock(
convert(ID.class, subject),
convert(UID.class, predicate),
convert(NODE.class, object),
context != null ? convert(UID.class, context) : null);
}
public static PatternBlock pattern(Object subject, Object predicate, Object object) {
return new PatternBlock(
convert(ID.class, subject),
convert(UID.class, predicate),
convert(NODE.class, object));
}
public static GroupBlock group(Collection<Predicate> predicates) {
List<Block> blocks = new ArrayList<Block>();
BooleanBuilder filters = new BooleanBuilder();
handle(predicates, blocks, filters);
if (filters.getValue() == null) {
return new GroupBlock(blocks);
} else {
return new GroupBlock(blocks, filters.getValue());
}
}
private static void handle(Collection<Predicate> predicates, List<Block> blocks, BooleanBuilder filters) {
for (Predicate predicate : predicates) {
if (predicate instanceof Block) {
blocks.add((Block) predicate);
} else {
filters.and(predicate);
}
}
}
public static GroupBlock group(Block... blocks) {
return new GroupBlock(Arrays.asList(blocks));
}
public static GroupBlock filter(Block block, Predicate... filters) {
return new GroupBlock(Collections.singletonList(block), filters);
}
public static OptionalBlock optional(Block... blocks) {
return new OptionalBlock(Arrays.asList(blocks));
}
public static OptionalBlock optional(List<Block> blocks, Predicate... predicates) {
return new OptionalBlock(blocks, predicates);
}
public static OptionalBlock optionalFilter(Block block, Predicate... predicates) {
return new OptionalBlock(Collections.singletonList(block), predicates);
}
public static UnionBlock union(Block... blocks) {
return new UnionBlock(Arrays.asList(blocks));
}
public static GraphBlock graph(UID context, Collection<Predicate> predicates) {
return graph(convert(UID.class, context), predicates);
}
public static GraphBlock graph(UID context, Block... blocks) {
return graph(convert(UID.class, context), blocks);
}
public static GraphBlock graphFilter(UID context, Block block, Predicate... filters) {
return graphFilter(convert(UID.class, context), block, filters);
}
public static GraphBlock graph(Expression<UID> context, Collection<Predicate> predicates) {
List<Block> blocks = new ArrayList<Block>();
BooleanBuilder filters = new BooleanBuilder();
handle(predicates, blocks, filters);
if (filters.getValue() == null) {
return new GraphBlock(convert(UID.class, context), blocks);
} else {
return new GraphBlock(convert(UID.class, context), blocks, filters.getValue());
}
}
public static GraphBlock graph(Expression<UID> context, Block... blocks) {
return new GraphBlock(context, Arrays.asList(blocks));
}
public static GraphBlock graphFilter(Expression<UID> context, Block block, Predicate... filters) {
return new GraphBlock(context, Collections.singletonList(block), filters);
}
private static <T extends NODE> Expression<T> convert(Class<T> cl, Object o) {
if (o instanceof UID && CACHE.containsKey(o)) {
return (Expression<T>) CACHE.get(o);
} else if (cl.isAssignableFrom(o.getClass())) {
return new ConstantImpl<T>((T) o);
} else if (o instanceof Expression && NODE.class.isAssignableFrom(((Expression) o).getType())) {
return (Expression<T>) o;
} else {
throw new IllegalArgumentException(o.toString());
}
}
private Blocks() {
}
}