Ejemplo n.º 1
0
 public bool TryMerge(ref IScheduleElem sourceNode, ref IScheduleElem targetNode)
 {
     if (sourceNode.Level == targetNode.Level)
     {
         return(GetStrategy(targetNode.Level)
                .TryRootToRootMerge(sourceNode, targetNode, TryMerge));
     }
     else
     {
         if (Math.Abs(sourceNode.Level - targetNode.Level) > 2 &&
             targetNode.Level != ScheduleElemLevel.Undefined)
         {
             throw new ScheduleConstructorException("wrong schedule trees");
         }
         //sourceNode.Level == Day and targetNode.Level == Week case f.e.
         if (sourceNode.Level > targetNode.Level)
         {
             GetStrategy(targetNode.Level).ChildToParent(ref sourceNode, ref targetNode, TryMerge);
             return(true);
         }
         else
         {
             GetStrategy(targetNode.Level).ParentToChild(ref sourceNode, ref targetNode, TryMerge);
             return(true);
         }
     }
 }
        public Task <bool> UpdateScheduleAsync(IScheduleGroup targetGroup, IScheduleElem scheduleRoot)
        {
            return(Task.Factory.StartNew(() =>
            {
                try
                {
                    string key = KeyFromGroup(targetGroup);
                    storage.AddOrUpdate(key,
                                        //if new key
                                        keyS =>
                    {
                        switch (scheduleRoot.Level)
                        {
                        case ScheduleElemLevel.Week:
                            return ((IScheduleElem)scheduleRoot.Clone()).Elems;

                        case ScheduleElemLevel.Day:
                            return new List <IScheduleElem>()
                            {
                                scheduleRoot
                            };

                        default:
                            throw new ArgumentOutOfRangeException(
                                $"Db cannot add root with level {scheduleRoot.Level.ToString()}");
                        }
                    },
                                        //if already exists
                                        (keyS, days) =>
                    {
                        switch (scheduleRoot.Level)
                        {
                        case ScheduleElemLevel.Week:
                            return ((IScheduleElem)scheduleRoot.Clone()).Elems;

                        case ScheduleElemLevel.Day:
                            var casted = (Day)scheduleRoot;
                            var toUpd = days.OfType <Day>().FirstOrDefault(d => d.DayOfWeek == casted.DayOfWeek);
                            if (toUpd != null)
                            {
                                days.Remove(toUpd);
                            }
                            days.Add((IScheduleElem)casted.Clone());
                            return days;

                        default:
                            throw new ArgumentOutOfRangeException(
                                $"Db cannot update root with level {scheduleRoot.Level.ToString()}");
                        }
                    });
                    return true;
                }
                catch (ArgumentOutOfRangeException e)
                {
                    //todo: logger
                    return false;
                }
            }));
        }
Ejemplo n.º 3
0
        private IScheduleElem AddToCommonParent(IScheduleElem sourceNode, IScheduleElem targetNode)
        {
            var res = CreateDefault(targetNode.Level - 1);

            res.Elems.Add(sourceNode);
            res.Elems.Add(targetNode);
            return(res);
        }
Ejemplo n.º 4
0
 public void Merge(ref IScheduleElem sourceNode, ref IScheduleElem targetNode)
 {
     if (!TryMerge(ref sourceNode, ref targetNode))
     {
         IScheduleElem commonParent = AddToCommonParent(sourceNode, targetNode);
         targetNode = commonParent;
     }
 }
Ejemplo n.º 5
0
 public bool Equals(IScheduleElem obj)
 {
     if (obj.GetType() != this.GetType())
     {
         return(false);
     }
     return(Equals((Lesson)obj));
 }
Ejemplo n.º 6
0
 public bool Equals(IScheduleElem other)
 {
     if (other.GetType() != this.GetType())
     {
         return(false);
     }
     return(Equals((Week)other));
 }
Ejemplo n.º 7
0
 protected void Visit(IScheduleElem elem)
 {
     if (elem?.Elems != null)
     {
         foreach (var scheduleElem in elem.Elems)
         {
             VisitElem(scheduleElem);
         }
     }
 }
Ejemplo n.º 8
0
 public EventArgs GetArgs(IScheduleElem schedule)
 {
     if (schedule is Day day)
     {
         return(new ParamEventArgs <DayOfWeek>()
         {
             Param = day.DayOfWeek
         });
     }
     return(EventArgs.Empty);
 }
Ejemplo n.º 9
0
        public override bool TryRootToRootMerge(IScheduleElem source, IScheduleElem target,
                                                ReccurentStep recurrentStep)
        {
            if (source == null || source.Elems == null || !source.Elems.Any())
            {
                return(true);
            }

            var sourceDay = (Day)source;
            var targetDay = (Day)target;

            if (sourceDay.DayOfWeek != targetDay.DayOfWeek)
            {
                return(false);
            }

            if (targetDay.Elems == null || !targetDay.Elems.Any())
            {
                targetDay.Elems = sourceDay.Elems;
                return(true);
            }


            targetDay.Elems = targetDay.Elems.Union(sourceDay.Elems).Cast <Lesson>().OrderBy(elem => elem.BeginTime)
                              .ToList <IScheduleElem>();
            Lesson prev = null;

            foreach (var lesson in targetDay.Elems.Cast <Lesson>())
            {
                if (prev == null)
                {
                    prev = lesson;
                    continue;
                }

                if (lesson.BeginTime <= prev.BeginTime &&
                    (lesson.IsOnEvenWeek == null || prev.IsOnEvenWeek == null ||
                     prev.IsOnEvenWeek == lesson.IsOnEvenWeek))
                {
                    //throw new ScheduleConstructorException(
                    //todo: throw exc!!!!!
                    logger?.LogError(String.Format(
                                         "Day's lessons merge exception: time intersects: {0}, {1}", JsonConvert.SerializeObject(prev),
                                         JsonConvert.SerializeObject(lesson)));
                }
            }

            return(true);
        }
Ejemplo n.º 10
0
        public override void ChildToParent(ref IScheduleElem sourceChild, ref IScheduleElem targetParent,
                                           ReccurentStep recurrentStep)
        {
            if (sourceChild == null)
            {
                return;
            }

            if (targetParent == null)
            {
                throw new ArgumentNullException("target branch is null");
            }
            if (targetParent.Elems == null)
            {
                targetParent.Elems = new List <IScheduleElem>();
            }
            if (!targetParent.Elems.Any())
            {
                targetParent.Elems.Add(sourceChild);
            }
            else
            {
                var sourceDay  = (Day)sourceChild;
                var days       = targetParent.Elems.Cast <Day>().ToList();
                var commonDays = days.Count(diw => diw.DayOfWeek == sourceDay.DayOfWeek);
                if (commonDays > 1)
                {
                    throw new ScheduleConstructorException("Several same day's of week");
                }
                if (commonDays == 1)
                {
                    IScheduleElem common = days.FirstOrDefault(diw => diw.DayOfWeek == sourceDay.DayOfWeek);
                    //swap target and source to save all into week branch
                    //todo: remove get strategy!!!!!
                    if (!recurrentStep.Invoke(ref sourceChild, ref common))
                    {
                        throw new ArgumentException(String.Format("Bad arguments: {0}, {1}",
                                                                  JsonConvert.SerializeObject(sourceChild), JsonConvert.SerializeObject(common)));
                    }
                }
                else
                {
                    targetParent.Elems.Add(sourceDay);
                }
            }
        }
Ejemplo n.º 11
0
        public override bool TryRootToRootMerge(IScheduleElem source, IScheduleElem target,
                                                ReccurentStep recurrentStep)
        {
            if (source == null || source.Elems == null || !source.Elems.Any())
            {
                return(true);
            }

            var sourceWeek = (Week)source;
            var targetWeek = (Week)target;

            if (targetWeek.Elems == null || !targetWeek.Elems.Any())
            {
                targetWeek.Elems = sourceWeek.Elems;
                return(true);
            }


            targetWeek.Elems = targetWeek.Elems.Concat(sourceWeek.Elems).GroupBy(elem => ((Day)elem).DayOfWeek,
                                                                                 (dayOfWeek, elems) =>
            {
                var count = elems.Count();
                if (count > 2)
                {
                    throw new ScheduleConstructorException("Several same day's of week");
                }
                if (count == 1)
                {
                    return(elems.First());
                }
                var first = elems.First();
                //next step merge
                var second = elems.ElementAt(1);
                if (!recurrentStep.Invoke(ref second, ref first))
                {
                    throw new ArgumentException(String.Format("Bad arguments: {0}, {1}",
                                                              JsonConvert.SerializeObject(second), JsonConvert.SerializeObject(first)));
                }
                return(first);
            }).ToList();
            return(true);
        }
Ejemplo n.º 12
0
        public override void ParentToChild(ref IScheduleElem sourceParent, ref IScheduleElem targetChild,
                                           ReccurentStep recurrentStep)
        {
            if (sourceParent == null || sourceParent.Elems == null)
            {
                //todo: init elems by list
                throw new ArgumentOutOfRangeException(
                          "source parent cannot be null and should have initialized collection");
            }

            //var sourceWeek = (Week) sourceParent;
            var targetDay  = (Day)targetChild;
            var days       = sourceParent.Elems.Cast <Day>().ToList();
            var commonDays = days.Count(diw => diw.DayOfWeek == targetDay.DayOfWeek);

            if (commonDays > 1)
            {
                throw new ScheduleConstructorException("Several same day's of week");
            }
            if (commonDays == 1)
            {
                IScheduleElem common = days.FirstOrDefault(diw => diw.DayOfWeek == targetDay.DayOfWeek);
                //swap target and source to save all into week branch
                if (!recurrentStep.Invoke(ref targetChild, ref common))
                {
                    throw new ArgumentException(String.Format("Bad arguments: {0}, {1}",
                                                              JsonConvert.SerializeObject(sourceParent), JsonConvert.SerializeObject(common)));
                }
            }
            else
            {
                sourceParent.Elems.Add(targetDay);
            }

            targetChild = sourceParent;
        }
Ejemplo n.º 13
0
        public static IScheduleElem OrderChildrenByDefault(this IScheduleElem scheduleElem)
        {
            switch (scheduleElem.Level)
            {
            case ScheduleElemLevel.Week:
                scheduleElem.Elems = scheduleElem.Elems.Select(d => d.OrderChildrenByDefault()).Cast <Day>()
                                     .OrderBy(d => d.DayOfWeek).Cast <IScheduleElem>().ToList();
                break;

            case ScheduleElemLevel.Day:
                scheduleElem.Elems = scheduleElem.Elems.Cast <Lesson>().OrderBy(l => l.BeginTime)
                                     .Cast <IScheduleElem>().ToList();
                break;

            case ScheduleElemLevel.Undefined:
                break;

            default:
                throw new ArgumentOutOfRangeException("scheduleElem",
                                                      $"Impossible to order children for such level {scheduleElem.Level}");
            }

            return(scheduleElem);
        }
Ejemplo n.º 14
0
        public void VisitElem(IScheduleElem elem)
        {
            dynamic @dynamic = elem;

            Visit(@dynamic);
        }
Ejemplo n.º 15
0
 public override bool TryRootToRootMerge(IScheduleElem source, IScheduleElem target, ReccurentStep recurrentStep)
 {
     //no body
     return(true);
 }
Ejemplo n.º 16
0
 public override void ChildToParent(ref IScheduleElem sourceChild, ref IScheduleElem targetParent, ReccurentStep recurrentStep)
 {
     targetParent = sourceChild;
 }
Ejemplo n.º 17
0
 public bool Equals(IScheduleElem obj)
 {
     return(Equals((object)obj));
 }
Ejemplo n.º 18
0
        public static CheckResult CheckElemIsCorrect(this IScheduleElem scheduleElem)
        {
            var res = new CheckResult();

            if (scheduleElem == null)
            {
                return(res.AddError("Null schedule elem"));
            }
            try
            {
                switch (scheduleElem.Level)
                {
                case ScheduleElemLevel.Week:
                    if (!(scheduleElem is Week))
                    {
                        res.AddError($"level week is not week level {scheduleElem.Level}, type: {scheduleElem.GetType()}");
                    }
                    if (scheduleElem.Elems == null)
                    {
                        res.AddError("null children: " + JsonConvert.SerializeObject(scheduleElem));
                    }
                    else
                    {
                        res = scheduleElem.Elems?.Aggregate(res,
                                                            (result, elem) => result + CheckElemIsCorrect(elem)) ?? res;
                        var nonUniqueDays = scheduleElem.Elems?.OfType <Day>()?.GroupBy(d => d.DayOfWeek)
                                            ?.FirstOrDefault(group => @group.Count() > 1);
                        if (nonUniqueDays != null)
                        {
                            res.AddError($"not unique days in week: {nonUniqueDays.Key}");
                        }
                    }

                    break;

                case ScheduleElemLevel.Day:
                    if (!(scheduleElem is Day))
                    {
                        res.AddError($"level day is not day: level {scheduleElem.Level}, type: {scheduleElem.GetType()}");
                    }
                    else
                    {
                        var day = (Day)scheduleElem;
                        if (day.DayOfWeek > DayOfWeek.Saturday || day.DayOfWeek < DayOfWeek.Sunday)
                        {
                            res.AddError($"unknown dayofweek: {day.DayOfWeek}");
                        }
                    }

                    if (scheduleElem.Elems == null)
                    {
                        res.AddError("null children: " + JsonConvert.SerializeObject(scheduleElem));
                    }
                    else
                    {
                        res = scheduleElem.Elems?.Aggregate(res,
                                                            (result, elem) => result + CheckElemIsCorrect(elem)) ?? res;
                        scheduleElem.Elems?.OfType <Lesson>()?.OrderBy(l => l.BeginTime).Aggregate((prev, current) =>
                        {
                            if (current.BeginTime <= prev.BeginTime &&
                                (current.IsOnEvenWeek == null || prev.IsOnEvenWeek == null ||
                                 prev.IsOnEvenWeek == current.IsOnEvenWeek))
                            {
                                res.AddError($"incompatible lessons in day {((Day)scheduleElem).DayOfWeek}:" +
                                             JsonConvert.SerializeObject(prev) +
                                             JsonConvert.SerializeObject(current));
                            }
                            return(current);
                        });
                    }

                    break;

                case ScheduleElemLevel.Lesson:
                    if (!(scheduleElem is Lesson))
                    {
                        res.AddError("level lesson is not lesson" + JsonConvert.SerializeObject(scheduleElem));
                    }
                    if (scheduleElem.Elems != null)
                    {
                        res.AddError("not null children for lesson: " +
                                     JsonConvert.SerializeObject(scheduleElem));
                    }

                    break;

                default:
                    res.AddError($"Impossible to check for such level {scheduleElem.Level}");
                    break;
                }

                return(res);
            }
            catch (Exception e)
            {
                return(res.AddExeption(e));
            }
        }
Ejemplo n.º 19
0
 public abstract void ChildToParent(ref IScheduleElem sourceChild, ref IScheduleElem targetParent,
                                    ReccurentStep recurrentStep);
Ejemplo n.º 20
0
 public abstract void ParentToChild(ref IScheduleElem sourceParent, ref IScheduleElem targetChild,
                                    ReccurentStep recurrentStep);
Ejemplo n.º 21
0
 public abstract bool TryRootToRootMerge(IScheduleElem source, IScheduleElem target,
                                         ReccurentStep recurrentStep);
Ejemplo n.º 22
0
 public override void ParentToChild(ref IScheduleElem sourceParent, ref IScheduleElem targetChild,
                                    ReccurentStep recurrentStep)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 23
0
 public override void ChildToParent(ref IScheduleElem sourceChild, ref IScheduleElem targetParent,
                                    ReccurentStep recurrentStep)
 {
     throw new NotImplementedException();
 }