package de.skuzzle.inject.async.internal.trigger;

import static com.google.common.base.Preconditions.checkArgument;

import java.lang.reflect.Method;
import java.util.ServiceLoader;
import java.util.concurrent.ScheduledExecutorService;

import javax.inject.Inject;

import com.cronutils.model.Cron;
import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;
import com.google.inject.Injector;

import de.skuzzle.inject.async.ExceptionHandler;
import de.skuzzle.inject.async.ScheduledContext;
import de.skuzzle.inject.async.TriggerStrategy;
import de.skuzzle.inject.async.annotation.CronTrigger;
import de.skuzzle.inject.async.annotation.CronType;
import de.skuzzle.inject.async.internal.TriggerStrategyRegistry;
import de.skuzzle.inject.async.internal.context.ContextFactory;
import de.skuzzle.inject.async.internal.runnables.Reschedulable;
import de.skuzzle.inject.async.internal.runnables.RunnableBuilder;
import de.skuzzle.inject.async.util.InjectedMethodInvocation;

/**
 * TriggerStrategy that handles the {@link CronTrigger} annotation.
 *
 * @author Simon Taddiken
 */
public class CronTriggerStrategy implements TriggerStrategy {

    @Inject
    private Injector injector;
    @Inject
    private RunnableBuilder runnableBuilder;
    @Inject
    private ContextFactory contextFactory;

    /**
     * Public constructor for being instantiated by the {@link ServiceLoader}. Supports
     * being used with the default {@link TriggerStrategyRegistry} which performs member
     * injection on all strategies that are loaded using the ServiceLoader.
     */
    public CronTriggerStrategy() {
    }

    @Override
    public Class<CronTrigger> getTriggerType() {
        return CronTrigger.class;
    }

    @Override
    public ScheduledContext schedule(Method method, Object self,
            ScheduledExecutorService executor,
            ExceptionHandler handler) {
        final CronTrigger trigger = method.getAnnotation(getTriggerType());
        checkArgument(trigger != null, "Method '%s' not annotated with @CronTrigger",
                method);

        final CronType cronType = trigger.cronType();
        final CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(
        		cronType.getType());
        final CronParser parser = new CronParser(cronDefinition);
        final Cron cron = parser.parse(trigger.value());
        final ExecutionTime execTime = ExecutionTime.forCron(cron);

        final InjectedMethodInvocation invocation = InjectedMethodInvocation
                .forMethod(method, self, this.injector);

        final ScheduledContext context = this.contextFactory.createContext(method);
        final Runnable runnable = this.runnableBuilder.createRunnableStack(invocation,
                context, handler);
        final Reschedulable rescheduleRunnable = this.runnableBuilder.reschedule(
                context,
                runnable,
                executor,
                execTime);

        rescheduleRunnable.scheduleNextExecution();
        return context;
    }
}

@@ -148,40 +148,8 @@
 od;%0A
-import java.util.ServiceLoader;%0A
 impo
@@ -198,16 +198,16 @@
 ervice;%0A
+
 %0Aimport 
@@ -756,73 +756,8 @@
 pe;%0A
-import de.skuzzle.inject.async.internal.TriggerStrategyRegistry;%0A
 impo
@@ -1339,319 +1339,8 @@
 y;%0A%0A
-    /**%0A     * Public constructor for being instantiated by the %7B@link ServiceLoader%7D. Supports%0A     * being used with the default %7B@link TriggerStrategyRegistry%7D which performs member%0A     * injection on all strategies that are loaded using the ServiceLoader.%0A     */%0A    public CronTriggerStrategy() %7B%0A    %7D%0A%0A
     
@@ -1950,10 +1950,16 @@
     
-%09%09
+        
 cron

Remove constructor