예제 #1
0
        /// <summary>
        /// Writes the exception together with some meta information to an <see cref="XmlWriter"/>. If that <see cref="XmlWriter"/> is
        ///   null, a new instance of an <see cref="XmlWriter"/> is being created for writing into the file specified as the parameter
        ///   <paramref name="exceptionReportFileName"/>.
        /// </summary>
        /// <remarks>
        /// While creating the exception file a start tag is being written for the root element. The calling method is
        ///   responsible to write the corresponding closing tag in order to finish the file.
        /// </remarks>
        /// <param name="valueArray">
        /// The value array working with while the exception has been thrown.
        /// </param>
        /// <param name="rowId">
        /// The row id of the data row that caused the exception.
        /// </param>
        /// <param name="colId">
        /// The col id of the data column that caused the exception.
        /// </param>
        /// <param name="newElement">
        /// The element that is being processed while the exception did occure.
        /// </param>
        /// <param name="exceptionFile">
        /// The <see cref="XmlWriter"/> for the exception file - if this element is NULL, a new file stream will be created.
        /// </param>
        /// <param name="exceptionReportFileName">
        /// The exception report file name - in case of a null reference in the parameter <paramref name="exceptionFile"/> this file name will be used to create a new file stream for the XmlWriter.
        /// </param>
        /// <param name="ex">
        /// The exception to be written to the file.
        /// </param>
        /// <returns>
        /// The instance of the <see cref="XmlWriter"/> that has been utilized to write the exception.
        /// </returns>
        private static XmlWriter WriteExceptionFile(
            string[,] valueArray,
            int rowId,
            int colId,
            StdElement newElement,
            XmlWriter exceptionFile,
            string exceptionReportFileName,
            Exception ex)
        {
            if (exceptionFile == null)
            {
                exceptionFile = XmlWriter.Create(File.AppendText(exceptionReportFileName));

                if (exceptionFile != null)
                {
                    exceptionFile.WriteStartDocument(true);
                    exceptionFile.WriteStartElement("ExceptionReport");
                }
            }

            if (exceptionFile != null)
            {
                exceptionFile.WriteStartElement("Exception");
                exceptionFile.WriteAttributeString("PersonName", newElement.ToString());
                exceptionFile.WriteAttributeString("Row", rowId.ToString(CultureInfo.InvariantCulture));
                exceptionFile.WriteAttributeString("Column", colId.ToString(CultureInfo.InvariantCulture));
                exceptionFile.WriteAttributeString("ExcelReference", colId.IndexToLetters() + rowId);
                exceptionFile.WriteElementString("CellValue", valueArray[rowId, colId]);
                exceptionFile.WriteElementString("Exception", ex.ToString());
                exceptionFile.WriteEndElement();
            }

            return(exceptionFile);
        }
예제 #2
0
        /// <summary>
        /// Writes a single element to the list of elements
        /// </summary>
        /// <param name="list"> The list of elements the new element should be added to </param>
        /// <param name="element"> The new element that should be added </param>
        /// <param name="skipIfExisting"> If false: overwrites an existing element with the same id </param>
        /// <returns> True if writing was successfull, false if the entry has been skipped </returns>
        private static bool WriteElement(ICollection <StdElement> list, StdElement element, bool skipIfExisting)
        {
            var        asContact = element as StdContact;
            StdElement listEntry;

            if (asContact != null)
            {
                listEntry = (from entry in list
                             where
                             entry.Id == element.Id || entry.ExternalIdentifier.Equals(asContact.ExternalIdentifier)
                             select entry).FirstOrDefault();
            }
            else
            {
                listEntry = (from entry in list where entry.Id == element.Id select entry).FirstOrDefault();
            }

            if (listEntry != null)
            {
                if (skipIfExisting)
                {
                    return(false);
                }

                list.Remove(listEntry);
            }

            list.Add(element);
            return(true);
        }
예제 #3
0
        /// <summary>
        /// The match std contact.
        /// </summary>
        /// <param name="contact">
        /// The contact.
        /// </param>
        /// <param name="baseline">
        /// The baseline.
        /// </param>
        private static void MatchStdContact(StdElement contact, IEnumerable <StdElement> baseline)
        {
            if (contact == null)
            {
                return;
            }

            var targetId      = contact.ExternalIdentifier;
            var corresponding =
                (from element in baseline where ((MatchingEntry)element).ProfileId.MatchesAny(targetId) select element).
                FirstOrDefault();

            // if there is one with a matching profile id,
            // we overwrite the id
            if (corresponding == null)
            {
                return;
            }

            var sourceId = ((MatchingEntry)corresponding).ProfileId;

            foreach (var id in sourceId)
            {
                var key = id.Key;
                if (string.IsNullOrEmpty(targetId.GetProfileId(key)))
                {
                    targetId.SetProfileId(key, id.Value);
                }
            }

            contact.Id = corresponding.Id;
        }
예제 #4
0
        /// <summary>
        /// The write contact.
        /// </summary>
        /// <param name="con">
        /// The con.
        /// </param>
        /// <param name="x">
        /// The x.
        /// </param>
        /// <param name="definitions">
        /// The definitions.
        /// </param>
        private static void WriteContact(SqlConnection con, StdElement x, List <ColumnDefinition> definitions)
        {
            var cmd = con.CreateCommand();

            cmd.CommandText = "SELECT ContactID FROM Contact WHERE ContactID = @contactId'";
            cmd.Parameters.AddWithValue("@contactId", x.Id);
            var ret = cmd.ExecuteScalar();
        }
예제 #5
0
        /// <summary>
        /// overrides the standard MergeMissingItem method to not read all outlook contacts, because
        ///   that is not needed to add a new contact
        /// </summary>
        /// <param name="element">
        /// element that should be merged into the outlook folder
        /// </param>
        /// <param name="clientFolderName">
        /// outlook folder that should get the new contact
        /// </param>
        public override void MergeMissingItem(StdElement element, string clientFolderName)
        {
            var elements = new List <StdElement> {
                element
            };

            this.WriteFullList(elements, clientFolderName, true);
        }
예제 #6
0
        /// <summary>
        /// This method does NOT get all elements before adding the new element. It will only match the element by the Id
        /// </summary>
        /// <param name="element">
        /// the element to add
        /// </param>
        /// <param name="clientFolderName">
        /// the outlook folder to use
        /// </param>
        public override void AddItem(StdElement element, string clientFolderName)
        {
            var elements = new List <StdElement> {
                element
            };

            this.WriteFullList(elements, clientFolderName, false);
        }
예제 #7
0
        /// <summary>
        /// Overridable implementation of the process of writing a single element. In the
        ///   default implementation this calls <see cref="GetAll"/>, WriteElement and
        ///   <see cref="WriteRange"/> to write the element and performs logging calls.
        /// </summary>
        /// <param name="element"> The element to be added. </param>
        /// <param name="clientFolderName">
        ///   The information where inside the source the elements reside -
        ///   This does not need to be a real "path", but need to be something that can be expressed as a string
        /// </param>
        public virtual void AddItem(StdElement element, string clientFolderName)
        {
            this.LogProcessingEvent(element, Resources.uiAddingElement);
            var data = this.GetAll(clientFolderName);

            WriteElement(data, element);
            this.WriteRange(data, clientFolderName);
            this.LogProcessingEvent(element, Resources.uiElementAdded);
        }
예제 #8
0
        /// <summary>
        /// Implementation of the process of writing a single element and skipping this process if this
        ///   element is already present. If the element does not exist, it will be added. If it does exist
        ///   the element will not be added and not be overridden.
        /// </summary>
        /// <param name="element">The element to be added</param>
        /// <param name="clientFolderName">
        ///   The information where inside the source the elements reside -
        ///   This does not need to be a real "path", but need to be something that can be expressed as a string
        /// </param>
        public virtual void MergeMissingItem(StdElement element, string clientFolderName)
        {
            this.LogProcessingEvent(element, Resources.uiAddingMissingElement);
            var data  = this.GetAll(clientFolderName);
            var added = WriteElement(data, element, true);

            this.WriteRange(data, clientFolderName);
            this.LogProcessingEvent(element, added ? Resources.uiElementAdded : Resources.uiElementSkipped);
        }
예제 #9
0
 /// <summary>
 /// logs an event by specifying the current element that is related to the event and a message about the current event
 /// </summary>
 /// <param name="stdItem">
 /// the std-element this event corresponds to
 /// </param>
 /// <param name="message">
 /// the message for this even (should describe what's happening in this step of execution)
 /// </param>
 protected void LogProcessingEvent(StdElement stdItem, string message)
 {
     if (this.ProcessingEvent != null)
     {
         this.ProcessingEvent(
             (object)stdItem ?? (object)this, new ProcessingEventArgs {
             Item = stdItem, Message = message
         });
     }
 }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Node"/> class.
        /// This ctor does create an element node from the ID and the <see cref="StdContact.GetFullName"/>
        /// or <see cref="StdElement.ToStringSimple"/> methods.
        /// </summary>
        /// <param name="element"> The element to convert. </param>
        public Node(StdElement element)
        {
            this.Id = element.Id.ToString("N");

            var contact = element as StdContact;

            this.Label =
                contact != null
                ? contact.GetFullName()
                : element.ToStringSimple();
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MatchView"/> class.
        /// </summary>
        /// <param name="sourceElement">
        /// The source element.
        /// </param>
        /// <param name="targetElement">
        /// The target element.
        /// </param>
        public MatchView(StdElement sourceElement, StdElement targetElement)
        {
            var sourceContact = sourceElement as StdContact;
            var targetContact = targetElement as StdContact;

            this.ContactName = sourceContact != null?sourceContact.GetFullName() : sourceElement.ToString();

            this.ContactNameMatch = targetContact != null?targetContact.GetFullName() : targetElement.ToString();

            this.BaselineId = targetElement.Id;
        }
예제 #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MatchCandidateView"/> class.
        /// </summary>
        /// <param name="stdElement">
        /// The std element.
        /// </param>
        public MatchCandidateView(StdElement stdElement)
        {
            this.Element = stdElement;
            var contact = stdElement as StdContact;

            if (contact != null)
            {
                this.ContactName = contact.GetFullName();
                return;
            }

            this.ContactName = stdElement.ToString();
        }
예제 #13
0
        /// <summary>
        /// Converts a <see cref="StdContact"/> to an Oracle CRM on Demand <see cref="ContactData"/>
        /// </summary>
        /// <param name="element">The standard contact</param>
        /// <param name="addCustomAttributes"> a value specifying whether non-mapped properties should be added from the <see cref="StdContact.SourceSpecificAttributes"/></param>
        /// <returns>The converted data as a <see cref="ContactData"/></returns>
        internal static ContactData ToOracleContact(this StdElement element, bool addCustomAttributes)
        {
            var contact = element as StdContact;

            if (contact == null)
            {
                return(null);
            }

            var result = new ContactData
            {
                Id = contact.ExternalIdentifier[ProfileIdentifierType.OracleCrmOnDemandId],

                CreatedDate          = contact.InternalSyncData.NewIfNull().DateOfCreation,
                CreatedDateSpecified = true,

                ModifiedDate          = contact.InternalSyncData.NewIfNull().DateOfLastChange,
                ModifiedDateSpecified = true,

                Description     = contact.AdditionalTextData,
                WorkPhone       = contact.BusinessAddressPrimary.NewIfNull().Phone.NewIfNull().ToString().Replace("(", string.Empty).Replace(")", string.Empty),
                PrimaryCity     = contact.BusinessAddressPrimary.NewIfNull().CityName,
                PrimaryZipCode  = contact.BusinessAddressPrimary.NewIfNull().PostalCode,
                PrimaryCountry  = contact.BusinessAddressPrimary.NewIfNull().CountryName,
                PrimaryAddress  = contact.BusinessAddressPrimary.NewIfNull().StreetName,
                PrimaryProvince = contact.BusinessAddressPrimary.NewIfNull().StateName,

                HomePhone     = contact.PersonalAddressPrimary.NewIfNull().Phone.NewIfNull().ToString().Replace("(", string.Empty).Replace(")", string.Empty),
                ContactEmail  = contact.BusinessEmailPrimary,
                CellularPhone = contact.BusinessPhoneMobile.NewIfNull().ToString().Replace("(", string.Empty).Replace(")", string.Empty),
                JobTitle      = contact.BusinessPosition,
                Department    = contact.BusinessDepartment,
                AccountName   = contact.BusinessCompanyName,

                DateofBirth          = contact.DateOfBirth,
                DateofBirthSpecified = contact.DateOfBirth > DateTime.MinValue,

                ContactFirstName = contact.Name.NewIfNull().FirstName,
                MiddleName       = contact.Name.NewIfNull().MiddleName,
                ContactLastName  = contact.Name.NewIfNull().LastName,
            };

            if (addCustomAttributes && contact.SourceSpecificAttributes != null)
            {
                // determine the prefix for the key
                var targetConnectorName = typeof(ContactClient).FullName;
                if (targetConnectorName == null)
                {
                    return(result);
                }

                var startIndex = targetConnectorName.Length;

                // get all matching source properties and set the target
                // property + the corresponding "specified" property.
                (from x in contact.SourceSpecificAttributes
                 where x.Key.StartsWith(targetConnectorName, StringComparison.OrdinalIgnoreCase)
                 select x).ForEach(attribute =>
                {
                    var key          = attribute.Key.Substring(startIndex);
                    var keySpecified = key + "Specified";
                    Tools.SetPropertyValue(result, key, attribute.Value);
                    Tools.SetPropertyValue(result, keySpecified, "true");
                });
            }

            return(result);
        }
예제 #14
0
 /// <summary>
 /// log the events
 /// </summary>
 /// <param name="contactStdItem">
 /// element, this entry belongs to
 /// </param>
 /// <param name="message">
 /// the message for this even (should describe what's happening in this step of execution)
 /// </param>
 /// <param name="parameters">
 /// parameters that will be inserted into the log-message
 /// </param>
 protected void LogProcessingEvent(StdElement contactStdItem, string message, params object[] parameters)
 {
     this.LogProcessingEvent(contactStdItem, string.Format(CultureInfo.CurrentCulture, message, parameters));
 }
예제 #15
0
        /// <summary>
        /// Sets a property inside an object
        /// </summary>
        /// <param name="stdElement"> The <see cref="StdElement"/> with the property to be set.  </param>
        /// <param name="pathToProperty"> The path to the property to be set property.
        /// </param> <param name="newValue"> The new value. </param>
        private static void SetPropertyValue(StdElement stdElement, string pathToProperty, string newValue)
        {
            object propObject = stdElement;
            var    propType   = stdElement.GetType();

            while (pathToProperty.Contains("."))
            {
                var nextSeparator = pathToProperty.IndexOf(".", StringComparison.Ordinal);
                var propName      = pathToProperty.Substring(0, nextSeparator);
                pathToProperty = pathToProperty.Substring(nextSeparator + 1);
                if (string.IsNullOrEmpty(propName))
                {
                    continue;
                }

                var member = propType.GetProperty(propName);
                propType = member.PropertyType;

                var destinObject = member.GetValue(propObject, null);
                if (destinObject == null)
                {
                    destinObject = propType.GetConstructor(new Type[0]).Invoke(null);
                    member.SetValue(propObject, destinObject, null);
                }

                propObject = destinObject;
            }

            var memberToSet = propType.GetProperty(pathToProperty);

            // we have to deal with special type data (int, datetime) that need to be
            // converted back from string - there is no automated cast in SetValue.
            var destinationType     = memberToSet.PropertyType.Name;
            var destinationBaseType = memberToSet.PropertyType.BaseType;

            if (destinationBaseType == typeof(Enum))
            {
                destinationType = "Enum";
            }

            switch (destinationType)
            {
            case "Enum":
                memberToSet.SetValue(propObject, Enum.Parse(memberToSet.PropertyType, newValue, true), null);
                break;

            case "TimeSpan":
                memberToSet.SetValue(propObject, TimeSpan.Parse(newValue, CultureInfo.InvariantCulture), null);
                break;

            case "DateTime":
                memberToSet.SetValue(propObject, DateTime.Parse(newValue, CultureInfo.CurrentCulture), null);
                break;

            case "List`1":

                // TODO: Implement setting of List<> from string
                break;

            case "Int32":
                memberToSet.SetValue(propObject, Int32.Parse(newValue, CultureInfo.CurrentCulture), null);
                break;

            default:
                memberToSet.SetValue(propObject, newValue, null);
                break;
            }
        }
예제 #16
0
 /// <summary>
 /// Writes a single element to the list of elements; overwrites an existing element with the same id
 /// </summary>
 /// <param name="list"> The list of elements the new element should be added to </param>
 /// <param name="element"> The new element that should be added </param>
 private static void WriteElement(ICollection <StdElement> list, StdElement element)
 {
     WriteElement(list, element, false);
 }
예제 #17
0
        /// <summary>
        /// Implements the method to fill the contact with additional links to other contacts.
        /// </summary>
        /// <param name="contactToFill"> The contact to be filled. </param>
        /// <param name="baseline"> The baseline that does contain possible link targets. </param>
        /// <returns> the manipulated contact </returns>
        public override StdElement FillContacts(StdElement contactToFill, ICollection <MatchingEntry> baseline)
        {
            var contact = contactToFill as StdContact;
            const ProfileIdentifierType ProfileIdentifierType = ProfileIdentifierType.WerKenntWenUrl;
            const string ProfilePhpId = "/person/";

            if (contact == null || !contact.ExternalIdentifier.ContainsKey(ProfileIdentifierType))
            {
                return(contactToFill);
            }

            var profileIdInformation = contact.ExternalIdentifier[ProfileIdentifierType];

            if (profileIdInformation == null || string.IsNullOrWhiteSpace(profileIdInformation.Id))
            {
                return(contactToFill);
            }

            var offset = 0;
            var added  = 0;

            while (true)
            {
                this.LogProcessingEvent("reading contacts ({0})", offset);
                this.HttpRequester.ContentCredentials = this;

                // get the contact list
                var url = string.Format(
                    CultureInfo.InvariantCulture,
                    "http://www.wer-kennt-wen.de/people/friends/{0}/sort/friends/0/0/{1}",
                    profileIdInformation.Id.Replace(ProfilePhpId, string.Empty),
                    offset);

                string profileContent;
                while (true)
                {
                    profileContent = this.HttpRequester.GetContent(url, string.Format(CultureInfo.InvariantCulture, "Wkw-{0}", offset));
                    if (profileContent.Contains(@"id=""loginform"""))
                    {
                        if (!this.GetLogon())
                        {
                            return(contactToFill);
                        }

                        continue;
                    }

                    if (profileContent.Contains(WkwCaptcha))
                    {
                        this.ResolveCaptcha();
                        continue;
                    }

                    break;
                }

                var extracts = Regex.Matches(profileContent, @"\<a href=""/person/(?<profileId>[0-9a-zA-Z]*)""\>", RegexOptions.Singleline);

                // if there is no contact in list, we did reach the end
                if (extracts.Count < 3)
                {
                    break;
                }

                // create a new instance of a list of references if there is none
                contact.Contacts = contact.Contacts ?? new List <ContactReference>(extracts.Count);

                foreach (Match extract in extracts)
                {
                    var profileId = ProfilePhpId + extract.Groups["profileId"];
                    var stdId     =
                        (from x in baseline
                         where x.ProfileId.GetProfileId(ProfileIdentifierType) == profileId
                         select x.Id).FirstOrDefault();

                    // we ignore contacts we donn't know
                    if (stdId == default(Guid))
                    {
                        continue;
                    }

                    // lookup an existing entry in this contacts contact-list
                    var contactInList = (from x in contact.Contacts where x.Target == stdId select x).FirstOrDefault();

                    if (contactInList == null)
                    {
                        // add a new one if no existing entry has been found
                        contactInList = new ContactReference {
                            Target = stdId
                        };
                        contact.Contacts.Add(contactInList);
                        added++;
                    }

                    // update the flag that this entry is a private contact
                    // todo: private/business contact
                    contactInList.IsPrivateContact = true;
                }

                Thread.Sleep(new Random().Next(230, 8789));

                offset += 64; // extracts.Count;
            }

            this.LogProcessingEvent(contact, "{0} contacts found, {1} new added", offset, added);

            return(contactToFill);
        }
예제 #18
0
        /// <summary>
        /// Implements the method to fill the contact with additional links to other contacts.
        /// </summary>
        /// <param name="contactToFill"> The contact to be filled. </param>
        /// <param name="baseline"> The baseline that does contain possible link targets. </param>
        /// <returns> the manipulated contact </returns>
        public virtual StdElement FillContacts(StdElement contactToFill, ICollection <MatchingEntry> baseline)
        {
            var contact           = contactToFill as StdContact;
            var webSideParameters = this.WebSideParameters;

            var profileIdentifierType = webSideParameters.ProfileIdentifierType;

            this.personIdentifierFromContactsListExtractor = new Regex(webSideParameters.PersonIdentifierFromContactsListRegex, RegexOptions.Singleline);
            var personIdentifierExtractor = new Regex(webSideParameters.ProfileIdPartExtractor, RegexOptions.Singleline);

            if (contact == null || !contact.ExternalIdentifier.ContainsKey(profileIdentifierType))
            {
                return(contactToFill);
            }

            var profileIdInformation = contact.ExternalIdentifier[profileIdentifierType];

            if (profileIdInformation == null || string.IsNullOrWhiteSpace(profileIdInformation.Id))
            {
                return(contactToFill);
            }

            var match = personIdentifierExtractor.Match(profileIdInformation.Id);

            if (match.Groups.Count == 0)
            {
                return(contactToFill);
            }

            var identifierPart = match.Groups[1];

            var offset = 0;
            var added  = 0;

            while (true)
            {
                this.LogProcessingEvent("reading contacts (from offset {0})", offset);
                this.HttpRequester.ContentCredentials = this;

                // get the contact list
                var url = string.Format(
                    CultureInfo.InvariantCulture,
                    webSideParameters.ContactListUrl,
                    identifierPart,
                    offset);

                var profileContent = this.HttpRequester.GetContent(url);
                var loginNeeded    = webSideParameters.HttpDetectionStringLogOnNeeded.Where(profileContent.Contains).Count() > 0;
                if (loginNeeded)
                {
                    this.LogProcessingEvent(contact, "log on needed");

                    if (!this.Logon())
                    {
                        this.LogProcessingEvent(contact, "log on failed");
                        return(contactToFill);
                    }

                    profileContent = this.HttpRequester.GetContent(url);
                }

                var profileIds = this.ExtractProfileIdsFromFriendsList(profileIdInformation, profileContent);

                // if there is no contact in list, we did reach the end
                if (profileIds.Count == 0)
                {
                    break;
                }

                // create a new instance of a list of references if there is none
                added = this.AddContactIdsToStdContact(contact, profileIds, baseline, added);
                this.LogProcessingEvent(contact, "{0} contacts found, {1} added.", profileIds.Count, added);

                this.LogProcessingEvent(contact, "sleeping some time to not being identifies as a bot...");
                this.ThinkTime();

                // todo: facebook uses a page size of 64, wer-kennt-wen
                offset += 64; // extracts.Count;
            }

            this.LogProcessingEvent(contact, "{0} contacts found, {1} new added", offset, added);

            return(contactToFill);
        }
예제 #19
0
 /// <summary>
 /// Implements the interface to get more information - in this case the
 ///   related contacts from the profile
 /// </summary>
 /// <param name="contactToFill">The contact to fill.</param>
 /// <param name="baseline"> The baseline.</param>
 /// <returns>the contact with more information</returns>
 public StdElement FillContacts(StdElement contactToFill, ICollection <MatchingEntry> baseline)
 {
     return(contactToFill);
 }