} // end of ProcessStatesAndTransitions /// <summary> /// Process the CQ properties for USER type field /// </summary> /// <param name="cqFieldType">ClearQuest field type</param> /// <param name="witField">WIT Field handle</param> /// <param name="fldMap">Field Map handle (will be populated with Field Map)</param> private void ProcessUserFieldProperties(int cqFieldType, FieldDefinition witField, ref FieldMapsFieldMap fldMap) { // set the type explicitly as string for user type field witField.type = CQConstants.WITFieldTypes[CQConstants.FIELD_SHORT_STRING]; fldMap = new FieldMapsFieldMap(); if (cqFieldType == CQConstants.FIELD_REFERENCE) { // set the VALIDUSER constraint only if its a single reference // for reference list of users, migrate as simple string field bug#399176 witField.VALIDUSER = new ValidUserRule(); fldMap.ValueMaps = new FieldMapsFieldMapValueMaps(); fldMap.ValueMaps.refer = CQConstants.UserMapXMLValue; } else { string warningMsg = UtilityMethods.Format(CQResource.CQ_USER_LIST_CHANGED, witField.OldFieldName); ConverterMain.MigrationReport.WriteIssue(String.Empty, warningMsg, CQWrapper.GetEntityDefName(this.cqEntity), null, IssueGroup.Witd.ToString(), ReportIssueType.Warning); Logger.Write(LogSource.CQ, TraceLevel.Warning, warningMsg); } // check only for requiredness for User field ProcessFieldProperties(witField, cqFieldType, true); fldMap.from = witField.OldFieldName; fldMap.to = witField.name; // new field name.. if changed fldMap.exclude = "false"; }
} // end of GetUniqueInstallationId /// <summary> /// Returns the set of internal field maps which has to be imposed for all the entities.. /// Used for internal purpose.. in case user already defines some field maps, this will be superseeded /// with that /// </summary> /// <param name="fldMaps"></param> /// <returns></returns> private static FieldMapsFieldMap[] GetInternalFieldMaps(FieldMaps fldMaps) { // add the pre defined field mappings for history items FieldMapsFieldMap[] newFldMaps = new FieldMapsFieldMap[fldMaps.FieldMap.Length + CQConstants.InternalMap.Count]; int currindex = 0; foreach (KeyValuePair <string, string> map in CQConstants.InternalMap) { FieldMapsFieldMap newMap = new FieldMapsFieldMap(); newMap.from = map.Key; newMap.to = map.Value; if (currindex < CQConstants.NoOfUserFldsInInternalMap) { // add the User Map section newMap.ValueMaps = new FieldMapsFieldMapValueMaps(); newMap.ValueMaps.refer = CQConstants.UserMapXMLValue; newMap.ValueMaps.defaultValue = Environment.UserName; } // add from the end newFldMaps[newFldMaps.Length - currindex - 1] = newMap; currindex++; } return(newFldMaps); }
/// <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
/// <summary> /// Get the Currituck field name from the Field Map /// </summary> /// <param name="from">Source field name</param> /// <param name="fvalue">Field value if changed because of some value map</param> /// <returns>Currituck Field Name</returns> private string GetMappedFieldName(string fName, ref object fValue) { string toval = string.Empty; FieldMapsFieldMap nmap = (FieldMapsFieldMap)m_fieldMappings[fName]; if (nmap != null) { FieldMapsFieldMapValueMaps fvmaps = null; toval = nmap.to; // check if there are value mappings for this field! if (nmap.ValueMaps != null) { fvmaps = nmap.ValueMaps; if (fvmaps.refer != null && !TFStringComparer.XmlAttributeValue.Equals(fvmaps.refer, "UserMap")) { fvmaps = (FieldMapsFieldMapValueMaps)m_valueMappings[nmap.ValueMaps.refer]; } if (TFStringComparer.XmlAttributeValue.Equals(fvmaps.refer, "UserMap")) { string currUser = fValue.ToString(); string toUser = currUser; if (m_userMappings != null && m_userMappings.UserMap != null) { foreach (UserMappingsUserMap userMap in m_userMappings.UserMap) { if (TFStringComparer.UserName.Equals(userMap.From, currUser)) { toUser = userMap.To; break; } } } if (m_vstsConnection.store.UserDisplayMode == UserDisplayMode.AccountName) { // for alias mode, no resolution is ever required fValue = toUser; } else { // resolve the user for Display Name mode if (VSTSUtil.ResolvedUsers.Contains(toUser)) { fValue = VSTSUtil.ResolvedUsers[toUser]; } else { Identity userIdentity = VSTSUtil.ResolveUser(m_vstsConnection, toUser); if (userIdentity == null) { CommonConstants.UnresolvedUsers.Append(string.Concat(toUser, ", ")); VSTSUtil.ResolvedUsers.Add(toUser, toUser); fValue = toUser; } else { VSTSUtil.ResolvedUsers.Add(toUser, userIdentity.DisplayName); fValue = userIdentity.DisplayName; } } } } else if (fvmaps.ValueMap != null) { int score = 0; ValueMap bestMatch = null; string fldVal = fValue.ToString(); foreach (ValueMap fvmap in fvmaps.ValueMap) { if (fldVal.StartsWith(fvmap.from, StringComparison.OrdinalIgnoreCase)) { // found one candidate if (fvmap.from.Length > score) { score = fvmap.from.Length; bestMatch = fvmap; } } } if (score > 0) { fValue = String.Concat(bestMatch.to, fValue.ToString().Substring(bestMatch.from.Length)); } } } // If it is Area Path, calculate the Area ID and update that field if (TFStringComparer.WorkItemFieldFriendlyName.Equals(nmap.to, VSTSConstants.AreaPathField) || TFStringComparer.WorkItemFieldFriendlyName.Equals(nmap.to, VSTSConstants.IterationPathField)) { Node.TreeType type = Node.TreeType.Area; if (TFStringComparer.WorkItemFieldFriendlyName.Equals(nmap.to, VSTSConstants.AreaPathField)) { toval = VSTSConstants.AreaIdField; type = Node.TreeType.Area; } else { toval = VSTSConstants.IterationIdField; type = Node.TreeType.Iteration; } Node tmpNode = null; string fValueStr = fValue.ToString().Trim(); if (fValueStr.Length != 0) { tmpNode = VSTSUtil.FindNodeInSubTree(m_vstsConnection, fValueStr, type); } if (tmpNode != null) { if (type == Node.TreeType.Area) { // update the current work item structure with this area id m_vstsWorkItem.areaId = tmpNode.Id; } fValue = tmpNode.Id; } else { if (fvmaps != null && fvmaps.defaultValue != null && fvmaps.defaultValue.Trim().Length > 0) { string defaultValueStr = fvmaps.defaultValue.Trim(); tmpNode = VSTSUtil.FindNodeInSubTree(m_vstsConnection, defaultValueStr, type); if (tmpNode != null) { Logger.Write(LogSource.WorkItemTracking, TraceLevel.Warning, UtilityMethods.Format( "Using: '{0}' instead of: '{1}' for: '{2}'", defaultValueStr, fValueStr, nmap.to)); ConverterMain.MigrationReport.WriteIssue("MigrationCheck", ReportIssueType.Info, UtilityMethods.Format( VSTSResource.UsingDefaultValue, defaultValueStr, fValueStr, nmap.to)); fValue = tmpNode.Id; } else { string errMsg = UtilityMethods.Format( VSTSResource.InvalidDefaultValueMap, m_sourceWorkItemId, nmap.to, fValueStr, m_fieldMapFile); throw new ConverterException(errMsg); } } else { string errMsg = UtilityMethods.Format( VSTSResource.NullDefaultValueMap, m_sourceWorkItemId, nmap.to, fValueStr, m_fieldMapFile); throw new ConverterException(errMsg); } } } } return(toval); }