/*
* Copyright Konstantin Triger <kostat@gmail.com>
*
* This file is part of Jaque - JAva QUEry library <http://code.google.com/p/jaque/>.
*
* Jaque is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Jaque 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package jaque;
import java.lang.reflect.Method;
import jaque.expressions.*;
import jaque.functions.*;
import static jaque.expressions.Expression.*;
abstract class Group<Key, T> implements Iterable<T> {
protected Group(Key key) {
Key = key;
}
public final Key Key;
}
final class Join2<Outer, Inner> {
public Join2(Outer outer, Inner inner) {
Outer = outer;
Inner = inner;
}
public final Outer Outer;
public final Inner Inner;
}
public final class DynamicQuery {
private static final Method _where;
private static final Method _skip;
private static final Method _select;
private static final Method _selectMany;
static {
try {
_where = Query.class.getDeclaredMethod("where", new Class<?>[] {
Function.class, Iterable.class });
_skip = Query.class.getDeclaredMethod("skip", new Class<?>[] {
Integer.TYPE, Iterable.class });
_select = Query.class.getDeclaredMethod("select", new Class<?>[] {
Function.class, Iterable.class });
_selectMany = Query.class.getDeclaredMethod("selectMany",
new Class<?>[] { Function.class, Iterable.class });
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public static <S> Iterable<S> from(Iterable<S> source) {
return source;
}
public static <S> Queryable<S> toQueryable(Iterable<S> source) {
return new IterableQueryable<S>(null, source);
}
@SuppressWarnings("unchecked")
public static <E> Queryable<E> where(
final Function<Boolean, ? super E> predicate,
final Queryable<E> source) {
LambdaExpression<?> lambda = LambdaExpression.parse(predicate);
Class<E> eType = source.getElementType();
if (eType == null)
eType = (Class<E>) lambda.getParameters().get(0).getResultType();
Expression e = invoke(null, _where, quote(lambda), source
.getExpression());
return source.getFactory().createQueryable(eType, e);
}
@SuppressWarnings("unchecked")
public static <T, Result> Queryable<Result> select(
final Function<? extends Result, ? super T> transform,
final Queryable<T> source) {
LambdaExpression<?> lambda = LambdaExpression.parse(transform);
Expression e = invoke(null, _select, quote(lambda), source
.getExpression());
return (Queryable<Result>) source.getFactory().createQueryable(
lambda.getResultType(), e);
}
@SuppressWarnings("unchecked")
public static <T, Result> Queryable<Result> selectMany(
final Function<Iterable<Result>, ? super T> transform,
final Queryable<T> source) {
LambdaExpression<?> lambda = LambdaExpression.parse(transform);
Expression e = invoke(null, _selectMany, quote(lambda), source
.getExpression());
return (Queryable<Result>) source.getFactory().createQueryable(null, e);
}
public static <T> Queryable<T> skip(final int count,
final Queryable<T> source) {
Expression e = invoke(null, _skip, constant(count, Integer.TYPE),
source.getExpression());
return source.getFactory().createQueryable(source.getElementType(), e);
}
private DynamicQuery() {
}
// public static <T, R> Iterable<R> from(
// Function<Iterable<?>, LambdaExpression<Function<Iterable<?>, Iterable<?
// extends T>>>> queryable,
// Function<Iterable<R>, Iterable<? extends T>> /*
// * {Iterable<?
// * extends T> =>
// * Iterable<R> }
// */selector) {
// try {
// return (Iterable<R>)queryable.invoke(
// (LambdaExpression<Function<Iterable<?>, Iterable<? extends T>>>)
// (Object)LambdaExpression.parse(selector));
// } catch (Throwable e) {
// throw new RuntimeException(e);
// }
// }
// @SuppressWarnings("unchecked")
// public static <T, R> Iterable<R> from(Queryable<T> source,
// Function<Iterable<R>, ? super Iterable<? extends T>> /*
// * {Iterable<?
// * extends
// * T> =>
// * Iterable<R> }
// */selector) {
// Expression e = LambdaExpression.parse(selector);
// e = e.apply(QueryableExpressionVisitor.Instance);
// e = e.apply(new ExpressionInliner());
// // e = e.apply(LambdaExpressionReducer.Instance);
// return null;// source
// // .invoke((LambdaExpression<Function<Iterable<R>, Iterable<? extends
// // T>>>) e);
// }
//
// public static <T, R> Iterable<R> from(Iterable<? extends T> source,
// Function<Iterable<R>, ? super Iterable<? extends T>> /*
// * {Iterable<?
// * extends
// * T> =>
// * Iterable<R> }
// */selector) {
// try {
// return selector.invoke(source);
// } catch (RuntimeException e) {
// throw e;
// } catch (Throwable e) {
// throw new RuntimeException(e);
// }
// }
//
// public static <T, S, R> Function<Iterable<R>, ? super Iterable<? extends
// T>> from(
// final Function<Iterable<S>, ? super T> /*
// * { T => Iterable<?
// * extends S> }
// */transform,
// final Function<Iterable<R>, ? super Iterable<? extends S>> selector) {
//
// return new Function<Iterable<R>, Iterable<? extends T>>() {
// public Iterable<R> invoke(Iterable<? extends T> t) throws Throwable {
// return selector.invoke(Query.selectMany(transform, t));
// }
// };
// }
//
// public static <T, S, R> Function<Iterable<R>, ? super Iterable<? extends
// T>> from1(
// final Function<Iterable<S>, ? super T> transform,
// final Function2<Iterable<R>, ? super Iterable<Join<T, S>>, Class<?>>
// selector) {
//
// return new Function<Iterable<R>, Iterable<? extends T>>() {
// public Iterable<R> invoke(Iterable<? extends T> t) throws Throwable {
// return selector.invoke(Query1.selectMany1(t, transform),
// Void.TYPE);
// }
// };
// }
//
// public static <T, Result> Iterable<Join<T, Result>> selectMany1(
// final Iterable<? extends T> t,
// final Function<Iterable<Result>, ? super T> transform) {
// return null;
// }
//
// /*
// * public static <T, S, R> { T, S => Iterable<R> } join({ T, S => boolean
// }
// * joinOn, { T, S => R } joinTo) { return null; }
// *
// * public static <T, S, R> { T, S => Iterable<Tuple2<T,S>> } join({ T, S
// =>
// * boolean } joinOn) { return null; }
// *
// * public static <T, S> Iterable<Tuple2<T,S>> join(Iterable<T> it,
// * Iterable<S> is, { T, S => boolean } joinOn) { return null; }
// *
// * public static <T, S, R> Iterable<R> from(Iterable<T> source1,
// Iterable<S>
// * source2, { T, S => boolean } joinOn, { T, S => Iterable<R> } selector)
// {
// * return null; }
// */
//
// // /*public*/ static <E> Iterable<E> where(final Iterable<? extends E>
// // source,
// // final { E => boolean } predicate) {
// // return null;
// // }
// public static <T, R> Function<Iterable<R>, ? super Iterable<? extends T>>
// where(
// final Function<Boolean, ? super T> p,
// final Function<Iterable<R>, ? super Iterable<? extends T>> selector) {
// // return { Iterable<? extends T> s => from(where(s, p), selector) };
// return new Function<Iterable<R>, Iterable<? extends T>>() {
// public Iterable<R> invoke(Iterable<? extends T> t) throws Throwable {
// return selector.invoke(Query.where(p, t));
// }
// };
// }
//
// public static <T, R> Function<Iterable<R>, ? super Iterable<? extends T>>
// orderBy(
// java.util.Comparator<T> c,
// Function<Iterable<R>, ? super Iterable<? extends T>> selector) {
// return null;
// }
// public static <T, Key, R> { T => Iterable<R> } orderBy(Comparator<T> c, {
// Group<Key, T> => Iterable<R> } selector) {
// return null;
// }
// public static <T, Key, R> Function<Iterable<R>, ? super Iterable<?
// extends T>> groupBy(
// Function<Key, ? super T> keySelector,
// Function<Iterable<R>, ? super Iterable<? extends Group<Key, T>>>
// selector) {
// return null;
// }
// /*public*/ static <T, R> Iterable<R> select(final Iterable<? extends T>
// source,
// final { T => R } transform) {
// return null;
// }
// public static <T, R> Function<Iterable<R>, ? super Iterable<? extends T>>
// select(
// final Function<R, ? super T> transform) {
// // return { Iterable<? extends T> s => select(s, transform) };
// return new Function<Iterable<R>, Iterable<? extends T>>() {
// public Iterable<R> invoke(Iterable<? extends T> t) throws Throwable {
// return Query.select(transform, t);
// }
// };
// }
//
// public static <T, S, R> Iterable<R> select(
// final Iterable<Join<T, S>> source,
// final Function2<R, ? super T, ? super S> transform) {
// return null;
// }
//
// public static <T, S, R> Function2<Iterable<R>, ? super Iterable<Join<T,
// S>>, Class<?>> select(
// final Function2<R, ? super T, ? super S> transform) {
// return new Function2<Iterable<R>, Iterable<Join<T, S>>, Class<?>>() {
// public Iterable<R> invoke(Iterable<Join<T, S>> t, Class<?> o)
// throws Throwable {
// return Query1.select(t, transform);
// }
// };
// }
// /*public*/ static <T> Iterable<T> skip(final Iterable<T> source, final
// int count) {
// return null;
// }
// public static <T, R> Function<Iterable<R>, ? super Iterable<? extends T>>
// skip(
// final int count,
// final Function<Iterable<R>, ? super Iterable<? extends T>> selector) {
// // return { Iterable<? extends T> s => from(skip(s, count), selector) };
// return new Function<Iterable<R>, Iterable<? extends T>>() {
// public Iterable<R> invoke(Iterable<? extends T> t) throws Throwable {
// return selector.invoke(Query.skip(count, t));
// }
// };
// }
}