Пример #1
0
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            switch (reader.LocalName)
            {
            case XmlElementNames.Periods:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Period))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromXml(reader);

                        this.periods.Add(period.Id, period);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Periods));

                return(true);

            case XmlElementNames.TransitionsGroups:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.TransitionsGroup))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);

                        transitionGroup.LoadFromXml(reader);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.TransitionsGroups));

                return(true);

            case XmlElementNames.Transitions:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement())
                    {
                        TimeZoneTransition transition = TimeZoneTransition.Create(this, reader.LocalName);

                        transition.LoadFromXml(reader);

                        this.transitions.Add(transition);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Transitions));

                return(true);

            default:
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// Adds a transition group with a single transition to the specified period.
        /// </summary>
        /// <param name="timeZonePeriod">The time zone period.</param>
        /// <returns>A TimeZoneTransitionGroup.</returns>
        private TimeZoneTransitionGroup CreateTransitionGroupToPeriod(TimeZonePeriod timeZonePeriod)
        {
            TimeZoneTransition transitionToPeriod = new TimeZoneTransition(this, timeZonePeriod);

            TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());

            transitionGroup.Transitions.Add(transitionToPeriod);

            this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

            return(transitionGroup);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="AbsoluteDateTransition"/> class.
 /// </summary>
 /// <param name="timeZoneDefinition">The time zone definition the transition will belong to.</param>
 /// <param name="targetGroup">The transition group the transition will target.</param>
 internal AbsoluteDateTransition(TimeZoneDefinition timeZoneDefinition, TimeZoneTransitionGroup targetGroup)
     : base(timeZoneDefinition, targetGroup)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TimeZoneTransition"/> class.
 /// </summary>
 /// <param name="timeZoneDefinition">The time zone definition the transition will belong to.</param>
 /// <param name="targetGroup">The transition group the transition will target.</param>
 internal TimeZoneTransition(TimeZoneDefinition timeZoneDefinition, TimeZoneTransitionGroup targetGroup)
     : this(timeZoneDefinition)
 {
     this.targetGroup = targetGroup;
 }
Пример #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AbsoluteDateTransition"/> class.
 /// </summary>
 /// <param name="timeZoneDefinition">The time zone definition the transition will belong to.</param>
 /// <param name="targetGroup">The transition group the transition will target.</param>
 internal AbsoluteDateTransition(TimeZoneDefinition timeZoneDefinition, TimeZoneTransitionGroup targetGroup)
     : base(timeZoneDefinition, targetGroup)
 {
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeZoneDefinition"/> class.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info used to initialize this definition.</param>
        internal TimeZoneDefinition(TimeZoneInfo timeZoneInfo)
            : this()
        {
            this.Id = timeZoneInfo.Id;
            this.Name = timeZoneInfo.DisplayName;

            // TimeZoneInfo only supports one standard period, which bias is the time zone's base
            // offset to UTC.
            TimeZonePeriod standardPeriod = new TimeZonePeriod();
            standardPeriod.Id = TimeZonePeriod.StandardPeriodId;
            standardPeriod.Name = TimeZonePeriod.StandardPeriodName;
            standardPeriod.Bias = -timeZoneInfo.BaseUtcOffset;
            
            TimeZoneInfo.AdjustmentRule[] adjustmentRules = timeZoneInfo.GetAdjustmentRules();

            TimeZoneTransition transitionToStandardPeriod = new TimeZoneTransition(this, standardPeriod);

            if (adjustmentRules.Length == 0)
            {
                this.periods.Add(standardPeriod.Id, standardPeriod);

                // If the time zone info doesn't support Daylight Saving Time, we just need to
                // create one transition to one group with one transition to the standard period.
                TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, "0");
                transitionGroup.Transitions.Add(transitionToStandardPeriod);

                this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                TimeZoneTransition initialTransition = new TimeZoneTransition(this, transitionGroup);

                this.transitions.Add(initialTransition);
            }
            else
            {
                for (int i = 0; i < adjustmentRules.Length; i++)
                {
                    TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());
                    transitionGroup.InitializeFromAdjustmentRule(adjustmentRules[i], standardPeriod);

                    this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                    TimeZoneTransition transition;

                    if (i == 0)
                    {
                        // If the first adjustment rule's start date in not undefined (DateTime.MinValue)
                        // we need to add a dummy group with a single, simple transition to the Standard
                        // period and a group containing the transitions mapping to the adjustment rule.
                        if (adjustmentRules[i].DateStart > DateTime.MinValue.Date)
                        {
                            TimeZoneTransition transitionToDummyGroup = new TimeZoneTransition(
                                this,
                                this.CreateTransitionGroupToPeriod(standardPeriod));

                            this.transitions.Add(transitionToDummyGroup);

                            AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                            absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                            transition = absoluteDateTransition;
                            this.periods.Add(standardPeriod.Id, standardPeriod);
                        }
                        else
                        {
                            transition = new TimeZoneTransition(this, transitionGroup);
                        }
                    }
                    else
                    {
                        AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                        absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                        transition = absoluteDateTransition;
                    }

                    this.transitions.Add(transition);
                }

                // If the last adjustment rule's end date is not undefined (DateTime.MaxValue),
                // we need to create another absolute date transition that occurs the date after
                // the last rule's end date. We target this additional transition to a group that
                // contains a single simple transition to the Standard period.
                DateTime lastAdjustmentRuleEndDate = adjustmentRules[adjustmentRules.Length - 1].DateEnd;

                if (lastAdjustmentRuleEndDate < DateTime.MaxValue.Date)
                {
                    AbsoluteDateTransition transitionToDummyGroup = new AbsoluteDateTransition(
                        this,
                        this.CreateTransitionGroupToPeriod(standardPeriod));
                    transitionToDummyGroup.DateTime = lastAdjustmentRuleEndDate.AddDays(1);

                    this.transitions.Add(transitionToDummyGroup);
                }
            }
        }
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            switch (reader.LocalName)
            {
                case XmlElementNames.Periods:
                    do
                    {
                        reader.Read();

                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Period))
                        {
                            TimeZonePeriod period = new TimeZonePeriod();
                            period.LoadFromXml(reader);

                            // OM:1648848 Bad timezone data from clients can include duplicate rules
                            // for one year, with duplicate ID. In that case, let the first one win.
                            if (!this.periods.ContainsKey(period.Id))
                            {
                                this.periods.Add(period.Id, period);
                            }
                            else
                            {
                                reader.Service.TraceMessage(
                                    TraceFlags.EwsTimeZones,
                                    string.Format(
                                        "An entry with the same key (Id) '{0}' already exists in Periods. Cannot add another one. Existing entry: [Name='{1}', Bias='{2}']. Entry to skip: [Name='{3}', Bias='{4}'].",
                                        period.Id,
                                        this.Periods[period.Id].Name,
                                        this.Periods[period.Id].Bias,
                                        period.Name,
                                        period.Bias));
                            }
                        }
                    }
                    while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Periods));

                    return true;
                case XmlElementNames.TransitionsGroups:
                    do
                    {
                        reader.Read();

                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.TransitionsGroup))
                        {
                            TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);

                            transitionGroup.LoadFromXml(reader);

                            this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                        }
                    }
                    while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.TransitionsGroups));

                    return true;
                case XmlElementNames.Transitions:
                    do
                    {
                        reader.Read();

                        if (reader.IsStartElement())
                        {
                            TimeZoneTransition transition = TimeZoneTransition.Create(this, reader.LocalName);

                            transition.LoadFromXml(reader);

                            this.transitions.Add(transition);
                        }
                    }
                    while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Transitions));

                    return true;
                default:
                    return false;
            }
        }
        /// <summary>
        /// Adds a transition group with a single transition to the specified period.
        /// </summary>
        /// <param name="timeZonePeriod">The time zone period.</param>
        /// <returns>A TimeZoneTransitionGroup.</returns>
        private TimeZoneTransitionGroup CreateTransitionGroupToPeriod(TimeZonePeriod timeZonePeriod)
        {
            TimeZoneTransition transitionToPeriod = new TimeZoneTransition(this, timeZonePeriod);

            TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());
            transitionGroup.Transitions.Add(transitionToPeriod);

            this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

            return transitionGroup;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="TimeZoneTransition"/> class.
 /// </summary>
 /// <param name="timeZoneDefinition">The time zone definition the transition will belong to.</param>
 /// <param name="targetGroup">The transition group the transition will target.</param>
 internal TimeZoneTransition(TimeZoneDefinition timeZoneDefinition, TimeZoneTransitionGroup targetGroup)
     : this(timeZoneDefinition)
 {
     this.targetGroup = targetGroup;
 }
Пример #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeZoneDefinition"/> class.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info used to initialize this definition.</param>
        internal TimeZoneDefinition(TimeZoneInfo timeZoneInfo)
            : this()
        {
            this.Id   = timeZoneInfo.Id;
            this.Name = timeZoneInfo.DisplayName;

            // TimeZoneInfo only supports one standard period, which bias is the time zone's base
            // offset to UTC.
            TimeZonePeriod standardPeriod = new TimeZonePeriod();

            standardPeriod.Id   = TimeZonePeriod.StandardPeriodId;
            standardPeriod.Name = TimeZonePeriod.StandardPeriodName;
            standardPeriod.Bias = -timeZoneInfo.BaseUtcOffset;

            this.periods.Add(standardPeriod.Id, standardPeriod);

            TimeZoneInfo.AdjustmentRule[] adjustmentRules = timeZoneInfo.GetAdjustmentRules();

            TimeZoneTransition transitionToStandardPeriod = new TimeZoneTransition(this, standardPeriod);

            if (adjustmentRules.Length == 0)
            {
                // If the time zone info doesn't support Daylight Saving Time, we just need to
                // create one transition to one group with one transition to the standard period.
                TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, "0");
                transitionGroup.Transitions.Add(transitionToStandardPeriod);

                this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                TimeZoneTransition initialTransition = new TimeZoneTransition(this, transitionGroup);

                this.transitions.Add(initialTransition);
            }
            else
            {
                for (int i = 0; i < adjustmentRules.Length; i++)
                {
                    TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());
                    transitionGroup.InitializeFromAdjustmentRule(adjustmentRules[i], standardPeriod);

                    this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                    TimeZoneTransition transition;

                    if (i == 0)
                    {
                        // If the first adjustment rule's start date in not undefined (DateTime.MinValue)
                        // we need to add a dummy group with a single, simple transition to the Standard
                        // period and a group containing the transitions mapping to the adjustment rule.
                        if (adjustmentRules[i].DateStart > DateTime.MinValue.Date)
                        {
                            TimeZoneTransition transitionToDummyGroup = new TimeZoneTransition(
                                this,
                                this.CreateTransitionGroupToPeriod(standardPeriod));

                            this.transitions.Add(transitionToDummyGroup);

                            AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                            absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                            transition = absoluteDateTransition;
                        }
                        else
                        {
                            transition = new TimeZoneTransition(this, transitionGroup);
                        }
                    }
                    else
                    {
                        AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                        absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                        transition = absoluteDateTransition;
                    }

                    this.transitions.Add(transition);
                }

                // If the last adjustment rule's end date is not undefined (DateTime.MaxValue),
                // we need to create another absolute date transition that occurs the date after
                // the last rule's end date. We target this additional transition to a group that
                // contains a single simple transition to the Standard period.
                DateTime lastAdjustmentRuleEndDate = adjustmentRules[adjustmentRules.Length - 1].DateEnd;

                if (lastAdjustmentRuleEndDate < DateTime.MaxValue.Date)
                {
                    AbsoluteDateTransition transitionToDummyGroup = new AbsoluteDateTransition(
                        this,
                        this.CreateTransitionGroupToPeriod(standardPeriod));
                    transitionToDummyGroup.DateTime = lastAdjustmentRuleEndDate.AddDays(1);

                    this.transitions.Add(transitionToDummyGroup);
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Loads from json.
        /// </summary>
        /// <param name="jsonProperty">The json property.</param>
        /// <param name="service">The service.</param>
        internal override void LoadFromJson(JsonObject jsonProperty, ExchangeService service)
        {
            base.LoadFromJson(jsonProperty, service);

            foreach (string key in jsonProperty.Keys)
            {
                switch (key)
                {
                case XmlAttributeNames.Name:
                    this.name = jsonProperty.ReadAsString(key);
                    break;

                case XmlAttributeNames.Id:
                    this.id = jsonProperty.ReadAsString(key);
                    break;

                case XmlElementNames.Periods:
                    foreach (object jsonPeriod in jsonProperty.ReadAsArray(key))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromJson(jsonPeriod as JsonObject, service);

                        this.periods.Add(period.Id, period);
                    }

                    break;

                case XmlElementNames.TransitionsGroups:
                    foreach (object arrayOfTransitionsTypeInstance in jsonProperty.ReadAsArray(key))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);
                        transitionGroup.LoadFromJson(arrayOfTransitionsTypeInstance as JsonObject, service);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }

                    break;

                case XmlElementNames.Transitions:
                    JsonObject arrayOfTransitionsType = jsonProperty.ReadAsJsonObject(key);

                    foreach (object uncastJsonTransition in arrayOfTransitionsType.ReadAsArray(XmlElementNames.Transition))
                    {
                        JsonObject         jsonTransition = uncastJsonTransition as JsonObject;
                        TimeZoneTransition transition     = TimeZoneTransition.Create(this, jsonTransition.ReadTypeString());

                        transition.LoadFromJson(jsonTransition, service);

                        this.transitions.Add(transition);
                    }

                    break;

                default:
                    break;
                }
            }

            // EWS can return a TimeZone definition with no Id. Generate a new Id in this case.
            if (string.IsNullOrEmpty(this.id))
            {
                string nameValue = string.IsNullOrEmpty(this.Name) ? string.Empty : this.Name;
                this.Id = NoIdPrefix + Math.Abs(nameValue.GetHashCode()).ToString();
            }

            this.transitions.Sort(this.CompareTransitions);
        }
Пример #12
0
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            switch (reader.LocalName)
            {
            case XmlElementNames.Periods:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Period))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromXml(reader);

                        // OM:1648848 Bad timezone data from clients can include duplicate rules
                        // for one year, with duplicate ID. In that case, let the first one win.
                        if (!this.periods.ContainsKey(period.Id))
                        {
                            this.periods.Add(period.Id, period);
                        }
                        else
                        {
                            reader.Service.TraceMessage(
                                TraceFlags.EwsTimeZones,
                                string.Format(
                                    "An entry with the same key (Id) '{0}' already exists in Periods. Cannot add another one. Existing entry: [Name='{1}', Bias='{2}']. Entry to skip: [Name='{3}', Bias='{4}'].",
                                    period.Id,
                                    this.Periods[period.Id].Name,
                                    this.Periods[period.Id].Bias,
                                    period.Name,
                                    period.Bias));
                        }
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Periods));

                return(true);

            case XmlElementNames.TransitionsGroups:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.TransitionsGroup))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);

                        transitionGroup.LoadFromXml(reader);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.TransitionsGroups));

                return(true);

            case XmlElementNames.Transitions:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement())
                    {
                        TimeZoneTransition transition = TimeZoneTransition.Create(this, reader.LocalName);

                        transition.LoadFromXml(reader);

                        this.transitions.Add(transition);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Transitions));

                return(true);

            default:
                return(false);
            }
        }
Пример #13
0
        /// <summary>
        /// Loads from json.
        /// </summary>
        /// <param name="jsonProperty">The json property.</param>
        /// <param name="service">The service.</param>
        internal override void LoadFromJson(JsonObject jsonProperty, ExchangeService service)
        {
            base.LoadFromJson(jsonProperty, service);

            foreach (string key in jsonProperty.Keys)
            {
                switch (key)
                {
                case XmlAttributeNames.Name:
                    this.name = jsonProperty.ReadAsString(key);
                    break;

                case XmlAttributeNames.Id:
                    this.id = jsonProperty.ReadAsString(key);
                    break;

                case XmlElementNames.Periods:
                    foreach (object jsonPeriod in jsonProperty.ReadAsArray(key))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromJson(jsonPeriod as JsonObject, service);

                        // OM:1648848 Bad timezone data from clients can include duplicate rules
                        // for one year, with duplicate ID. In that case, let the first one win.
                        if (!this.periods.ContainsKey(period.Id))
                        {
                            this.periods.Add(period.Id, period);
                        }
                        else
                        {
                            service.TraceMessage(
                                TraceFlags.EwsTimeZones,
                                string.Format(
                                    "An entry with the same key (Id) '{0}' already exists in Periods. Cannot add another one. Existing entry: [Name='{1}', Bias='{2}']. Entry to skip: [Name='{3}', Bias='{4}'].",
                                    period.Id,
                                    this.Periods[period.Id].Name,
                                    this.Periods[period.Id].Bias,
                                    period.Name,
                                    period.Bias));
                        }
                    }

                    break;

                case XmlElementNames.TransitionsGroups:
                    foreach (object arrayOfTransitionsTypeInstance in jsonProperty.ReadAsArray(key))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);
                        transitionGroup.LoadFromJson(arrayOfTransitionsTypeInstance as JsonObject, service);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }

                    break;

                case XmlElementNames.Transitions:
                    JsonObject arrayOfTransitionsType = jsonProperty.ReadAsJsonObject(key);

                    foreach (object uncastJsonTransition in arrayOfTransitionsType.ReadAsArray(XmlElementNames.Transition))
                    {
                        JsonObject         jsonTransition = uncastJsonTransition as JsonObject;
                        TimeZoneTransition transition     = TimeZoneTransition.Create(this, jsonTransition.ReadTypeString());

                        transition.LoadFromJson(jsonTransition, service);

                        this.transitions.Add(transition);
                    }

                    break;

                default:
                    break;
                }
            }

            // EWS can return a TimeZone definition with no Id. Generate a new Id in this case.
            if (string.IsNullOrEmpty(this.id))
            {
                string nameValue = string.IsNullOrEmpty(this.Name) ? string.Empty : this.Name;
                this.Id = NoIdPrefix + Math.Abs(nameValue.GetHashCode()).ToString();
            }

            this.transitions.Sort(this.CompareTransitions);
        }