# TimelineSchedulerServiceMixin.java

    /*
     * Copyright (c) 2012, Niclas Hedhman. All Rights Reserved.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     *
     *     You may obtain a copy of the License at
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package org.qi4j.library.scheduler.timeline;

    import java.util.SortedSet;
    import java.util.TreeSet;
    import org.joda.time.DateTime;
    import org.qi4j.api.injection.scope.Service;
    import org.qi4j.api.injection.scope.Structure;
    import org.qi4j.api.service.ServiceComposite;
    import org.qi4j.api.structure.Module;
    import org.qi4j.api.unitofwork.UnitOfWork;
    import org.qi4j.functional.Iterables;
    import org.qi4j.library.scheduler.SchedulerMixin;
    import org.qi4j.library.scheduler.SchedulerService;
    import org.qi4j.library.scheduler.schedule.Schedule;
    import org.qi4j.library.scheduler.schedule.Schedules;

    /**
     * WARN TimelineService Mixin use SortedSets to keep records ordered and repeatedly search for the next run.
     * Could be greedy with large intervals
     */
    public abstract class TimelineSchedulerServiceMixin
        implements Timeline, ServiceComposite
    {
        @Structure
        private Module module;

        @Service
        private SchedulerService scheduler;

        @Override
        public Iterable<TimelineRecord> getLastRecords( int maxResults )
        {
            SortedSet<TimelineRecord> result = new TreeSet<>();

            UnitOfWork uow = module.currentUnitOfWork();
            String schedulesName = SchedulerMixin.getSchedulesIdentity( scheduler );
            Schedules schedules = uow.get( Schedules.class, schedulesName );
            for( Schedule schedule : schedules.schedules() )
            {
                Timeline timeline = (Timeline) schedule;
                Iterable<TimelineRecord> lastRecords = timeline.getLastRecords( maxResults );
                Iterables.addAll( result, lastRecords );
            }
            return Iterables.limit( maxResults, Iterables.reverse( result ) );
        }

        @Override
        public Iterable<TimelineRecord> getNextRecords( int maxResults )
        {
            SortedSet<TimelineRecord> result = new TreeSet<>();
            UnitOfWork uow = module.currentUnitOfWork();
            String schedulesName = SchedulerMixin.getSchedulesIdentity( scheduler );
            Schedules schedules = uow.get( Schedules.class, schedulesName );
            for( Schedule schedule : schedules.schedules() )
            {
                Timeline timeline = (Timeline) schedule;
                Iterable<TimelineRecord> lastRecords = timeline.getNextRecords( maxResults );
                Iterables.addAll( result, lastRecords );
            }
            return Iterables.limit( maxResults, result );
        }

        @Override
        public Iterable<TimelineRecord> getRecords( DateTime from, DateTime to )
        {
            SortedSet<TimelineRecord> result = new TreeSet<>();

            UnitOfWork uow = module.currentUnitOfWork();
            String schedulesName = SchedulerMixin.getSchedulesIdentity( scheduler );
            Schedules schedules = uow.get( Schedules.class, schedulesName );
            for( Schedule schedule : schedules.schedules() )
            {
                Timeline timeline = (Timeline) schedule;
                Iterable<TimelineRecord> lastRecords = timeline.getRecords( from, to );
                Iterables.addAll( result, lastRecords );
            }
            return result;
        }

        @Override
        public Iterable<TimelineRecord> getRecords( long from, long to )
        {
            SortedSet<TimelineRecord> result = new TreeSet<>();

            UnitOfWork uow = module.currentUnitOfWork();
            String schedulesName = SchedulerMixin.getSchedulesIdentity( scheduler );
            Schedules schedules = uow.get( Schedules.class, schedulesName );
            for( Schedule schedule : schedules.schedules() )
            {
                Timeline timeline = (Timeline) schedule;
                Iterable<TimelineRecord> lastRecords = timeline.getRecords( from, to );
                Iterables.addAll( result, lastRecords );
            }
            return result;
        }
    }