internal ChangeGroup CreateChangeGroup(
            ChangeGroupService changeGroupService,
            ClearQuestMigrationContext migrationContext,
            bool isLastRevOfThisSyncCycle)
        {
            ChangeGroup changeGroup = changeGroupService.CreateChangeGroupForDeltaTable(ChangeGroupName);
            OAdEntity   record      = CQWrapper.GetEntity(CQSession, EntityDefName, EntityDispName);

            if (IsRecordHistory)
            {
                XmlDocument recordHistDesc = CreateRecordHistoryDesc(record, HistoryValue, HistoryFieldName + "::" + Version, isLastRevOfThisSyncCycle);

                changeGroup.CreateAction(WellKnownChangeActionId.Edit,
                                         this,
                                         MigrationRecordId,
                                         "",
                                         Version,
                                         "",
                                         WellKnownContentType.WorkItem.ReferenceName,
                                         recordHistDesc);
            }
            else
            {
                XmlDocument recordDesc = CreateRecordDesc(record, Version, migrationContext, isLastRevOfThisSyncCycle);

                if (Version.Equals(NewRecordVersion, StringComparison.InvariantCulture))
                {
                    changeGroup.CreateAction(WellKnownChangeActionId.Add,
                                             this,
                                             MigrationRecordId,
                                             "",
                                             Version,
                                             "",
                                             WellKnownContentType.WorkItem.ReferenceName,
                                             recordDesc);
                }
                else
                {
                    changeGroup.CreateAction(WellKnownChangeActionId.Edit,
                                             this,
                                             MigrationRecordId,
                                             "",
                                             Version,
                                             "",
                                             WellKnownContentType.WorkItem.ReferenceName,
                                             recordDesc);
                }
            }


            return(changeGroup);
        }
        private OAdEntity CreateTestEntity(OAdEntity record, ClearQuestMigrationContext migrationContext)
        {
            string entityName = CQWrapper.GetEntityDefName(record);

            if (m_perEntityTypeTestEntities.ContainsKey(entityName))
            {
                return(m_perEntityTypeTestEntities[entityName]);
            }

            var aTestEntity = CQWrapper.BuildEntity(migrationContext.UserSession, entityName);

            m_perEntityTypeTestEntities.Add(entityName, aTestEntity);

            return(aTestEntity);
        }
        public bool Update(
            ClearQuestMigrationContext migrationContext,
            Session cqSession,
            OAdEntity hostRecord,
            LinkChangeAction linkChangeAction)
        {
            if (null == linkChangeAction)
            {
                throw new ArgumentNullException("linkChangeAction");
            }

            if (!linkChangeAction.Link.LinkType.ReferenceName.Equals(REFERENCE_NAME))
            {
                throw new ArgumentException("Link type mismatch.");
            }

            string childRecEntityDefName;

            if (!ClearQuestRecordArtifactHandler.TryExtractRecordDefName(linkChangeAction.Link.TargetArtifact,
                                                                         out childRecEntityDefName))
            {
                return(false);
            }
            string childRecDispName;

            if (!ClearQuestRecordArtifactHandler.TryExtractRecordDispName(linkChangeAction.Link.TargetArtifact,
                                                                          out childRecDispName))
            {
                return(false);
            }

            OAdEntity childEntity = CQWrapper.GetEntity(cqSession, childRecEntityDefName, childRecDispName);

            if (null == childEntity)
            {
                return(false);
            }

            // check if hostRecord already has a duplicate of this childRecord
            bool duplicateAlreadyExist = HasDuplicateRecord(hostRecord, childRecEntityDefName, childRecDispName);

            // find out the child entity's current state
            // find the current state
            string childEntityDefName = CQWrapper.GetEntityDefName(childEntity);

            OAdFieldInfo aFldInfo       = CQWrapper.GetEntityFieldValue(childEntity, migrationContext.GetStateField(childEntityDefName));
            string       srcState       = CQWrapper.GetFieldValue(aFldInfo);
            OAdEntityDef childEntityDef = CQWrapper.GetEntityDef(cqSession, childEntityDefName);

            if (linkChangeAction.ChangeActionId.Equals(WellKnownChangeActionId.Add))
            {
                if (duplicateAlreadyExist)
                {
                    // [teyang] TODO
                    return(false);
                }

                string[] changeActionNames = CQUtilityMethods.FindAllActionNameByTypeAndSourceState(
                    childEntityDef,
                    srcState,
                    CQConstants.ACTION_DUPLICATE);

                string changeActionName = string.Empty;
                if (changeActionNames.Length == 0)
                {
                    // [teyang] TODO conflict
                }
                else if (changeActionNames.Length > 1)
                {
                    // [teyang] TODO conflict
                }
                else
                {
                    changeActionName = changeActionNames[0];
                }

                if (!string.IsNullOrEmpty(changeActionName))
                {
                    CQWrapper.MarkEntityAsDuplicate(cqSession, childEntity, hostRecord, changeActionName);

                    string retVal = CQWrapper.Validate(childEntity);
                    if (string.IsNullOrEmpty(retVal))
                    {
                        // [teyang] TODO conflict
                    }

                    retVal = CQWrapper.Commmit(childEntity);
                    if (string.IsNullOrEmpty(retVal))
                    {
                        // [teyang] TODO conflict
                    }
                }
            }
            else if (linkChangeAction.ChangeActionId.Equals(WellKnownChangeActionId.Delete))
            {
                if (!duplicateAlreadyExist)
                {
                    // [teyang] TODO
                    return(false);
                }

                string[] changeActionNames = CQUtilityMethods.FindAllActionNameByTypeAndSourceState(
                    childEntityDef,
                    srcState,
                    CQConstants.ACTION_UNDUPLICATE);

                string changeActionName = string.Empty;
                if (changeActionNames.Length == 0)
                {
                    // [teyang] TODO conflict
                }
                else if (changeActionNames.Length > 1)
                {
                    // [teyang] TODO conflict
                }
                else
                {
                    changeActionName = changeActionNames[0];
                }

                if (!string.IsNullOrEmpty(changeActionName))
                {
                    CQWrapper.UnmarkEntityAsDuplicate(cqSession, childEntity, changeActionName);

                    string retVal = CQWrapper.Validate(childEntity);
                    if (string.IsNullOrEmpty(retVal))
                    {
                        // [teyang] TODO conflict
                    }

                    retVal = CQWrapper.Commmit(childEntity);
                    if (string.IsNullOrEmpty(retVal))
                    {
                        // [teyang] TODO conflict
                    }
                }
            }
            else
            {
                //throw new MigrationException(TfsWITAdapterResources.ErrorUnsupportedChangeAction);
            }

            return(true);
        }
        public XmlDocument CreateRecordDesc(
            OAdEntity record,
            string versionStr,
            ClearQuestMigrationContext migrationContext,
            bool isLastRevOfThisSyncCycle)
        {
            string   lastAuthor;
            DateTime lastChangeDate;

            FindLastRevDtls(record, out lastAuthor, out lastChangeDate);

            ClearQuestRecordDescription recordDesc = new ClearQuestRecordDescription();

            recordDesc.CreateHeader(lastAuthor, lastChangeDate, MigrationRecordId, EntityDefName, versionStr, isLastRevOfThisSyncCycle);

            object[] fieldNames = (object[])CQWrapper.GetEntityFieldNames(record);
            foreach (object fldName in fieldNames)
            {
                string fieldName = (string)fldName;
                if (s_skipAlgorithm.SkipField(fieldName))
                {
                    TraceManager.TraceInformation("Skipping Field '{0}' while migrating data for Entity '{1}'",
                                                  fieldName, EntityDefName);
                    continue;
                }

                OAdFieldInfo fldInfo     = CQWrapper.GetEntityFieldValue(record, fieldName);
                int          cqFieldType = CQWrapper.GetFieldType(fldInfo);

                switch (cqFieldType)
                {
                case CQConstants.FIELD_INT:
                case CQConstants.FIELD_ID:
                case CQConstants.FIELD_SHORT_STRING:
                case CQConstants.FIELD_STATE:
                case CQConstants.FIELD_DBID:
                case CQConstants.FIELD_STATETYPE:
                case CQConstants.FIELD_RECORDTYPE:
                {
                    string fldValue = CQWrapper.GetFieldValue(fldInfo);
                    recordDesc.AddField(fieldName, string.Empty, fldValue ?? String.Empty);
                }
                break;

                case CQConstants.FIELD_MULTILINE_STRING:
                {
                    string fldValue = CQWrapper.GetFieldValue(fldInfo);

                    if (migrationContext == null ||
                        !CQStringComparer.FieldName.Equals(migrationContext.NotesLogFieldName, fieldName))
                    {
                        // non-log field
                        try
                        {
                            var aTestEntity = CreateTestEntity(record, migrationContext);

                            object[] choices = (object[])CQWrapper.GetFieldChoiceList(aTestEntity, fieldName);
                            if (choices != null && choices.Length > 0)
                            {
                                // Multi Line String with List of Allowed/Suggested Values.. replace all '\n' with comma
                                // fix for bug# 429098
                                if (fldValue != null)
                                {
                                    fldValue = fldValue.Replace("\n", ",");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            // NOTE:
                            // This feature of testing the multiline string choices create a dummy CQ record
                            // The API call CreateTestEntity requires WRITE permission to CQ
                            // If the migration account doesn't have the permission, we will simply use
                            // the field's current value
                            TraceManager.TraceInformation(
                                "Skipping retrieval of Allowed Values for field '{0}' - Write permission is needed. Error: {1}",
                                fieldName, ex.Message);
                        }

                        recordDesc.AddField(fieldName, string.Empty, fldValue);
                    }
                    else if (fldValue != null)
                    {
                        // log field

                        StringBuilder     sb    = new StringBuilder();
                        List <CQNotesLog> notes = CQNotesLog.Parse(fldValue);
                        foreach (CQNotesLog note in notes)
                        {
                            if (string.IsNullOrEmpty(note.Content) ||
                                note.Content.Contains(Constants.PlatformCommentSuffixMarker))
                            {
                                // skip empty logs or those generated by this adapter
                                continue;
                            }

                            if (note.Header.ChangeDate.CompareTo(migrationContext.CurrentHWMBaseLine) <= 0)
                            {
                                // skip the logs before the hwm
                                continue;
                            }

                            sb.AppendFormat("{0} {1} {2}\n",
                                            CQNotesLogHeader.NotesLogHeaderIdentifier,
                                            note.HeaderString,
                                            CQNotesLogHeader.NotesLogHeaderIdentifier);
                            sb.AppendLine(note.Content);
                        }

                        string extractedLog = sb.ToString();

                        if (!string.IsNullOrEmpty(extractedLog))
                        {
                            recordDesc.AddField(fieldName, string.Empty, extractedLog);
                        }
                    }
                }
                break;

                case CQConstants.FIELD_DATE_TIME:
                {
                    string fldValue = CQWrapper.GetFieldValue(fldInfo);
                    if (fldValue != null)
                    {
                        // the time returned from CQ API is the local time..
                        DateTime fldVal = DateTime.Parse(fldValue, CultureInfo.CurrentCulture);

                        //convert it in UTC
                        DateTime utcTime = UtilityMethods.ConvertLocalToUTC(fldVal);
                        TraceManager.TraceInformation("Field [{0}], CQ Time [{1}], UTC Time [{2}]",
                                                      fieldName, fldVal.ToString(), utcTime.ToString());

                        recordDesc.AddField(fieldName, string.Empty, utcTime.ToString());
                    }
                    else
                    {
                        recordDesc.AddField(fieldName, string.Empty, string.Empty);
                    }
                }
                break;

                case CQConstants.FIELD_REFERENCE:
                {
                    // get the current entity def handle
                    OAdEntityDef curEntityDef  = CQWrapper.GetEntityDef(CQSession, EntityDefName);
                    OAdEntityDef refEntityDef  = CQWrapper.GetFieldReferenceEntityDef(curEntityDef, fieldName);
                    string       refEntityName = CQWrapper.GetEntityDefName(refEntityDef);

                    if (CQWrapper.GetFieldValueStatus(fldInfo) == (int)CQConstants.FieldStatus.HAS_VALUE)
                    {
                        // single value required
                        string refFldVal = CQWrapper.GetFieldValue(fldInfo);
                        recordDesc.AddField(fieldName, string.Empty, refFldVal ?? string.Empty);
                    }
                    else
                    {
                        recordDesc.AddField(fieldName, string.Empty, string.Empty);
                    }
                }
                break;

                case CQConstants.FIELD_REFERENCE_LIST:
                {
                    // get the current entity def handle
                    OAdEntityDef curEntityDef  = CQWrapper.GetEntityDef(CQSession, EntityDefName);
                    OAdEntityDef refEntityDef  = CQWrapper.GetFieldReferenceEntityDef(curEntityDef, fieldName);
                    string       refEntityName = CQWrapper.GetEntityDefName(refEntityDef);

                    object[] refFldValues = CQWrapper.GetFieldValueAsList(fldInfo);
                    if (refFldValues != null)
                    {
                        StringBuilder userList = new StringBuilder();
                        for (int valueIndex = 0; valueIndex < refFldValues.Length; valueIndex++)
                        {
                            object refFldObj = refFldValues[valueIndex];
                            if (valueIndex > 0)
                            {
                                userList.Append(",");
                            }

                            userList.Append((string)refFldObj);
                        }
                        recordDesc.AddField(fieldName, string.Empty, userList.ToString());
                    }
                    else
                    {
                        recordDesc.AddField(fieldName, string.Empty, string.Empty);
                    }
                }
                break;

                case CQConstants.FIELD_ATTACHMENT_LIST:
                case CQConstants.FIELD_JOURNAL:
                    TraceManager.TraceInformation("Skipping the Field migration for Internal Field Type '{0}'",
                                                  cqFieldType);
                    // not migrating these fields as they are CQ internal fields
                    continue;

                default:
                    TraceManager.TraceInformation("Skipping the Field migration for Unkknown Field Type '{0}'",
                                                  cqFieldType);
                    break;
                } // end of switch cqFieldType
            }     // end of foreach fieldNames


            return(recordDesc.DescriptionDocument);
        }
 public bool Update(ClearQuestMigrationContext migrationContext, ClearQuestOleServer.Session session, ClearQuestOleServer.OAdEntity hostRecord, LinkChangeAction linkChangeAction)
 {
     // this link type is fabricated. Do nothing for submission.
     linkChangeAction.Status = LinkChangeAction.LinkChangeActionStatus.Completed;
     return(true);
 }
        public bool Update(
            ClearQuestMigrationContext migrationContext,
            Session session,
            OAdEntity hostRecord,
            LinkChangeAction linkChangeAction)
        {
            if (null == linkChangeAction)
            {
                throw new ArgumentNullException("linkChangeAction");
            }

            if (!linkChangeAction.Link.LinkType.ReferenceName.StartsWith(ReferenceNameQualifier))
            {
                throw new ArgumentException("Link type mismatch.");
            }

            string childRecEntityDefName;

            if (!ClearQuestRecordArtifactHandler.TryExtractRecordDefName(linkChangeAction.Link.TargetArtifact,
                                                                         out childRecEntityDefName))
            {
                return(false);
            }
            string childRecDispName;

            if (!ClearQuestRecordArtifactHandler.TryExtractRecordDispName(linkChangeAction.Link.TargetArtifact,
                                                                          out childRecDispName))
            {
                return(false);
            }

            string hostRecEntityDefName = CQWrapper.GetEntityDefName(hostRecord);

            if (string.IsNullOrEmpty(hostRecEntityDefName) ||
                !CQStringComparer.EntityName.Equals(hostRecEntityDefName, this.m_hostRecordType))
            {
                return(false);
            }

            string refFieldName = linkChangeAction.Link.LinkType.ReferenceName.Substring(ReferenceNameQualifier.Length);

            if (string.IsNullOrEmpty(refFieldName))
            {
                return(false);
            }

            // retrieve reference field information
            OAdFieldInfo refFieldInfo = CQWrapper.GetEntityFieldValue(hostRecord, refFieldName);
            int          cqFieldType  = CQWrapper.GetFieldType(refFieldInfo);

            if (cqFieldType != CQConstants.FIELD_REFERENCE)
            {
                // the field is not of the reference type

                // [teyang] TODO conflict?
                return(false);
            }

            // get the current entity def
            OAdEntityDef hostRecordEntityDef      = CQWrapper.GetEntityDef(session, CQWrapper.GetEntityDefName(hostRecord));
            OAdEntityDef childRecordEntityDef     = CQWrapper.GetFieldReferenceEntityDef(hostRecordEntityDef, refFieldName);
            string       childRecordEntityDefName = CQWrapper.GetEntityDefName(childRecordEntityDef);

            if (!CQStringComparer.EntityName.Equals(childRecordEntityDefName, childRecEntityDefName))
            {
                // the field is not designated to hold reference to the EntityType of the target artifact

                // [teyang] TODO conflict?
                return(false);
            }

            int valueStatus = CQWrapper.GetFieldValueStatus(refFieldInfo);

            if (valueStatus == (int)CQConstants.FieldStatus.HAS_VALUE)
            {
                // the field already has a reference value set

                // single value required
                string refFldVal = CQWrapper.GetFieldValue(refFieldInfo);
                if (CQStringComparer.RecordName.Equals(refFldVal, childRecDispName))
                {
                    // the target artifact is already referenced in the field

                    // [teyang] TODO conflict?
                    return(false);
                }
                else
                {
                    // field currently holds a reference to another entity

                    // [teyang] TODO conflict?
                    return(false);
                }
            }

            string[] modifyActionNames = CQUtilityMethods.FindAllChangeActionNamesByType(
                session, hostRecord, CQConstants.ACTION_MODIFY);

            if (modifyActionNames.Length == 0)
            {
                // [teyang] TODO conflict?
                return(false);
            }
            else if (modifyActionNames.Length > 1)
            {
                // [teyang] TODO conflict?
                return(false);
            }
            else
            {
                string modAction = modifyActionNames[0];

                CQWrapper.EditEntity(session, hostRecord, modAction);

                string retVal = CQWrapper.SetFieldValue(hostRecord, refFieldName, childRecDispName);

                retVal = CQWrapper.Validate(hostRecord);
                if (string.IsNullOrEmpty(retVal))
                {
                    // [teyang] TODO conflict
                    return(false);
                }

                retVal = CQWrapper.Commmit(hostRecord);
                if (string.IsNullOrEmpty(retVal))
                {
                    // [teyang] TODO conflict
                    return(false);
                }

                return(true);
            }
        }