Пример #1
0
        internal static OAdAttachmentField AttachmentsFieldsItem(OAdAttachmentFields attFields, ref object item)
        {
            OAdAttachmentField retval = null;

            try
            {
                retval = (OAdAttachmentField)attFields.item(ref item);
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
Пример #2
0
        internal static int AttachmentsFieldsCount(OAdAttachmentFields attFields)
        {
            int retval = 0;

            try
            {
                retval = attFields.Count;
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(retval);
        }
Пример #3
0
        internal static OAdAttachmentFields GetAttachmentFields(OAdEntity cqEntity)
        {
            OAdAttachmentFields attFields = null;

            try
            {
                attFields = (OAdAttachmentFields)cqEntity.AttachmentFields;
            }
            catch (COMException ex)
            {
                InteropErrorHandler.HandleCQException(ex);
            }
            return(attFields);
        }
        private bool AttachmentExists(
            OAdEntity entity,
            string attName,
            string attComment,
            string lengthStr)
        {
            OAdAttachmentFields aAttachmentFields = CQWrapper.GetAttachmentFields(entity);

            for (int aAttachmentFieldsIndex = 0;
                 aAttachmentFieldsIndex < CQWrapper.AttachmentsFieldsCount(aAttachmentFields);
                 aAttachmentFieldsIndex++)
            {
                object             ob = (object)aAttachmentFieldsIndex;
                OAdAttachmentField aAttachmentField = CQWrapper.AttachmentsFieldsItem(aAttachmentFields, ref ob);

                // process all attachments
                OAdAttachments attachments = CQWrapper.GetAttachments(aAttachmentField);
                for (int attachmentIndex = 0;
                     attachmentIndex < CQWrapper.AttachmentsCount(attachments);
                     attachmentIndex++)
                {
                    object        obIndex     = (object)attachmentIndex;
                    OAdAttachment aAttachment = CQWrapper.AttachmentsItem(attachments, ref obIndex);

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

                    if (attName.Equals(name) && attComment.Equals(comment) && long.Parse(lengthStr).Equals((long)fileSize))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #5
0
        private void ComputeDeltaPerRecord(
            OAdEntity aRecord)
        {
            OAdEntityDef aEntityDef       = CQWrapper.GetEntityDef(m_userSession, CQWrapper.GetEntityDefName(aRecord));
            string       recordDispName   = CQWrapper.GetEntityDisplayName(aRecord);
            string       recordEntDefName = CQWrapper.GetEntityDefName(aRecord);

            #region process history

            bool recordContentIsModified = false;
            bool maybeNewRecord          = false;
            Dictionary <string, List <ClearQuestRecordItem> > historyDelta = new Dictionary <string, List <ClearQuestRecordItem> >();
            Dictionary <string, int> perHistoryFieldLastIndex = new Dictionary <string, int>();   // needed for updating processed delta

            // find all history fields
            OAdHistoryFields aHistFields = CQWrapper.GetHistoryFields(aRecord);
            int  historyFldCount         = CQWrapper.HistoryFieldsCount(aHistFields);
            bool containsNewHistory      = false;
            for (int histFldIndex = 0; histFldIndex < historyFldCount; histFldIndex++)
            {
                object          ob               = (object)histFldIndex;
                OAdHistoryField aHistoryField    = CQWrapper.HistoryFieldsItem(aHistFields, ref ob);
                string          historyFieldName = CQWrapper.GetHistoryFieldName(aHistoryField);

                // find last processed history entry for this history field
                string lookupItemId   = CQDeltaComputationProgressLookupService.CreateHistoryItemId(recordEntDefName, recordDispName, historyFieldName);
                int    startHistIndex = 1 + DeltaComputeProgressService.GetLastProcessedItemVersion(lookupItemId);

                // find all history in a particular history field
                int historyCount = CQWrapper.HistoryFieldHistoriesCount(aHistoryField);
                for (int histIndex = startHistIndex; histIndex < historyCount; histIndex++)
                {
                    object     obHistIndex = (object)histIndex;
                    OAdHistory aHistory    = CQWrapper.HistoryFieldHistoriesItem(aHistoryField, ref obHistIndex);
                    CQHistory  cqHistory   = new CQHistory(aHistory);

                    CQMigrationItem migrationItem = new CQHistoryMigrationItem(recordDispName, historyFieldName, histIndex);

                    if (TranslationService.IsSyncGeneratedItemVersion(ClearQuestRecordItem.GetMigrationRecordId(recordEntDefName, recordDispName),
                                                                      migrationItem.MigrationItemVersion,
                                                                      m_configurationService.SourceId))
                    {
                        continue;
                    }

                    if (histIndex == 0)
                    {
                        maybeNewRecord = true;
                    }

                    // add unprocessed history fields for processing
                    if (!historyDelta.ContainsKey(historyFieldName))
                    {
                        historyDelta.Add(historyFieldName, new List <ClearQuestRecordItem>(historyCount));
                    }
                    historyDelta[aHistoryField.fieldname].Add(new ClearQuestRecordItem(aRecord, aHistory, historyFieldName, histIndex.ToString()));
                    containsNewHistory = true;

                    // based on action type, we decide whether content change is needed
                    int actionType = CQWrapper.GetActionDefType(aEntityDef, cqHistory.Action);
                    switch (actionType)
                    {
                    case CQConstants.ACTION_SUBMIT:
                        break;

                    case CQConstants.ACTION_MODIFY:
                        recordContentIsModified = true;
                        break;

                    case CQConstants.ACTION_CHANGE:
                        break;

                    case CQConstants.ACTION_DUPLICATE:
                        break;

                    case CQConstants.ACTION_UNDUPLICATE:
                        break;

                    case CQConstants.ACTION_IMPORT:
                        break;

                    case CQConstants.ACTION_DELETE:
                        TraceManager.TraceInformation(ClearQuestResource.ClearQuest_Msg_RecordDeleted, recordEntDefName, recordDispName);
                        break;

                    case CQConstants.ACTION_BASE:
                        break;

                    case CQConstants.ACTION_RECORD_SCRIPT_ALIAS:
                        break;
                    }
                }

                perHistoryFieldLastIndex.Add(historyFieldName, historyCount - 1);
            }

            #endregion

            #region generate delta for content and history

            if (maybeNewRecord || recordContentIsModified)
            {
                // the first revision, i.e. "Submit", of a CQ record is always hard-coded to be '1'
                CQMigrationItem contentMigrationAction = new CQMigrationItem(recordDispName, ClearQuestRecordItem.NewRecordVersion);
                bool            isNewRecord            = false;
                if (maybeNewRecord)
                {
                    isNewRecord = !(DeltaComputeProgressService.IsMigrationItemProcessed(recordDispName, ClearQuestRecordItem.NewRecordVersionValue));
                }

                if (!isNewRecord)
                {
                    // all subsequent record "MODIFICATIONs" are hard-coded to be "update@<Now.Ticks>"
                    contentMigrationAction.MigrationItemVersion = ClearQuestRecordItem.RecordUpdateVersion + "@" + DateTime.Now.Ticks;
                }

                ClearQuestRecordItem recordContentItem = new ClearQuestRecordItem(aRecord, contentMigrationAction.MigrationItemVersion);
                recordContentItem.CQSession = m_userSession;
                recordContentItem.Version   = contentMigrationAction.MigrationItemVersion;
                ChangeGroup contentChangeGroup = recordContentItem.CreateChangeGroup(
                    m_changeGroupService, m_migrationContext, isNewRecord && m_isLastRevisionAutoCorrectionEnabled);
                contentChangeGroup.Save();

                if (isNewRecord && !containsNewHistory)
                {
                    DeltaComputeProgressService.UpdateCache(recordDispName, ClearQuestRecordItem.NewRecordVersionValue);
                }
            }

            var lastHistoryRecordItem = historyDelta[historyDelta.Keys.Last()].Last();
            foreach (string histFieldName in historyDelta.Keys)
            {
                foreach (ClearQuestRecordItem recordHistItem in historyDelta[histFieldName])
                {
                    recordHistItem.CQSession = m_userSession;
                    ChangeGroup changeGroup = recordHistItem.CreateChangeGroup(
                        m_changeGroupService,
                        m_migrationContext,
                        (CQStringComparer.FieldName.Equals(recordHistItem.HistoryFieldName, lastHistoryRecordItem.HistoryFieldName) &&
                         recordHistItem.Version.Equals(lastHistoryRecordItem.Version, StringComparison.OrdinalIgnoreCase) &&
                         m_isLastRevisionAutoCorrectionEnabled));
                    changeGroup.Save();
                }

                Debug.Assert(perHistoryFieldLastIndex.ContainsKey(histFieldName), "perHistoryFieldLastIndex.ContainsKey(histFieldName) returns false");
                string deltaComputeProcessLookupId = CQDeltaComputationProgressLookupService.CreateHistoryItemId(recordEntDefName, recordDispName, histFieldName);
                DeltaComputeProgressService.UpdateCache(deltaComputeProcessLookupId, perHistoryFieldLastIndex[histFieldName]);
            }

            #endregion

            #region process attachment

            OAdAttachmentFields aAttachmentFields = CQWrapper.GetAttachmentFields(aRecord);

            for (int aAttachmentFieldsIndex = 0;
                 aAttachmentFieldsIndex < CQWrapper.AttachmentsFieldsCount(aAttachmentFields);
                 aAttachmentFieldsIndex++)
            {
                object             ob = (object)aAttachmentFieldsIndex;
                OAdAttachmentField aAttachmentField = CQWrapper.AttachmentsFieldsItem(aAttachmentFields, ref ob);
                string             fieldName        = CQWrapper.GetAttachmentFieldName(aAttachmentField);

                ChangeGroup changeGroup = m_changeGroupService.CreateChangeGroupForDeltaTable(
                    string.Format("{0}:{1}:{2}", recordDispName, "Attachments", fieldName));

                // process all attachments
                OAdAttachments attachments = CQWrapper.GetAttachments(aAttachmentField);
                for (int attachmentIndex = 0;
                     attachmentIndex < CQWrapper.AttachmentsCount(attachments);
                     attachmentIndex++)
                {
                    object        obIndex     = (object)attachmentIndex;
                    OAdAttachment aAttachment = CQWrapper.AttachmentsItem(attachments, ref obIndex);

                    ClearQuestAttachmentItem attachmentItem = new ClearQuestAttachmentItem(aRecord, aAttachmentField, aAttachment, UserSessionConnConfig);
                    attachmentItem.CQSession = m_userSession;
                    attachmentItem.CreateChangeAction(changeGroup, lastHistoryRecordItem.Version);
                }

                if (changeGroup.Actions.Count > 0)
                {
                    changeGroup.Save();
                }
            }

            #endregion
        }
Пример #6
0
        } // end of ProcessHistory()

        /// <summary>
        /// Processes the attachments for current record
        /// </summary>
        private void ProcessAttachments()
        {
            int noOfAttachments = 0;

            try
            {
                OAdAttachmentFields allAttachments = CQWrapper.GetAttachmentFields(m_CQEntity);
                StringCollection    filesAttached  = new StringCollection();

                int attachmentsIndex = 0;
                for (attachmentsIndex = 0;
                     attachmentsIndex < CQWrapper.AttachmentsFieldsCount(allAttachments);
                     attachmentsIndex++)
                {
                    object             ob            = (object)attachmentsIndex;
                    OAdAttachmentField attachmentFld = CQWrapper.AttachmentsFieldsItem(allAttachments, ref ob);

                    // process all attachments
                    OAdAttachments attachments = CQWrapper.GetAttachments(attachmentFld);
                    int            attachmentIndex;
                    for (attachmentIndex = 0;
                         attachmentIndex < CQWrapper.AttachmentsCount(attachments);
                         attachmentIndex++)
                    {
                        // there are some attachments

                        // create the dir for this bug dbid only if
                        string dirName = Path.Combine(CQConstants.AttachmentsDir, m_dbid.ToString());

                        if (attachmentIndex == 0)   // for the first time
                        {
                            // check if dir with curr dbid exist
                            if (Directory.Exists(dirName))
                            {
                                // if the dir exists, clean the contents
                                // as it is the system created dir
                                Logger.Write(LogSource.CQ, TraceLevel.Warning,
                                             "Removing folder {0} recursively for attachments of entity {1}",
                                             m_dbid, m_entityName);

                                try
                                {
                                    Directory.Delete(dirName, true);
                                }
                                catch (IOException ioe)
                                {
                                    Logger.Write(LogSource.CQ, TraceLevel.Warning, "Failed to delete folder {0} containing attachments for work item {1}",
                                                 dirName, SourceId);
                                    Logger.WriteException(LogSource.CQ, ioe);
                                }
                                catch (UnauthorizedAccessException uae)
                                {
                                    Logger.Write(LogSource.CQ, TraceLevel.Warning, "Permission denied for deleting folder {0} containing attachments for work item {1}",
                                                 dirName, SourceId);
                                    Logger.WriteException(LogSource.CQ, uae);
                                }
                            }

                            Logger.Write(LogSource.CQ, TraceLevel.Info,
                                         "Creating folder {0} for attachments of entity {1}",
                                         m_dbid, m_entityName);
                            UtilityMethods.CreateDirectory(dirName);
                        }

                        // for every attachments attachment create a separate
                        // sub dir as (attchmentsIndex+attchmentIndex)
                        string currAttachmentDir = Path.Combine(dirName, attachmentsIndex.ToString(CultureInfo.InvariantCulture));
                        currAttachmentDir = Path.Combine(currAttachmentDir, attachmentIndex.ToString(CultureInfo.InvariantCulture));

                        // there cannot be any dir existing as we already cleaned up
                        Logger.Write(LogSource.CQ, TraceLevel.Info,
                                     "Creating folder {0} for attachment {1} of entity {2}",
                                     currAttachmentDir, attachmentIndex + 1, m_entityName);
                        UtilityMethods.CreateDirectory(currAttachmentDir);

                        object        obIndex     = (object)attachmentIndex;
                        OAdAttachment aAttachment = CQWrapper.AttachmentsItem(attachments, ref obIndex);
                        noOfAttachments++;
                        string attachFileName;
                        string attachDescription;
                        CQWrapper.GetAttachmentFileNameAndDescription(aAttachment, out attachFileName, out attachDescription);
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Adding attachment");
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "\tFile Name : {0}", attachFileName);
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "\tDescription : {0}", attachDescription);

                        // save the attachment as file on disk
                        string tempfile = Path.Combine(currAttachmentDir, attachFileName);
                        CQWrapper.LoadAttachment(aAttachment, tempfile);
                        m_imWorkItem.Attachments.Add(new InMemoryAttachment(tempfile, attachDescription, false));
                        filesAttached.Add(attachFileName);
#if DEBUG
                        CommonConstants.NoOfAttachments++;
                        CommonConstants.TotalAttachmentSize += CQWrapper.AttachmentFileSize(aAttachment);
#endif
                    } // end of processing attachment
                }     // end of processing attachments
            }
            finally
            {
            }
        } // end of GetAttachments
Пример #7
0
        public void Download(string localPath)
        {
            byte[] metadataHash = HashAttachmentMetadata(Name, Comment, DisplayName, Length);

            if (null == CQSession)
            {
                throw new InvalidOperationException("CQSession == NULL");
            }

            // [teyang] TODO: validation on localPath
            if (File.Exists(localPath))
            {
                File.Delete(localPath);
            }

            OAdEntity aRecord = CQWrapper.GetEntity(CQSession, EntityDefName, EntityDispName);

            OAdAttachmentFields aAllAttFields = CQWrapper.GetAttachmentFields(aRecord);

            bool attachmentFound = false;

            for (int attFieldsIndex = 0;
                 attFieldsIndex < CQWrapper.AttachmentsFieldsCount(aAllAttFields);
                 attFieldsIndex++)
            {
                object             ob        = (object)attFieldsIndex;
                OAdAttachmentField aAttField = CQWrapper.AttachmentsFieldsItem(aAllAttFields, ref ob);

                string fieldName = CQWrapper.GetAttachmentFieldName(aAttField);

                if (!CQStringComparer.FieldName.Equals(fieldName, this.FieldName))
                {
                    // not the hosting attachment field, try next one
                    continue;
                }

                // attachment field is found, now look for the attachment
                OAdAttachments aAttachments = CQWrapper.GetAttachments(aAttField);
                OAdAttachment  aAttachment  = null;
                for (int attachmentIndex = 0;
                     attachmentIndex < CQWrapper.AttachmentsCount(aAttachments);
                     attachmentIndex++)
                {
                    object obIndex = (object)attachmentIndex;
                    aAttachment = CQWrapper.AttachmentsItem(aAttachments, ref obIndex);

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

                    byte[] hash = HashAttachmentMetadata(name, comment, dispName, (long)fileSize);
                    if (HashProducer.CompareMD5(metadataHash, hash) == 0)
                    {
                        attachmentFound = true;
                        break;
                    }
                }

                if (attachmentFound)
                {
                    Debug.Assert(null != aAttachment, "null == aAttachment");
                    CQWrapper.LoadAttachment(aAttachment, localPath);
                }

                // we've checked the host att field already, no need to proceed
                break;
            }

            if (!attachmentFound)
            {
                // [teyang] TODO: typed exception, AttachmentNotFound conflict handling
                throw new Exception(string.Format("attachment '{0}' is not found", Name));
            }
        }