Beispiel #1
0
        private IReadOnlyList <EntityWithId <Uri, vCard> > ParallelDeserialize(IReadOnlyList <EntityWithId <Uri, string> > serializedEntities)
        {
            var result = new List <EntityWithId <Uri, vCard> >();

            Parallel.ForEach(
                serializedEntities,
                () => Tuple.Create(new vCardStandardReader(), new List <Tuple <Uri, vCard> >()),
                (serialized, loopState, threadLocal) =>
            {
                vCard vcard;

                if (TryDeserialize(serialized.Entity, out vcard, serialized.Id, threadLocal.Item1))
                {
                    threadLocal.Item2.Add(Tuple.Create(serialized.Id, vcard));
                }
                return(threadLocal);
            },
                threadLocal =>
            {
                lock (result)
                {
                    foreach (var card in threadLocal.Item2)
                    {
                        result.Add(EntityWithId.Create(card.Item1, card.Item2));
                    }
                }
            });

            return(result);
        }
Beispiel #2
0
        private IReadOnlyList <EntityWithId <WebResourceName, TEntity> > ParallelDeserialize(IReadOnlyList <EntityWithId <WebResourceName, string> > serializedEntities, ILoadEntityLogger logger)
        {
            var result = new List <EntityWithId <WebResourceName, TEntity> >();

            Parallel.ForEach(
                serializedEntities,
                () => Tuple.Create(new TDeserializationThreadLocal(), new List <Tuple <WebResourceName, TEntity> >()),
                (serialized, loopState, threadLocal) =>
            {
                TEntity entity;

                if (TryDeserialize(serialized.Entity, out entity, serialized.Id, threadLocal.Item1, logger))
                {
                    threadLocal.Item2.Add(Tuple.Create(serialized.Id, entity));
                }
                return(threadLocal);
            },
                threadLocal =>
            {
                lock (result)
                {
                    foreach (var card in threadLocal.Item2)
                    {
                        result.Add(EntityWithId.Create(card.Item1, card.Item2));
                    }
                }
            });

            return(result);
        }
        private IReadOnlyList <EntityWithId <WebResourceName, vCard> > ParallelDeserialize(IReadOnlyList <EntityWithId <WebResourceName, string> > serializedEntities, ILoadEntityLogger logger)
        {
            var result = new List <EntityWithId <WebResourceName, vCard> >();

            Parallel.ForEach(
                serializedEntities,
                () => Tuple.Create(new vCardStandardReader(), new List <Tuple <WebResourceName, vCard> >()),
                (serialized, loopState, threadLocal) =>
            {
                vCard vcard;

                // fix some linebreak issues with Open-Xchange
                string normalizedVcardData = serialized.Entity.Contains("\r\r\n") ? ContactDataPreprocessor.NormalizeLineBreaks(serialized.Entity) : serialized.Entity;

                if (TryDeserialize(normalizedVcardData, out vcard, serialized.Id, threadLocal.Item1, logger))
                {
                    threadLocal.Item2.Add(Tuple.Create(serialized.Id, vcard));
                }
                return(threadLocal);
            },
                threadLocal =>
            {
                lock (result)
                {
                    foreach (var card in threadLocal.Item2)
                    {
                        result.Add(EntityWithId.Create(card.Item1, card.Item2));
                    }
                }
            });

            return(result);
        }
Beispiel #4
0
        public async Task <IReadOnlyList <EntityWithId <WebResourceName, string> > > GetEntities(IEnumerable <WebResourceName> eventUrls)
        {
            WebResourceName firstResourceNameOrNull = null;

            var requestBody = @"<?xml version=""1.0""?>
			                    <C:calendar-multiget xmlns:C=""urn:ietf:params:xml:ns:caldav"" xmlns:D=""DAV:"">
			                        <D:prop>
			                            <D:getetag/>
			                            <D:displayname/>
			                            <C:calendar-data/>
			                        </D:prop>
                                        " +
                              String.Join(
                "\r\n",
                eventUrls.Select(
                    u =>
            {
                if (firstResourceNameOrNull == null)
                {
                    firstResourceNameOrNull = u;
                }
                return($"<D:href>{SecurityElement.Escape(u.OriginalAbsolutePath)}</D:href>");
            })) + @"
                                    </C:calendar-multiget>";

            var responseXml = await _webDavClient.ExecuteWebDavRequestAndReadResponse(
                UriHelper.AlignServerUrl(_serverUrl, firstResourceNameOrNull),
                "REPORT",
                1,
                null,
                null,
                "application/xml",
                requestBody
                );

            XmlNodeList responseNodes = responseXml.XmlDocument.SelectNodes("/D:multistatus/D:response", responseXml.XmlNamespaceManager);

            var entities = new List <EntityWithId <WebResourceName, string> >();

            if (responseNodes == null)
            {
                return(entities);
            }

            // ReSharper disable once LoopCanBeConvertedToQuery
            // ReSharper disable once PossibleNullReferenceException
            foreach (XmlElement responseElement in responseNodes)
            {
                var urlNode  = responseElement.SelectSingleNode("D:href", responseXml.XmlNamespaceManager);
                var dataNode = responseElement.SelectSingleNode("D:propstat/D:prop/C:calendar-data", responseXml.XmlNamespaceManager);
                if (urlNode != null && !string.IsNullOrEmpty(dataNode?.InnerText))
                {
                    entities.Add(EntityWithId.Create(new WebResourceName(urlNode.InnerText), dataNode.InnerText));
                }
            }

            return(entities);
        }
#pragma warning disable 1998
        public async Task <IEnumerable <EntityWithId <string, IDistListItemWrapper> > > Get(ICollection <string> ids, ILoadEntityLogger logger, Tcontext context)
#pragma warning restore 1998
        {
            return(ids
                   .Select(id => EntityWithId.Create(
                               id,
                               _comWrapperFactory.Create(
                                   _session.GetDistListItem(id, _folderStoreId)))));
        }
        public async Task <IEnumerable <EntityWithId <string, GoogleContactWrapper> > > Get(ICollection <string> ids, ILoadEntityLogger logger, IGoogleContactContext context)
        {
            var result = new List <EntityWithId <string, GoogleContactWrapper> >();

            foreach (var id in ids)
            {
                Contact contact;
                if (context.ContactCache.TryGetValue(id, out contact))
                {
                    result.Add(EntityWithId.Create(contact.Id, new GoogleContactWrapper(contact)));
                }
            }

            var groups = context.GroupCache.Groups.ToDictionary(g => g.Id);

            foreach (var contactWrapper in result)
            {
                foreach (var groupMembership in contactWrapper.Entity.Contact.GroupMembership)
                {
                    if (!context.GroupCache.IsDefaultGroupId(groupMembership.HRef))
                    {
                        Group group;
                        if (groups.TryGetValue(groupMembership.HRef, out group))
                        {
                            contactWrapper.Entity.Groups.Add(group.Title);
                        }
                        else
                        {
                            s_logger.Warn($"Could not find Group '{groupMembership.HRef}' in the cached groups");
                        }
                    }
                }
            }

            if (_contactMappingConfiguration.MapContactPhoto)
            {
                await Task.Run(() =>
                {
                    foreach (var contactWrapper in result)
                    {
                        if (contactWrapper.Entity.Contact.PhotoEtag != null)
                        {
                            using (var photoStream = _apiOperationExecutor.Execute(f => f.Service.Query(contactWrapper.Entity.Contact.PhotoUri)))
                            {
                                var memoryStream = new MemoryStream();
                                photoStream.CopyTo(memoryStream);
                                // ReSharper disable once PossibleAssignmentToReadonlyField
                                contactWrapper.Entity.PhotoOrNull = memoryStream.ToArray();
                            }
                        }
                    }
                });
            }

            return(result);
        }
Beispiel #7
0
#pragma warning disable 1998
        public async Task <IEnumerable <EntityWithId <AppointmentId, IAppointmentItemWrapper> > > Get(ICollection <AppointmentId> ids, ILoadEntityLogger logger, IEventSynchronizationContext context)
#pragma warning restore 1998
        {
            return(ids
                   .Select(id => EntityWithId.Create(
                               id,
                               _comWrapperFactory.Create(
                                   _session.GetAppointmentItem(id.EntryId, _folderStoreId),
                                   entryId => _session.GetAppointmentItem(entryId, _folderStoreId)))));
        }
        public Task <IReadOnlyList <EntityWithId <WebResourceName, string> > > GetEntities(IEnumerable <WebResourceName> eventUrls)
        {
            var entities =
                from url in eventUrls
                let path = Path.Combine(_directory.FullName, url.OriginalAbsolutePath)
                           where File.Exists(path)
                           select EntityWithId.Create(url, File.ReadAllText(path));

            return(Task.FromResult <IReadOnlyList <EntityWithId <WebResourceName, string> > >(entities.ToArray()));
        }
Beispiel #9
0
#pragma warning disable 1998
        public async Task <IReadOnlyList <EntityWithId <string, GenericComObjectWrapper <DistListItem> > > > Get(ICollection <string> ids, ILoadEntityLogger logger, Tcontext context)
#pragma warning restore 1998
        {
            return(ids
                   .Select(id => EntityWithId.Create(
                               id,
                               GenericComObjectWrapper.Create(
                                   (DistListItem)_mapiNameSpace.GetItemFromID(id, _folderStoreId))))
                   .ToArray());
        }
Beispiel #10
0
#pragma warning disable 1998
        public async Task <IReadOnlyList <EntityWithId <AppointmentId, AppointmentItemWrapper> > > Get(ICollection <AppointmentId> ids, ILoadEntityLogger logger, IEventSynchronizationContext context)
#pragma warning restore 1998
        {
            return(ids
                   .Select(id => EntityWithId.Create(
                               id,
                               new AppointmentItemWrapper(
                                   (AppointmentItem)_mapiNameSpace.GetItemFromID(id.EntryId, _folderStoreId),
                                   entryId => (AppointmentItem)_mapiNameSpace.GetItemFromID(entryId, _folderStoreId))))
                   .ToArray());
        }
Beispiel #11
0
#pragma warning disable 1998
        public async Task <IReadOnlyList <EntityWithId <string, ContactItemWrapper> > > Get(ICollection <string> ids, ILoadEntityLogger logger)
#pragma warning restore 1998
        {
            return(ids
                   .Select(id => EntityWithId.Create(
                               id,
                               new ContactItemWrapper(
                                   (ContactItem)_mapiNameSpace.GetItemFromID(id, _folderStoreId),
                                   entryId => (ContactItem)_mapiNameSpace.GetItemFromID(entryId, _folderStoreId))))
                   .ToArray());
        }
Beispiel #12
0
        public async Task <IReadOnlyList <EntityWithId <Uri, string> > > GetEntities(IEnumerable <Uri> urls)
        {
            var requestBody = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
   <A:addressbook-multiget xmlns:D=""DAV:"" xmlns:A=""urn:ietf:params:xml:ns:carddav"">
     <D:prop>
       <D:getetag/>
       <D:getcontenttype/>
       <A:address-data/>
     </D:prop>
     " + String.Join("\r\n", urls.Select(u => string.Format("<D:href>{0}</D:href>", SecurityElement.Escape(u.ToString())))) + @"
   </A:addressbook-multiget>
 ";


            var responseXml = await _webDavClient.ExecuteWebDavRequestAndReadResponse(
                _serverUrl,
                "REPORT",
                0,
                null,
                null,
                "application/xml",
                requestBody
                );

            XmlNodeList responseNodes = responseXml.XmlDocument.SelectNodes("/D:multistatus/D:response", responseXml.XmlNamespaceManager);

            var entities = new List <EntityWithId <Uri, string> >();

            if (responseNodes == null)
            {
                return(entities);
            }

            // ReSharper disable once LoopCanBeConvertedToQuery
            // ReSharper disable once PossibleNullReferenceException
            foreach (XmlElement responseElement in responseNodes)
            {
                var    urlNode         = responseElement.SelectSingleNode("D:href", responseXml.XmlNamespaceManager);
                var    dataNode        = responseElement.SelectSingleNode("D:propstat/D:prop/A:address-data", responseXml.XmlNamespaceManager);
                var    contentTypeNode = responseElement.SelectSingleNode("D:propstat/D:prop/D:getcontenttype", responseXml.XmlNamespaceManager);
                string contentType     = contentTypeNode.InnerText ?? string.Empty;

                // TODO: add vlist support but for now filter out sogo vlists since we can't parse them atm
                if (urlNode != null && dataNode != null && !string.IsNullOrEmpty(dataNode.InnerText) && contentType != "text/x-vlist")
                {
                    entities.Add(EntityWithId.Create(UriHelper.UnescapeRelativeUri(_serverUrl, urlNode.InnerText), dataNode.InnerText));
                }
            }

            return(entities);
        }
        public async Task GetVCardTypesAndCleanupCache_AllIdsInCache_LoadsMissingFromRepositoryAndRemovesUnusedEntries()
        {
            _readOnlyEntityRepository
            .Expect(r => r.Get(
                        new[]
            {
                new WebResourceName("id5"),
                new WebResourceName("id4")
            },
                        NullLoadEntityLogger.Instance,
                        NullCardDavRepositoryLogger.Instance))
            .Return(Task.FromResult <IEnumerable <EntityWithId <WebResourceName, vCard> > >(new[]
            {
                EntityWithId.Create(new WebResourceName("id5"), new vCard {
                    Kind = vCardKindType.Group
                }),
                EntityWithId.Create(new WebResourceName("id4"), new vCard {
                    Kind = vCardKindType.Location
                })
            }));

            await GetVCardTypesAndCleanupCacheTest(
                initialCacheEntries : new[]
            {
                Tuple.Create("id1", VCardType.Contact),
                Tuple.Create("id2", VCardType.Group),
                Tuple.Create("id66", VCardType.Group),
                Tuple.Create("id77", VCardType.Contact),
                Tuple.Create("id3", VCardType.Contact)
            },
                idsToQuery : new[] { "id5", "id2", "id3", "id4", "id1" },
                expectedResult : new[]
            {
                Tuple.Create("id1", VCardType.Contact),
                Tuple.Create("id2", VCardType.Group),
                Tuple.Create("id3", VCardType.Contact),
                Tuple.Create("id4", VCardType.Contact),
                Tuple.Create("id5", VCardType.Group)
            },
                expectedFinalCacheEntries : new[]
            {
                Tuple.Create("id1", VCardType.Contact),
                Tuple.Create("id2", VCardType.Group),
                Tuple.Create("id3", VCardType.Contact),
                Tuple.Create("id4", VCardType.Contact),
                Tuple.Create("id5", VCardType.Group)
            });

            _readOnlyEntityRepository.VerifyAllExpectations();
        }
        public async Task <IReadOnlyList <EntityWithId <string, Task> > > Get(ICollection <string> ids, ILoadEntityLogger logger, int context)
        {
            var items = new List <EntityWithId <string, Task> > ();

            // All the requests are awaited sequentially in a loop, because creating all the requests at once ant awaiting them after the loop would
            // probably open up too many connections
            foreach (var id in ids)
            {
                var item = await _tasksService.Tasks.Get(_taskList.Id, id).ExecuteAsync();

                items.Add(EntityWithId.Create(item.Id, item));
            }

            return(items);
        }
        public async Task <IReadOnlyList <EntityWithId <Uri, string> > > GetEntities(IEnumerable <Uri> eventUrls)
        {
            var requestBody = @"<?xml version=""1.0""?>
			                    <C:calendar-multiget xmlns:C=""urn:ietf:params:xml:ns:caldav"" xmlns:D=""DAV:"">
			                        <D:prop>
			                            <D:getetag/>
			                            <D:displayname/>
			                            <C:calendar-data/>
			                        </D:prop>
                                        " + String.Join("\r\n", eventUrls.Select(u => string.Format("<D:href>{0}</D:href>", SecurityElement.Escape(u.ToString())))) + @"
                                    </C:calendar-multiget>";

            var responseXml = await _webDavClient.ExecuteWebDavRequestAndReadResponse(
                _serverUrl,
                "REPORT",
                1,
                null,
                null,
                "application/xml",
                requestBody
                );

            XmlNodeList responseNodes = responseXml.XmlDocument.SelectNodes("/D:multistatus/D:response", responseXml.XmlNamespaceManager);

            var entities = new List <EntityWithId <Uri, string> >();

            if (responseNodes == null)
            {
                return(entities);
            }

            // ReSharper disable once LoopCanBeConvertedToQuery
            // ReSharper disable once PossibleNullReferenceException
            foreach (XmlElement responseElement in responseNodes)
            {
                var urlNode  = responseElement.SelectSingleNode("D:href", responseXml.XmlNamespaceManager);
                var dataNode = responseElement.SelectSingleNode("D:propstat/D:prop/C:calendar-data", responseXml.XmlNamespaceManager);
                if (urlNode != null && dataNode != null)
                {
                    entities.Add(EntityWithId.Create(UriHelper.UnescapeRelativeUri(_serverUrl, urlNode.InnerText), dataNode.InnerText));
                }
            }

            return(entities);
        }
Beispiel #16
0
        public static string SyncOutlookToCalDav_EventsExistsInCalDav(string existingEventData, IEntityRelationDataAccess <string, DateTime, WebResourceName, string> entityRelationDataAccess = null)
        {
            string            roundTrippedData = null;
            ICalDavDataAccess calDavDataAccess = MockRepository.GenerateMock <ICalDavDataAccess>();
            var entityUri = new WebResourceName("/e1");

            calDavDataAccess
            .Expect(r => r.GetEventVersions(null))
            .IgnoreArguments()
            .Return(Task.FromResult <IReadOnlyList <EntityVersion <WebResourceName, string> > > (
                        new[] { EntityVersion.Create(entityUri, "v1") }));

            calDavDataAccess
            .Expect(r => r.GetEntities(Arg <ICollection <WebResourceName> > .List.Equal(new[] { entityUri })))
            .Return(Task.FromResult <IReadOnlyList <EntityWithId <WebResourceName, string> > > (
                        new[] { EntityWithId.Create(entityUri, existingEventData) }));

            calDavDataAccess
            .Expect(r => r.TryUpdateEntity(
                        new WebResourceName("http://bla.com"),
                        null,
                        null))
            .IgnoreArguments()
            .Return(Task.FromResult <EntityVersion <WebResourceName, string> > (
                        EntityVersion.Create(new WebResourceName("http://bla.com"), "blubb")))
            .WhenCalled(a => { roundTrippedData = (string)a.Arguments[2]; });

            var synchronizer = OutlookTestContext.CreateEventSynchronizer(
                SynchronizationMode.ReplicateOutlookIntoServer,
                calDavDataAccess,
                entityRelationDataAccess);

            WaitForTask(synchronizer.SynchronizeNoThrow(NullSynchronizationLogger.Instance));

            return(roundTrippedData);
        }
Beispiel #17
0
        public static void SyncCalDavToOutlook(string eventData, IEntityRelationDataAccess <string, DateTime, WebResourceName, string> entityRelationDataAccess)
        {
            var calDavDataAccess = MockRepository.GenerateMock <ICalDavDataAccess>();

            var entityUri = new WebResourceName("/e1");

            calDavDataAccess
            .Expect(r => r.GetEventVersions(null))
            .IgnoreArguments()
            .Return(Task.FromResult <IReadOnlyList <EntityVersion <WebResourceName, string> > > (
                        new[] { EntityVersion.Create(entityUri, "v1") }));

            calDavDataAccess
            .Expect(r => r.GetEntities(Arg <ICollection <WebResourceName> > .List.Equal(new[] { entityUri })))
            .Return(Task.FromResult <IReadOnlyList <EntityWithId <WebResourceName, string> > > (
                        new[] { EntityWithId.Create(entityUri, eventData) }));

            var synchronizer = OutlookTestContext.CreateEventSynchronizer(
                SynchronizationMode.ReplicateServerIntoOutlook,
                calDavDataAccess,
                entityRelationDataAccess);

            WaitForTask(synchronizer.SynchronizeNoThrow(NullSynchronizationLogger.Instance));
        }
        public async Task Synchronize_GetVersionsAndGetReturnDuplicateEntries_RemovesDuplicates()
        {
            var builder = new SynchronizerBuilder();

            builder.AtypeIdComparer = StringComparer.InvariantCultureIgnoreCase;

            builder.AtypeRepository
            .Expect(r => r.GetAllVersions(new string[] { }))
            .IgnoreArguments()
            .Return(
                Task.FromResult <IReadOnlyList <EntityVersion <string, string> > > (
                    new[] { EntityVersion.Create("A1", "v1"), EntityVersion.Create("a1", "v3") }));

            builder.BtypeRepository
            .Expect(r => r.GetAllVersions(new string[] { }))
            .IgnoreArguments()
            .Return(
                Task.FromResult <IReadOnlyList <EntityVersion <string, string> > > (
                    new[] { EntityVersion.Create("b1", "v2") }));


            Task <IReadOnlyList <EntityWithId <string, string> > > aTypeLoadTask = new Task <IReadOnlyList <EntityWithId <string, string> > > (
                () => new List <EntityWithId <string, string> > {
                EntityWithId.Create("A1", "AAAA"), EntityWithId.Create("a1", "____")
            });

            aTypeLoadTask.RunSynchronously();
            builder.AtypeRepository
            .Expect(r => r.Get(Arg <ICollection <string> > .Matches(c => c.Count == 1 && c.First() == "A1"), Arg <ILoadEntityLogger> .Is.NotNull))
            .Return(aTypeLoadTask);

            Task <IReadOnlyList <EntityWithId <string, string> > > bTypeLoadTask = new Task <IReadOnlyList <EntityWithId <string, string> > > (
                () => new List <EntityWithId <string, string> > {
                EntityWithId.Create("b1", "BBBB"),
            });

            bTypeLoadTask.RunSynchronously();
            builder.BtypeRepository
            .Expect(r => r.Get(Arg <ICollection <string> > .Matches(c => c.Count == 1 && c.First() == "b1"), Arg <ILoadEntityLogger> .Is.NotNull))
            .Return(bTypeLoadTask);


            var knownData = new EntityRelationData <string, string, string, string> ("A1", "v1", "b1", "v2");

            builder.InitialEntityMatcher
            .Expect(m => m.FindMatchingEntities(null, null, null, null, null))
            .IgnoreArguments()
            .Return(new List <IEntityRelationData <string, string, string, string> > {
                knownData
            });

            builder.InitialSyncStateCreationStrategy
            .Expect(s => s.CreateFor_Unchanged_Unchanged(knownData))
            .Return(new DoNothing <string, string, string, string, string, string> (knownData));

            var synchronizer = builder.Build();
            await synchronizer.SynchronizeNoThrow(NullSynchronizationLogger.Instance);

            builder.EntityRelationDataAccess.AssertWasCalled(
                c => c.SaveEntityRelationData(Arg <List <IEntityRelationData <string, string, string, string> > > .Matches(l => l.Count == 1 && l[0] == knownData)));
        }
Beispiel #19
0
        public async Task <IReadOnlyList <EntityWithId <WebResourceName, string> > > GetEntities(IEnumerable <WebResourceName> urls)
        {
            s_logger.Debug("Entered GetEntities.");

            WebResourceName firstResourceNameOrNull = null;

            var requestBody = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
   <A:addressbook-multiget xmlns:D=""DAV:"" xmlns:A=""urn:ietf:params:xml:ns:carddav"">
     <D:prop>
       <D:getetag/>
       <D:getcontenttype/>
       <A:address-data/>
     </D:prop>
     " +
                              String.Join("\r\n", urls.Select(u =>
            {
                if (s_logger.IsDebugEnabled)
                {
                    s_logger.Debug($"Requesting: '{u}'");
                }

                if (firstResourceNameOrNull == null)
                {
                    firstResourceNameOrNull = u;
                }

                return($"<D:href>{SecurityElement.Escape (u.OriginalAbsolutePath)}</D:href>");
            }))
                              + @"
   </A:addressbook-multiget>
 ";

            var responseXml = await _webDavClient.ExecuteWebDavRequestAndReadResponse(
                UriHelper.AlignServerUrl(_serverUrl, firstResourceNameOrNull),
                "REPORT",
                0,
                null,
                null,
                "application/xml",
                requestBody
                );

            XmlNodeList responseNodes = responseXml.XmlDocument.SelectNodes("/D:multistatus/D:response", responseXml.XmlNamespaceManager);

            var entities = new List <EntityWithId <WebResourceName, string> >();

            if (responseNodes == null)
            {
                return(entities);
            }

            // ReSharper disable once LoopCanBeConvertedToQuery
            // ReSharper disable once PossibleNullReferenceException
            foreach (XmlElement responseElement in responseNodes)
            {
                var    urlNode         = responseElement.SelectSingleNode("D:href", responseXml.XmlNamespaceManager);
                var    dataNode        = responseElement.SelectSingleNode("D:propstat/D:prop/A:address-data", responseXml.XmlNamespaceManager);
                var    contentTypeNode = responseElement.SelectSingleNode("D:propstat/D:prop/D:getcontenttype", responseXml.XmlNamespaceManager);
                string contentType     = contentTypeNode?.InnerText ?? string.Empty;

                if (urlNode != null && dataNode != null && !string.IsNullOrEmpty(dataNode.InnerText) && _contentTypePredicate(contentType))
                {
                    if (s_logger.IsDebugEnabled)
                    {
                        s_logger.DebugFormat($"Got: '{urlNode.InnerText}'");
                    }
                    entities.Add(EntityWithId.Create(new WebResourceName(urlNode.InnerText), dataNode.InnerText));
                }
            }

            s_logger.Debug("Exiting GetEntities.");
            return(entities);
        }
Beispiel #20
0
        private Task <IReadOnlyList <EntityWithId <WebResourceName, IICalendar> > > ParallelDeserialize(IReadOnlyList <EntityWithId <WebResourceName, string> > serializedEntities, ILoadEntityLogger logger)
        {
            return(Task.Factory.StartNew(() =>
            {
                var result = new List <EntityWithId <WebResourceName, IICalendar> >();

                Parallel.ForEach(
                    serializedEntities,
                    () => Tuple.Create(new iCalendarSerializer(), new List <Tuple <WebResourceName, IICalendar> >()),
                    (serialized, loopState, threadLocal) =>
                {
                    IICalendar calendar;
                    string normalizedICalData, fixedICalData;

                    // fix some linebreak issues with Open-Xchange
                    if (serialized.Entity.Contains("\r\r\n"))
                    {
                        normalizedICalData = CalendarDataPreprocessor.NormalizeLineBreaks(serialized.Entity);
                    }
                    else
                    {
                        normalizedICalData = serialized.Entity;
                    }

                    // emClient sets DTSTART in VTIMEZONE to year 0001, which causes a 90 sec delay in DDay.iCal to evaluate the recurrence rule.
                    // If we find such a DTSTART we replace it 0001 with 1970 since the historic data is not valid anyway and avoid the performance issue.
                    if (normalizedICalData.Contains("DTSTART:00010101"))
                    {
                        fixedICalData = CalendarDataPreprocessor.FixInvalidDTSTARTInTimeZoneNoThrow(normalizedICalData);
                        s_logger.InfoFormat("Changed DTSTART from year 0001 to 1970 in VTIMEZONE of ICalData '{0}'.", serialized.Id);
                    }
                    else
                    {
                        fixedICalData = normalizedICalData;
                    }

                    if (TryDeserializeCalendar(fixedICalData, out calendar, serialized.Id, threadLocal.Item1, NullLoadEntityLogger.Instance))
                    {
                        threadLocal.Item2.Add(Tuple.Create(serialized.Id, calendar));
                    }
                    else
                    {
                        // maybe deserialization failed because of the iCal-TimeZone-Bug =>  try to fix it
                        var fixedICalData2 = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(fixedICalData);
                        if (TryDeserializeCalendar(fixedICalData2, out calendar, serialized.Id, threadLocal.Item1, logger))
                        {
                            threadLocal.Item2.Add(Tuple.Create(serialized.Id, calendar));
                            s_logger.Info(string.Format("Deserialized ICalData with reordering of TimeZone data '{0}'.", serialized.Id));
                        }
                    }

                    return threadLocal;
                },
                    threadLocal =>
                {
                    lock (result)
                    {
                        foreach (var calendar in threadLocal.Item2)
                        {
                            result.Add(EntityWithId.Create(calendar.Item1, calendar.Item2));
                        }
                    }
                });

                IReadOnlyList <EntityWithId <WebResourceName, IICalendar> > readOnlyResult = result;
                return readOnlyResult;
            }));
        }
Beispiel #21
0
 public Task <IReadOnlyList <EntityWithId <Uri, string> > > GetEntities(IEnumerable <Uri> eventUrls)
 {
     return(Task.FromResult <IReadOnlyList <EntityWithId <Uri, string> > > (
                eventUrls.Select(id => EntityWithId.Create(id, _entites[id].Item2)).ToList()));
 }
        private async Task <IReadOnlyList <IEntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> > > CreateEntitySyncStateContexts(
            IEntityContainer <TAtypeEntityId, TAtypeEntity, TContext> aEntities,
            IEntityContainer <TBtypeEntityId, TBtypeEntity, TContext> bEntities,
            IEnumerable <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> > knownEntityRelations,
            Dictionary <TAtypeEntityId, TAtypeEntityVersion> newAVersions,
            Dictionary <TBtypeEntityId, TBtypeEntityVersion> newBVersions,
            ISynchronizationLogger logger,
            TContext synchronizationContext,
            ISynchronizationInterceptor <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> interceptor)
        {
            var entitySynchronizationContexts = new List <IEntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> >();

            var aDeltaLogInfo = new VersionDeltaLoginInformation();
            var bDeltaLogInfo = new VersionDeltaLoginInformation();

            foreach (var knownEntityRelationData in knownEntityRelations)
            {
                TAtypeEntityVersion newAVersion;
                TBtypeEntityVersion newBVersion;

                var newAVersionAvailable = newAVersions.TryGetValue(knownEntityRelationData.AtypeId, out newAVersion);
                var newBVersionAvailable = newBVersions.TryGetValue(knownEntityRelationData.BtypeId, out newBVersion);

                if (newAVersionAvailable)
                {
                    newAVersions.Remove(knownEntityRelationData.AtypeId);
                }

                if (newBVersionAvailable)
                {
                    newBVersions.Remove(knownEntityRelationData.BtypeId);
                }

                entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(
                                                      CreateInitialSyncState(knownEntityRelationData, newAVersionAvailable, newAVersion, newBVersionAvailable, newBVersion, aDeltaLogInfo, bDeltaLogInfo)));
            }

            await _atypeRepository.VerifyUnknownEntities(newAVersions, synchronizationContext);

            await _btypeRepository.VerifyUnknownEntities(newBVersions, synchronizationContext);

            if (newAVersions.Count > 0 && newBVersions.Count > 0)
            {
                s_logger.Info($"Performing entity matching with {newAVersions.Count} Atype and {newBVersions.Count} Btype entities.");

                var matchingEntites = _initialEntityMatcher.FindMatchingEntities(
                    _entityRelationDataFactory,
                    (await aEntities.SelectEntities(newAVersions.Keys, logger.ALoadEntityLogger, synchronizationContext, e => EntityWithId.Create(e.Id, _aMatchDataFactory.CreateMatchData(e.Entity)))).ToDictionary(e => e.Id, e => e.Entity),
                    (await bEntities.SelectEntities(newBVersions.Keys, logger.BLoadEntityLogger, synchronizationContext, e => EntityWithId.Create(e.Id, _bMatchDataFactory.CreateMatchData(e.Entity)))).ToDictionary(e => e.Id, e => e.Entity),
                    newAVersions,
                    newBVersions);

                foreach (var knownEntityRelationData in matchingEntites)
                {
                    newAVersions.Remove(knownEntityRelationData.AtypeId);
                    newBVersions.Remove(knownEntityRelationData.BtypeId);
                    var entitySyncState = _initialSyncStateCreationStrategy.CreateFor_Unchanged_Unchanged(knownEntityRelationData);
                    entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(entitySyncState));
                    aDeltaLogInfo.IncUnchanged();
                    bDeltaLogInfo.IncUnchanged();
                }

                s_logger.Info("Entity matching finished.");
            }

            foreach (var newA in newAVersions)
            {
                var syncState = _initialSyncStateCreationStrategy.CreateFor_Added_NotExisting(newA.Key, newA.Value);
                entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(syncState));
            }

            foreach (var newB in newBVersions)
            {
                var syncState = _initialSyncStateCreationStrategy.CreateFor_NotExisting_Added(newB.Key, newB.Value);
                entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(syncState));
            }

            interceptor.TransformInitialCreatedStates(entitySynchronizationContexts, _syncStateFactory);

            // all the leftovers in newAVersions and newBVersions must be the added ones
            aDeltaLogInfo.IncAdded(newAVersions.Count);
            bDeltaLogInfo.IncAdded(newBVersions.Count);
            s_logger.InfoFormat("Atype delta: {0}", aDeltaLogInfo);
            s_logger.InfoFormat("Btype delta: {0}", bDeltaLogInfo);
            logger.LogDeltas(aDeltaLogInfo, bDeltaLogInfo);

            return(entitySynchronizationContexts);
        }
Beispiel #23
0
 public Task <IReadOnlyList <EntityWithId <Identifier, string> > > Get(ICollection <Identifier> ids, ILoadEntityLogger logger)
 {
     return(Task.FromResult <IReadOnlyList <EntityWithId <Identifier, string> > > (
                ids.Select(id => EntityWithId.Create(id, EntityVersionAndContentById[id].Item2)).ToArray()));
 }