bool HasDuplicateRecord(
            OAdEntity hostRecord,
            string childRecordEntityTypeName,
            string childRecordDisplayName)
        {
            // check if hostRecord already has a duplicate of this childRecord
            if (!CQWrapper.HasDuplicates(hostRecord))
            {
                return(false);
            }

            object[] dupRecObjs = CQWrapper.GetDuplicates(hostRecord) as object[];
            foreach (object dupRecObj in dupRecObjs)
            {
                OAdLink aLink = dupRecObj as OAdLink;
                if (null != aLink)
                {
                    OAdEntity record = CQWrapper.GetChildEntity(aLink) as OAdEntity;
                    if (null != record)
                    {
                        string recDispName      = CQWrapper.GetEntityDisplayName(record);
                        string recEntityDefName = CQWrapper.GetEntityDefName(record);
                        if (CQStringComparer.EntityName.Equals(recEntityDefName, childRecordEntityTypeName) &&
                            CQStringComparer.RecordName.Equals(recDispName, childRecordDisplayName))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Parametrized Constructor for instantiating schema object
        /// No other CTors are provided as these values are required to start with
        /// </summary>
        /// <param name="xmlFile">Name of the target schema xml file</param>
        /// <param name="cqSess">Handle to valid CQ session</param>
        /// <param name="entityDef">Handle to valid CQ Entity Definition</param>
        public WITDXMLGenerator(string schemaXmlFile,
                                string fieldMapXmlFile,
                                Session cqSess,
                                OAdEntityDef entityDef,
                                VSTSConnection vstsConn)
        {
            Logger.EnteredMethod(LogSource.CQ, schemaXmlFile, fieldMapXmlFile,
                                 cqSess, entityDef);

            // create instance of WITDFieldMap to store field mappings
            witdFieldMap = new WITFieldMappings();

            // create instance of WITDSchema to store WITD schema
            witdSchema = new WITDSchema();
            witdSchema.SetApplication(Application.Workitemtypeeditor);

            // set the VSTS connection handle for finding the unique fields in VSTS system
            WITDSchema.VstsConn = vstsConn;

            // store file name to be used later to generate xml
            schemaXMLFileName   = schemaXmlFile;
            fieldMapXMLFileName = fieldMapXmlFile;

            cqEntityDef = entityDef;
            cqSession   = cqSess;
            cqEntity    = CQWrapper.BuildEntity(cqSession, CQWrapper.GetEntityDefName(cqEntityDef));

            Logger.ExitingMethod(LogSource.CQ);
        }
        private void EditRecord(IMigrationAction action, ConversionResult convRslt)
        {
            string ownerRecordDisplayName = FindTargetWorkItemId(action);
            string ownerRecordType        = UtilityMethods.ExtractRecordType(action);
            string changeAuthor           = UtilityMethods.ExtractAuthor(action);

            // find the entity
            OAdEntity entity = CQWrapper.GetEntity(m_userSession, ownerRecordType, ownerRecordDisplayName);

            XmlNodeList columns = action.MigrationActionDescription.SelectNodes("/WorkItemChanges/Columns/Column");

            if (null == columns)
            {
                throw new MigrationException(ClearQuestResource.ClearQuest_Error_InvalidActionDescription, action.ActionId);
            }

            string  stateField            = m_migrationContext.GetStateField(ownerRecordType);
            XmlNode stateTransitFieldNode = UtilityMethods.ExtractSingleFieldNodeFromMigrationDescription(
                action.MigrationActionDescription, stateField);
            bool containsStateTransit = (stateTransitFieldNode != null);

            if (containsStateTransit)
            {
                // change contains state transition
                List <string> skipFields;
                if (ChangeRecordState(entity, action, convRslt, stateTransitFieldNode, out skipFields))
                {
                    ModifyRecordContent(entity, action, convRslt, skipFields);
                }
            }
            else
            {
                ModifyRecordContent(entity, action, convRslt, null);
            }
        }
        /// <summary>
        /// Download the XML document describing this CQ record
        /// </summary>
        /// <remarks>
        /// EntityDisplayName, EntityDefName and CQSession properties are needed to retrieve record details
        /// </remarks>
        /// <param name="localPath"></param>
        public void Download(string localPath)
        {
            if (null == CQSession)
            {
                throw new InvalidOperationException("CQSession == NULL");
            }

            if (File.Exists(localPath))
            {
                File.Delete(localPath);
            }

            if (IsRecordHistory)
            {
                // download the record history
                OAdEntity   record         = CQWrapper.GetEntity(CQSession, EntityDefName, EntityDispName);
                XmlDocument recordHistDesc = CreateRecordHistoryDesc(record, HistoryValue, HistoryFieldName + "::" + Version, false);
                recordHistDesc.Save(localPath);
            }
            else
            {
                // download the *complete* record content (field + value)
                OAdEntity   record     = CQWrapper.GetEntity(CQSession, EntityDefName, EntityDispName);
                XmlDocument recordDesc = CreateRecordDesc(record, Version, null, false);
                recordDesc.Save(localPath);
            }
        }
예제 #5
0
        public ClearQuestAttachmentItem(
            OAdEntity aHostRecord,
            OAdAttachmentField aHostField,
            OAdAttachment aAttachment,
            ClearQuestConnectionConfig connectionConfiguration)
        {
            // gather info to query for the record
            EntityDefName  = CQWrapper.GetEntityDefName(aHostRecord);
            EntityDispName = CQWrapper.GetEntityDisplayName(aHostRecord);

            // gather info to query for attachment field
            FieldName = CQWrapper.GetAttachmentFieldName(aHostField);

            string name;
            string comment;
            string dispName;
            int    fileSize;

            CQWrapper.GetAttachmentMetadata(aAttachment,
                                            out name,
                                            out comment,
                                            out dispName,
                                            out fileSize);

            Name                    = name;
            Comment                 = comment;
            DisplayName             = dispName;
            Length                  = (long)fileSize; // fileSize returned by CQ API is in bytes
            ConnectionConfiguration = connectionConfiguration;
        }
예제 #6
0
        public void UpdateAttachment(int workItemId, WITAttachmentChangeAction action)
        {
            // find the entity
            OAdEntity entity = GetEntityByDBId(workItemId);

            // mark entity to be editable
            CQWrapper.EditEntity(m_session, entity, "Modify");

            foreach (WITAttachment attachment in action.Attachments)
            {
                if (attachment.ActionType == AttachmentChangeActionType.Add)
                {
                    AddAttachment(entity, attachment.FileName, attachment.Comment);
                }
                else if (attachment.ActionType == AttachmentChangeActionType.Delete)
                {
                    throw new NotImplementedException("DeleteAttachment is not supported yet");
                }
                // Update attachment comment
                else if (attachment.ActionType == AttachmentChangeActionType.Edit)
                {
                    throw new NotImplementedException("EditAttachment is not supported yet");
                }
            }

            SaveWorkItem(entity);
        }
        public void ExtractLinkChangeActions(
            Session session,
            OAdEntity hostRecord,
            List <LinkChangeGroup> linkChangeGroups)
        {
            string hostRecDispName      = CQWrapper.GetEntityDisplayName(hostRecord);
            string hostRecEntityDefName = CQWrapper.GetEntityDefName(hostRecord);
            string hostRecMigrItemId    = UtilityMethods.CreateCQRecordMigrationItemId(hostRecEntityDefName, hostRecDispName);

            var linkChangeGroup = new LinkChangeGroup(hostRecMigrItemId, LinkChangeGroup.LinkChangeGroupStatus.Created, false);

            if (!CQWrapper.HasDuplicates(hostRecord))
            {
                return;
            }

            object[] dupRecObjs = CQWrapper.GetDuplicates(hostRecord) as object[];

            foreach (object dupRecObj in dupRecObjs)
            {
                OAdLink aLink = dupRecObj as OAdLink;

                if (null != aLink)
                {
                    OAdEntity childRecord = CQWrapper.GetChildEntity(aLink) as OAdEntity;
                    if (null != childRecord)
                    {
                        string childRecDispName      = CQWrapper.GetEntityDisplayName(childRecord);
                        string childRecEntityDefName = CQWrapper.GetEntityDefName(childRecord);
                        string childRecMigrItemId    = UtilityMethods.CreateCQRecordMigrationItemId(childRecEntityDefName, childRecDispName);

                        ILink dupLink = new ArtifactLink(hostRecDispName,
                                                         new Artifact(hostRecMigrItemId, new ClearQuestRecordArtifactType()),
                                                         new Artifact(childRecMigrItemId, new ClearQuestRecordArtifactType()),
                                                         string.Empty,
                                                         this);
                        LinkChangeAction action = new LinkChangeAction(WellKnownChangeActionId.Add,
                                                                       dupLink,
                                                                       LinkChangeAction.LinkChangeActionStatus.Created,
                                                                       false);
                        linkChangeGroup.AddChangeAction(action);
                    }
                    else
                    {
                        // [teyang] TODO replace debug assertion with a conflict?
                        Debug.Assert(false, "null == childRecord");
                    }
                }
                else
                {
                    // [teyang] TODO replace debug assertion with a conflict?
                    Debug.Assert(false, "null == aLink");
                }
            }

            linkChangeGroups.Add(linkChangeGroup);
        }
        public ClearQuestRecordItem(OAdEntity aRecord, string version)
        {
            Initialize(CQWrapper.GetEntityDefName(aRecord),
                       CQWrapper.GetEntityDisplayName(aRecord),
                       string.Empty,
                       false);

            Version = version;
        }
        private void SetRecordEditable(OAdEntity cqEntity)
        {
            string       entityDefName       = CQWrapper.GetEntityDefName(cqEntity);
            OAdEntityDef entityDef           = CQWrapper.GetEntityDef(m_userSession, entityDefName);
            string       modifyActionDefName = FindCQActionDefName(entityDef, CQConstants.ACTION_MODIFY);

            // open the record with the modify action
            CQWrapper.EditEntity(m_userSession, cqEntity, modifyActionDefName);
        }
예제 #10
0
        public ChangeSummary GetSummaryOfChangesSince(string lastProcessedChangeItemId, List <string> filterStrings)
        {
            // lastProcessedChangeItemId is in a form such as "Defect:UCM0100019437:history:0"
            // Parse it and query for the record with that Id to get the time is was last changed
            string[]  identity            = UtilityMethods.ParseCQRecordMigrationItemId(lastProcessedChangeItemId);
            OAdEntity lastProcessedRecord = CQWrapper.GetEntity(m_userSession, identity[0], identity[1]);
            string    lastProcessedRecordAuthor;
            DateTime  lastProcessedRecordChangeDate;

            ClearQuestRecordItem.FindLastRevDtls(lastProcessedRecord, out lastProcessedRecordAuthor, out lastProcessedRecordChangeDate);

            string lastProcessedRecordChangeDateStr = lastProcessedRecordChangeDate.ToString("u").Replace("Z", ""); // using "ISO 8601" DateTime string format

            if (lastProcessedRecordChangeDateStr.LastIndexOf('.') >= 0)
            {
                lastProcessedRecordChangeDateStr = lastProcessedRecordChangeDateStr.Substring(0, lastProcessedRecordChangeDateStr.LastIndexOf('.')); // drop the millisec
            }

            ChangeSummary changeSummary = new ChangeSummary();

            changeSummary.ChangeCount = 0;
            changeSummary.FirstChangeModifiedTimeUtc = DateTime.MinValue;

            foreach (CQRecordFilter filter in m_filters)
            {
                CQRecordQueryBase recordQuery =
                    CQRecordQueryFactory.CreatQuery(m_userSession, filter, lastProcessedRecordChangeDateStr, this);

                foreach (OAdEntity record in recordQuery)
                {
                    // HACK HACK
                    if (record != null) // this if check is HACK
                    {
                        DateTime lastChangeDate;
                        string   lastAuthor;
                        ClearQuestRecordItem.FindLastRevDtls(record, out lastAuthor, out lastChangeDate);

                        // Make sure the lastChangeDate on this record is after the lastProcessedRecordChangeDate before counting it in the backclog
                        // because the query issued above is imprecise because the milliseconds are dropped
                        if (lastChangeDate > lastProcessedRecordChangeDate)
                        {
                            changeSummary.ChangeCount++;
                            DateTime lastChangeDateUtc = lastChangeDate.ToUniversalTime();
                            if (changeSummary.FirstChangeModifiedTimeUtc == DateTime.MinValue ||
                                lastChangeDateUtc < changeSummary.FirstChangeModifiedTimeUtc)
                            {
                                changeSummary.FirstChangeModifiedTimeUtc = lastChangeDateUtc;
                            }
                        }
                    }
                }
            }

            return(changeSummary);
        }
예제 #11
0
 internal static void Revert(OAdEntity cqEntity)
 {
     try
     {
         cqEntity.Revert();
     }
     catch (COMException ex)
     {
         InteropErrorHandler.HandleCQException(ex);
     }
 }
예제 #12
0
        private void SaveWorkItem(OAdEntity entity)
        {
            string retVal = CQWrapper.Validate(entity);

            Trace.WriteIf(!string.IsNullOrEmpty(retVal), "retVal = " + retVal);
            Assert.IsTrue(string.IsNullOrEmpty(retVal), "retVal is not empty after validate");

            retVal = CQWrapper.Commmit(entity);
            Trace.WriteIf(!string.IsNullOrEmpty(retVal), "retVal = " + retVal);
            Assert.IsTrue(string.IsNullOrEmpty(retVal), "retVal is not empty after commit");
        }
예제 #13
0
 internal static void EditEntity(Session cqSession, OAdEntity cqEntity, string actionName)
 {
     try
     {
         cqSession.EditEntity(cqEntity, actionName);
     }
     catch (COMException ex)
     {
         InteropErrorHandler.HandleCQException(ex);
     }
 }
        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 bool SetMandatoryFields(IMigrationAction action, ref OAdEntity newRecord, out List <string> processedFields)
        {
            XmlNodeList columns = action.MigrationActionDescription.SelectNodes("/WorkItemChanges/Columns/Column");

            if (null == columns)
            {
                throw new MigrationException(ClearQuestResource.ClearQuest_Error_InvalidActionDescription, action.ActionId);
            }

            StringBuilder updateLog = new StringBuilder();

            PrintUpdateLogHeader(action, updateLog);
            processedFields = new List <string>();

            foreach (XmlNode columnData in columns)
            {
                string stringVal = columnData.FirstChild.InnerText;
                string fieldName = columnData.Attributes["ReferenceName"].Value;

                Debug.Assert(!string.IsNullOrEmpty(fieldName),
                             "Field ReferenceName is absent in the Migration Description");


                OAdFieldInfo aFieldInfo        = CQWrapper.GetEntityFieldValue(newRecord, fieldName);
                int          fieldRequiredness = CQWrapper.GetRequiredness(aFieldInfo);
                if (fieldRequiredness != CQConstants.MANDATORY)
                {
                    // skipping all non-mandatory fields
                    continue;
                }

                string originalFieldValue = CQWrapper.GetFieldValue(aFieldInfo);

                int attempt1Count = 0;
                if (!SetFieldValue(action, newRecord, fieldName, stringVal, ref attempt1Count))
                {
                    return(false);
                }
                AddFieldToUpdateLog(fieldName, stringVal, updateLog);
                processedFields.Add(fieldName);
            }

            AddLineToUpdateLog(updateLog);
            int attempt2Count = 0;

            if (!SetFieldValue(action, newRecord, NoteEntryFieldName, updateLog.ToString(), ref attempt2Count))
            {
                return(false);
            }

            return(true);
        }
예제 #16
0
        public void BatchSubmitLinkChange(LinkChangeGroup linkChanges)
        {
            if (linkChanges.Actions.Count == 0)
            {
                linkChanges.Status = LinkChangeGroup.LinkChangeGroupStatus.Completed;
                return;
            }

            // group changes by work item Id
            Dictionary <string, List <LinkChangeAction> > perRecordLinkChanges = RegroupLinkChangeActions(linkChanges);

            WorkItemLinkStore relatedArtifactsStore = new WorkItemLinkStore(m_configurationService.SourceId);

            // batch-submit links of each cq record
            bool successForAllActions = true;

            foreach (var perWorkItemLinkChange in perRecordLinkChanges)
            {
                string[]  identity   = UtilityMethods.ParseCQRecordMigrationItemId(perWorkItemLinkChange.Key);
                OAdEntity hostEntity = CQWrapper.GetEntity(m_userSession, identity[0], identity[1]);

                foreach (LinkChangeAction linkChangeAction in perWorkItemLinkChange.Value)
                {
                    if (linkChangeAction.Status != LinkChangeAction.LinkChangeActionStatus.ReadyForMigration ||
                        linkChangeAction.IsConflicted)
                    {
                        continue;
                    }

                    var handler = linkChangeAction.Link.LinkType as ILinkHandler;
                    Debug.Assert(null != handler, "linktype is not an ILinkHandler");
                    if (!handler.Update(m_migrationContext, m_userSession, hostEntity, linkChangeAction))
                    {
                        successForAllActions = false;
                        // [teyang] todo conflict handling
                        linkChangeAction.Status       = LinkChangeAction.LinkChangeActionStatus.Completed;
                        linkChangeAction.IsConflicted = true;
                        TraceManager.TraceError("Failed processing link change action: {0} linked to {1}",
                                                linkChangeAction.Link.SourceArtifact.Uri,
                                                linkChangeAction.Link.TargetArtifact.Uri);
                    }
                    else
                    {
                        MarkLinkChangeActionCompleted(linkChangeAction, relatedArtifactsStore);
                    }
                }
            }

            linkChanges.Status = successForAllActions
                                 ? LinkChangeGroup.LinkChangeGroupStatus.Completed
                                 : LinkChangeGroup.LinkChangeGroupStatus.ReadyForMigration;
        }
예제 #17
0
        private void SetFieldValue(OAdEntity entity, string fieldName, string fieldValue)
        {
            if (string.IsNullOrEmpty(fieldValue))
            {
                return;
            }

            string retVal = CQWrapper.SetFieldValue(entity, fieldName, fieldValue);

            Trace.WriteIf(!string.IsNullOrEmpty(retVal), "retVal = " + retVal);
            Assert.IsTrue(string.IsNullOrEmpty(retVal),
                          string.Format("SetFiledValue returned non-empty result : {0}, {1}", fieldName, fieldValue));
        }
예제 #18
0
        internal static int GetEntityFieldRequiredness(OAdEntity cqEntity, string fldName)
        {
            int retval = 0;

            try
            {
                retval = cqEntity.GetFieldRequiredness(fldName);
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
예제 #19
0
        internal static string GetEntityDefName(OAdEntity cqEntity)
        {
            string entityDefName = null;

            try
            {
                entityDefName = cqEntity.GetEntityDefName();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(entityDefName);
        }
예제 #20
0
        public static string[] FindAllChangeActionNamesByType(
            Session userSession,
            OAdEntity entity,
            int changeType)
        {
            // find the entity type
            OAdEntityDef entityDef = CQWrapper.GetEntityDef(userSession, CQWrapper.GetEntityDefName(entity));

            // find the MODIFY action def name to open the record
            object[] actionDefNames      = CQWrapper.GetActionDefNames(entityDef) as object[];
            string[] allValidActionNames = CQUtilityMethods.FindActionNameByType(entityDef, actionDefNames, changeType);

            return(allValidActionNames);
        }
예제 #21
0
        internal static object GetFieldChoiceList(OAdEntity cqEntity, string fldName)
        {
            object choices = null;

            try
            {
                choices = cqEntity.GetFieldChoiceList(fldName);
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(choices);
        }
예제 #22
0
        internal static int GetFieldChoiceType(OAdEntity cqEntity, string fldName)
        {
            int choice = 0;

            try
            {
                choice = cqEntity.GetFieldChoiceType(fldName);
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(choice);
        }
예제 #23
0
        internal static object GetEntityFieldNames(OAdEntity cqEntity)
        {
            object fldNames = null;

            try
            {
                fldNames = cqEntity.GetFieldNames();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(fldNames);
        }
예제 #24
0
        internal static object GetDuplicates(OAdEntity cqEntity)
        {
            object retval = null;

            try
            {
                retval = cqEntity.GetDuplicates();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
예제 #25
0
        internal static int GetEntityDbId(OAdEntity cqEntity)
        {
            int retVal = 0;

            try
            {
                retVal = cqEntity.GetDbId();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retVal);
        }
예제 #26
0
        internal static bool HasDuplicates(OAdEntity cqEntity)
        {
            bool retval = false;

            try
            {
                retval = cqEntity.HasDuplicates();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
예제 #27
0
        internal static string GetOriginalEntityId(OAdEntity cqEntity)
        {
            string retval = null;

            try
            {
                retval = cqEntity.GetOriginalId();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
예제 #28
0
        internal static OAdEntity BuildEntity(Session cqSession, string entitydef_name)
        {
            OAdEntity entity = null;

            try
            {
                entity = (OAdEntity)cqSession.BuildEntity(entitydef_name);
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(entity);
        }
예제 #29
0
        internal static OAdEntity GetOriginalEntity(OAdEntity cqEntity)
        {
            OAdEntity retval = null;

            try
            {
                retval = (OAdEntity)cqEntity.GetOriginal();
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
예제 #30
0
        internal static OAdFieldInfo GetEntityFieldValue(OAdEntity cqEntity, string fldName)
        {
            OAdFieldInfo retval = null;

            try
            {
                retval = (OAdFieldInfo)cqEntity.GetFieldValue(fldName);
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }