package org.qi4j.library.framework;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.qi4j.composite.AppliesTo;
import org.qi4j.composite.AppliesToFilter;
import org.qi4j.composite.scope.Entity;
import org.qi4j.query.QueryBuilder;
import org.qi4j.query.QueryBuilderFactory;
import static org.qi4j.query.QueryExpression.eq;

/**
 * Generic finder mixin.
 * <p/>
 * This mixin will be applied to all methods with names matching "findBy*".
 * The part after "findBy" will be interpreted and converted to a QueryBuilder.
 */
@AppliesTo( FinderMixin.AppliesTo.class )
public class FinderMixin
    implements InvocationHandler
{
    public static class AppliesTo
        implements AppliesToFilter
    {
        public boolean appliesTo( Method method, Class compositeType, Class mixin, Class modelClass )
        {
            String name = method.getName();
            if( name.startsWith( "findBy" ) )
            {
                return true;
            }

            return false;
        }
    }

    // Attributes ----------------------------------------------------
    @Entity( "someQuery" ) QueryBuilderFactory factory;

    // InvocationHandler implementation ------------------------------
    public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
    {
        // Build query
        String methodName = method.getName();

        Class resultType = method.getReturnType();

        QueryBuilder builder = factory.newQueryBuilder( resultType );

        // Remove "findBy"
        methodName = methodName.substring( 6 );

        Object param = builder.parameter( resultType );

        Method getter = param.getClass().getMethod( "get" + methodName );

        builder = builder.where( eq( getter.invoke( param ), args[ 0 ] ) );

        // Execute query
        return builder.newQuery().find();
    }

}

@@ -240,32 +240,40 @@
 t org.qi4j.query
+obsolete
 .QueryBuilder;%0Ai
@@ -288,24 +288,32 @@
 g.qi4j.query
+obsolete
 .QueryBuilde
@@ -350,16 +350,24 @@
 4j.query
+obsolete
 .QueryEx
@@ -1368,24 +1368,32 @@
  Build query
+obsolete
 %0A        Str
@@ -1860,16 +1860,24 @@
 te query
+obsolete
 %0A       

Deprecate query api.