} // end of ValidateSchemaMapOnCQ /// <summary> /// Validates the Field Map on CQ for a Entity Type /// </summary> /// <param name="entityDef">Handle to Entity Definition</param> /// <param name="fldMaps">Deserialized Field Map data</param> /// <returns>true if successful, false in case of some error</returns> private static void ValidateFieldMapOnCQ(OAdEntityDef entityDef, FieldMapsFieldMap[] fldMaps, string fieldMapFile) { string entityName = CQWrapper.GetEntityDefName(entityDef); object[] cqFields = (object[])CQWrapper.GetFieldDefNames(entityDef); // prepare the list of fields from the current entity type Dictionary <string, bool> cqFieldsList = new Dictionary <string, bool>(TFStringComparer.OrdinalIgnoreCase); foreach (string cqFld in cqFields) { cqFieldsList.Add(cqFld, false); } Display.StartProgressDisplay(UtilityMethods.Format(CQResource.CQ_VALIDATE_FLD_MAP, fieldMapFile)); try { StringBuilder invalidFields = new StringBuilder(); foreach (FieldMapsFieldMap fldMap in fldMaps) { if (fldMap.exclude != null && !TFStringComparer.XmlAttributeValue.Equals(fldMap.exclude, "true") && !CQConstants.CQInternalFields.ContainsKey(fldMap.from)) { // this is to be included in the selected fields for migration if (!cqFieldsList.ContainsKey(fldMap.from)) { if (invalidFields.Length > 0) { invalidFields.Append(", "); } invalidFields.Append(fldMap.from); } } } if (invalidFields.Length > 0) { string errMsg = UtilityMethods.Format(CQResource.CQ_FLD_NOT_EXIST, Path.GetFileName(fieldMapFile), invalidFields.ToString(), entityName); PostMigrationReport.WriteIssue(null, null, RepStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Witd, errMsg); throw new ConverterException(errMsg); } } finally { Display.StopProgressDisplay(); Display.NewLine(); } } // end of ValidateFieldMapOnCQ
/// <summary> /// Process and add Fields to the WIT /// </summary> /// <param name="wit">Handle to WIT to add the fields</param> private void ProcessFields(WorkItemType wit) { Logger.EnteredMethod(LogSource.CQ, wit); // add vsts_sourcedb and vsts_sourceid fields FieldDefinition vstsIdField = AddInternalFields(wit, CQConstants.IdFieldName, FieldType.Integer); FieldDefinition vstsSourceIdField = AddInternalFields(wit, CommonConstants.VSTSSrcIdField, FieldType.String); vstsSourceIdField.READONLY = new PlainRule(); AddInternalFields(wit, CommonConstants.VSTSSrcDbField, FieldType.String); // add id and vsts_sourceid in form CreateDefaultControl(vstsIdField.name, vstsIdField.refname, FieldType.Integer, wit); CreateDefaultControl(CQConstants.SourceFieldLabel, vstsSourceIdField.refname, FieldType.String, wit); // get all the fields from CQ object[] cqFields = (object[])CQWrapper.GetFieldDefNames(cqEntityDef); FieldDefinition witField; if (cqFields.Length > 0) { foreach (object ob in cqFields) { string fldName = (string)ob; if (CQConstants.InternalFieldTypes.ContainsKey(fldName)) { // these are internal clearquest fields // we dont want to migrate these Logger.Write(LogSource.CQ, TraceLevel.Info, "Skipping CQ Internal Field '{0}'", fldName); continue; } int cqFieldType = CQWrapper.GetFieldDefType(cqEntityDef, fldName); string suggestedFldMap = (string)CQConstants.SuggestedMap[fldName]; if (suggestedFldMap != null) { // this field name matched to one the suggested mappings to one of the core field // generate the field in schema and also a field map for this.. witField = new FieldDefinition(); witField.OldFieldName = fldName; witField.name = suggestedFldMap; witField.type = CQConstants.WITFieldTypes[cqFieldType]; // use the core field refname and type for (int coreFieldIndex = 0; coreFieldIndex < CQConstants.CurrituckCoreFields.Length; coreFieldIndex++) { string coreFieldName = CQConstants.CurrituckCoreFields[coreFieldIndex].Name; if (TFStringComparer.WorkItemFieldFriendlyName.Equals(coreFieldName, suggestedFldMap)) { // use the refname and type from the core fields witField.refname = CQConstants.CurrituckCoreFields[coreFieldIndex].ReferenceName; witField.type = (FieldType)Enum.Parse(typeof(FieldType), CQConstants.CurrituckCoreFields[coreFieldIndex].FieldType.ToString()); break; } } fieldsToComment.Add(witField.name); wit.AddField(witField); FieldMapsFieldMap fldMap = null; // process the field properties to set rules for Required/Read Only and list of values // check if it requires UserMap also if (cqFieldType == CQConstants.FIELD_REFERENCE || cqFieldType == CQConstants.FIELD_REFERENCE_LIST) { OAdEntityDef refEntity = CQWrapper.GetFieldReferenceEntityDef(cqEntityDef, witField.OldFieldName); if (TFStringComparer.WorkItemType.Equals(CQWrapper.GetEntityDefName(refEntity), "users")) { ProcessUserFieldProperties(cqFieldType, witField, ref fldMap); } } else { ProcessFieldProperties(witField, cqFieldType, false); fldMap = new FieldMapsFieldMap(); fldMap.from = witField.OldFieldName; fldMap.to = witField.name; fldMap.exclude = "false"; } Logger.Write(LogSource.CQ, TraceLevel.Info, "Using Suggested Field Map {0} to {1}", witField.OldFieldName, suggestedFldMap.ToString()); witdFieldMap.GetFieldMappings().AddFieldMap(fldMap); if (TFStringComparer.WorkItemFieldFriendlyName.Equals(fldMap.to, VSTSConstants.DescriptionField)) { CreateDefaultControl(witField.OldFieldName, witField.refname, FieldType.PlainText, wit); } else { CreateDefaultControl(witField.OldFieldName, witField.refname, FieldType.String, wit); } continue; } switch (cqFieldType) { case CQConstants.FIELD_ID: case CQConstants.FIELD_SHORT_STRING: case CQConstants.FIELD_MULTILINE_STRING: case CQConstants.FIELD_INT: case CQConstants.FIELD_DATE_TIME: { Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Migrating Field '{0}'", fldName); witField = new FieldDefinition(); witField.OldFieldName = witField.name = fldName; witField.type = CQConstants.WITFieldTypes[cqFieldType]; // find the set of allowed values and populate in the xml ProcessFieldProperties(witField, cqFieldType, false); wit.AddField(witField); FieldMapsFieldMap fldMap = new FieldMapsFieldMap(); fldMap.from = witField.OldFieldName; fldMap.to = witField.name; // new field name.. if changed fldMap.exclude = "false"; // add the field map witdFieldMap.GetFieldMappings().AddFieldMap(fldMap); // add in FORM CreateDefaultControl(witField.OldFieldName, witField.refname, witField.type, wit); } break; case CQConstants.FIELD_REFERENCE_LIST: case CQConstants.FIELD_REFERENCE: { // find the referenced entity name OAdEntityDef refEntity = CQWrapper.GetFieldReferenceEntityDef(cqEntityDef, fldName); if (TFStringComparer.WorkItemType.Equals(CQWrapper.GetEntityDefName(refEntity), "users")) { // add the refer keyword in the FieldMap file for this field // and generate the field information for this field.. // as User is a core functionality in currituck.. // handle is in special way // there are no chances that a "users" field will be of REFERENCE_LIST type.. // in case we see a requirement for REFERENCE_LIST also, add this code there also Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Migrating User Field '{0}'", fldName); FieldMapsFieldMap fldMap = null; witField = new FieldDefinition(); witField.OldFieldName = witField.name = fldName; ProcessUserFieldProperties(cqFieldType, witField, ref fldMap); // add in FIELD, FieldMap and FORM wit.AddField(witField); // fix for bug# 15769 // set new "To" field name in the field map in case the field name got changed as part of AddField() call fldMap.to = witField.name; witdFieldMap.GetFieldMappings().AddFieldMap(fldMap); CreateDefaultControl(witField.OldFieldName, witField.refname, witField.type, wit); } } break; case CQConstants.FIELD_STATE: case CQConstants.FIELD_ATTACHMENT_LIST: case CQConstants.FIELD_JOURNAL: case CQConstants.FIELD_DBID: case CQConstants.FIELD_STATETYPE: case CQConstants.FIELD_RECORDTYPE: // not migrating these fields as they are CQ internal fields Logger.Write(LogSource.CQ, TraceLevel.Info, "Skipping the Field migration for Internal Field Type '{0}'", cqFieldType); break; default: break; } // switch (cqFieldType) } // end of foreach (object ob in cqFields) } //if (cqFields.Length > 0) else { Logger.Write(LogSource.CQ, TraceLevel.Warning, "No Fields present in the current Entity Definition '{0}'", wit.name); } // add all the core fields in the FIELDS section as these fields are being used in the FORM section // as per Currituck implementation, any field existing in FORM section has to be in the FIELDS also // even if it is a core field FieldDefinition coreFldDef = null; for (int coreFieldIndex = 0; coreFieldIndex < CQConstants.CurrituckCoreFields.Length; coreFieldIndex++) { string coreFieldName = CQConstants.CurrituckCoreFields[coreFieldIndex].Name; bool fieldExist = false; foreach (FieldDefinition fldDef in wit.FIELDS) { if (TFStringComparer.WorkItemFieldFriendlyName.Equals(fldDef.name, coreFieldName)) { fieldExist = true; break; } } if (fieldExist == true) { // skip this field.. its already added in the FIELDS section continue; } coreFldDef = new FieldDefinition(); coreFldDef.name = coreFieldName; coreFldDef.refname = CQConstants.CurrituckCoreFields[coreFieldIndex].ReferenceName; coreFldDef.type = (FieldType)Enum.Parse(typeof(FieldType), CQConstants.CurrituckCoreFields[coreFieldIndex].FieldType.ToString()); if (coreFieldIndex < CQConstants.NoOfUserFldsInCoreFields) { //add VALIDUSER rule for all user fields coreFldDef.VALIDUSER = new ValidUserRule(); } wit.AddField(coreFldDef); } int pos; ControlType reasonFld = wit.FindFieldInForm(CQConstants.ReasonField, out pos); if (reasonFld == null) { // Bug# 50492: reason field is not yet added .. add it after the State field // look for state field position wit.FindFieldInForm(CQConstants.StateField, out pos); if (pos >= 0) { FieldDefinition reasonFldDef = AddInternalFields(wit, CQConstants.ReasonFieldName, FieldType.String); wit.FORM.Layout.WITDItems.Insert(pos + 1, CreateDefaultControl(reasonFldDef.name, CQConstants.ReasonField, FieldType.String, null)); } } Logger.ExitingMethod(LogSource.CQ); } // end of ProcessFields
private void MapLinkTypes(string[] refEntities, string entityToMigrate, OAdEntityDef entityDef) { List <string> refEntityList = new List <string>(refEntities); object[] fieldDefNameObjs = CQWrapper.GetFieldDefNames(entityDef) as object[]; // add the field reference[list] links foreach (object fieldDefNameObj in fieldDefNameObjs) { string fieldDefName = fieldDefNameObj as string; int fieldDefType = CQWrapper.GetFieldDefType(entityDef, fieldDefName); if (fieldDefType == CQConstants.FIELD_REFERENCE) { OAdEntityDef childRecordEntityDef = CQWrapper.GetFieldReferenceEntityDef(entityDef, fieldDefName); string childRecordEntityDefName = CQWrapper.GetEntityDefName(childRecordEntityDef); if (refEntityList.Contains(childRecordEntityDefName)) { var linkTypeMapping = new LinkingLinkTypeMapping(); linkTypeMapping.LeftMigrationSourceUniqueId = "[Please add Left Migration Source Migration Id]"; linkTypeMapping.RightMigrationSourceUniqueId = "[Please add Right Migration Source Migration Id]"; linkTypeMapping.LeftLinkType = string.Format("ClearQuestAdapter.LinkType.ReferenceFieldRecordLink.{0}.{1}", entityToMigrate, childRecordEntityDef); linkTypeMapping.RightLinkType = "[Please add Right link type reference name]"; if (!m_linkTypeMaps.ContainsKey(linkTypeMapping.LeftLinkType)) { m_linkTypeMaps.Add(linkTypeMapping.LeftLinkType, linkTypeMapping); } } } else if (fieldDefType == CQConstants.FIELD_REFERENCE_LIST) { OAdEntityDef childRecordEntityDef = CQWrapper.GetFieldReferenceEntityDef(entityDef, fieldDefName); string childRecordEntityDefName = CQWrapper.GetEntityDefName(childRecordEntityDef); if (refEntityList.Contains(childRecordEntityDefName)) { var linkTypeMapping = new LinkingLinkTypeMapping(); linkTypeMapping.LeftMigrationSourceUniqueId = "[Please add Left Migration Source Migration Id]"; linkTypeMapping.RightMigrationSourceUniqueId = "[Please add Right Migration Source Migration Id]"; linkTypeMapping.LeftLinkType = string.Format("ClearQuestAdapter.LinkType.ReferenceListFieldRecordLink.{0}.{1}", entityToMigrate, childRecordEntityDef); linkTypeMapping.RightLinkType = "[Please add Right link type reference name]"; if (!m_linkTypeMaps.ContainsKey(linkTypeMapping.LeftLinkType)) { m_linkTypeMaps.Add(linkTypeMapping.LeftLinkType, linkTypeMapping); } } } } // add the duplicate links var duplinkTypeMapping = new LinkingLinkTypeMapping(); duplinkTypeMapping.LeftMigrationSourceUniqueId = "[Please add Left Migration Source Migration Id]"; duplinkTypeMapping.RightMigrationSourceUniqueId = "[Please add Right Migration Source Migration Id]"; duplinkTypeMapping.LeftLinkType = "ClearQuestAdapter.LinkType.Duplicate"; duplinkTypeMapping.RightLinkType = "[Please add Right link type reference name]"; if (!m_linkTypeMaps.ContainsKey(duplinkTypeMapping.LeftLinkType)) { m_linkTypeMaps.Add(duplinkTypeMapping.LeftLinkType, duplinkTypeMapping); } }