コード例 #1
0
ファイル: ReferenceHelper.cs プロジェクト: mparsin/Elements
        private ReferenceDisplayFieldDefinition GetDisplayField(ReferenceHelperContext context, FieldEdit fieldInfo, bool throwOnError)
        {
            var publishedProcess = fieldInfo.GetParent<ProcessEdit>();

            if (context.VisitedFields.Contains(Tuple.Create(publishedProcess.SystemName, fieldInfo.SystemName)))
            {
                throw new CircularReferenceException("Circular reference detected.");
            }

            var fieldDefinition = new ReferenceDisplayFieldDefinition
            {
                Name = fieldInfo.Name,
                SystemName = fieldInfo.SystemName,
                ColumnType = fieldInfo.FieldType.ColumnType,
                DefinedIn = GetProcessDefinition(publishedProcess),
            };

            var tuple = Tuple.Create(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

            try
            {
                context.VisitedFields.Add(tuple);

                if (fieldDefinition.IsRef)
                {
                    var crStep = (CrossRefRequiredStepEdit)fieldInfo.StepList.FirstOrDefault(s => s is CrossRefRequiredStepEdit);

                    if (crStep == null || !crStep.CrossRefProcessId.HasValue)
                        throw new InvalidReferenceFieldExpcetion(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName, "Cross reference process is null.");

                    if (crStep.AllowMultiple)
                        fieldDefinition.ColumnType = ColumnTypes.MultiReference;

                    var referencedProcess = Cache.GetProcessInfo(crStep.CrossRefProcessId.Value);

                    fieldDefinition.ReferencedProcess = GetProcessDefinition(referencedProcess);

                    if (fieldDefinition.ColumnType == ColumnTypes.MultiReference && !string.IsNullOrEmpty(crStep.LinkFieldSystemName))
                    {
                        var referenceField = GetJoinField(referencedProcess.SystemName, crStep.LinkFieldSystemName);

                        if (referenceField.ColumnType != ColumnTypes.Reference)
                            throw new InvalidReferenceFieldExpcetion(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName, "Invalid link field type.");

                        if (referenceField.ReferencedProcess.SystemName != fieldDefinition.DefinedIn.SystemName)
                            throw new InvalidReferenceFieldExpcetion(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName, "Invalid link field.");

                        fieldDefinition.ReferenceField = referenceField;
                    }

                    var order = 0;
                    ReferenceDisplayFieldDefinition fd;

                    foreach (var displayField in crStep.SelectedFields)
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, displayField.FullPath, throwOnError);

                        ++order;
                        fd.Order = order;
                        fd.Guid = displayField.FieldGuid;
                        fd.ShowOnDetails = true;
                        fd.ShowOnSearch = false;
                        fieldDefinition.Subfields.Add(fd);
                    }

                    fd = fieldDefinition.Subfields.FirstOrDefault(x => x.FullPath == crStep.DisplayFieldName);

                    if (fd != null)
                        fd.ShowOnSearch = true;
                    else
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, crStep.DisplayFieldName, throwOnError);

                        fd.Order = 1;
                        fd.Guid = Guid.NewGuid();
                        fd.ShowOnDetails = false;
                        fd.ShowOnSearch = true;
                        fieldDefinition.Subfields.Add(fd);
                    }
                }

                if (fieldDefinition.IsReverseRef)
                {
                    var rcrStep = (ReverseCrossRefRequiredStepEdit)fieldInfo.StepList.FirstOrDefault(s => s is ReverseCrossRefRequiredStepEdit);
                    var rcrOptions = (ReverseCrossRefOptionsStepEdit)fieldInfo.StepList.FirstOrDefault(s => s is ReverseCrossRefOptionsStepEdit);

                    if (rcrStep == null || rcrOptions == null || !rcrStep.ReverseCrossRefProcessId.HasValue)
                        throw new InvalidReferenceFieldExpcetion(
                            fieldDefinition.DefinedIn.SystemName,
                            fieldDefinition.SystemName,
                            "Reverse cross reference process is null.");

                    var referencedProcess = Cache.GetProcessInfo(rcrStep.ReverseCrossRefProcessId.Value);

                    var crStep = Cache.GetCrossReferenceRequiredStep(referencedProcess.SystemName, rcrStep.CrossRefFieldName);
                    if (!crStep.CrossRefProcessId.HasValue)
                        throw new InvalidReferenceFieldExpcetion(
                            fieldDefinition.DefinedIn.SystemName,
                            fieldDefinition.SystemName,
                            "Cross reference process is null.");

                    fieldDefinition.ShowLatestVersion = rcrOptions.ShowLatestVersion && referencedProcess.ProcessOption == ProcessOption.VersionEnabled;
                    fieldDefinition.ReferenceField = new ReferenceJoinFieldDefinition
                    {
                        SystemName = rcrStep.CrossRefFieldName,
                        ColumnType =
                            crStep.AllowMultiple
                                ? ColumnTypes.MultiReference
                                : ColumnTypes.Reference,
                        DefinedIn = GetProcessDefinition(referencedProcess),
                        ReferencedProcess = GetProcessDefinition(publishedProcess)
                    };

                    var order = 0;
                    ReferenceDisplayFieldDefinition fd;

                    foreach (var displayField in rcrStep.DisplayFields.OrderBy(df => df.Order))
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, displayField.FullPath, throwOnError);

                        if (fd != null)
                        {
                            ++order;
                            fd.Order = order;
                            fd.Guid = displayField.Guid;
                            fd.ShowOnDetails = true;
                            fd.ShowOnSearch = false;
                            fieldDefinition.Subfields.Add(fd);
                        }
                    }

                    fd = fieldDefinition.Subfields.FirstOrDefault(x => x.FullPath == rcrStep.DisplayFieldName);

                    if (fd != null)
                    {
                        fd.ShowOnSearch = true;
                    }
                    else
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, rcrStep.DisplayFieldName, throwOnError);

                        fd.Order = 1;
                        fd.Guid = Guid.NewGuid();
                        fd.ShowOnDetails = false;
                        fd.ShowOnSearch = true;

                        fieldDefinition.Subfields.Add(fd);
                    }
                }

                if (fieldDefinition.ColumnType == ColumnTypes.Numeric)
                {
                    var numericStep = (NumericRequiredStepEdit)fieldInfo.StepList.First(s => s is NumericRequiredStepEdit);

                    fieldDefinition.NumericType = NumericTypes.Numeric;

                    if (numericStep.NumberOfDigits == 0 && numericStep.Minimum >= int.MinValue && numericStep.Maximum <= int.MaxValue && numericStep.NumericType == NumericTypes.Numeric)
                        fieldDefinition.ColumnType = ColumnTypes.Integer;

                    fieldDefinition.NumericType = numericStep.NumericType;
                    fieldDefinition.NumberOfDigits = numericStep.NumberOfDigits;
                }

                if (fieldDefinition.ColumnType == ColumnTypes.DateTime)
                {
                    var dateTimeStep = (DateRequiredSettingsStepEdit)fieldInfo.StepList.First(s => s is DateRequiredSettingsStepEdit);
                    fieldDefinition.DateTimeFormat = DateTimeFormat.DateTime;

                    DateTimeFormat format;

                    if (Enum.TryParse(dateTimeStep.SelectedDateTimeFormat, true, out format))
                    {
                        fieldDefinition.DateTimeFormat = format;
                    }
                }

                if (fieldDefinition.ColumnType == ColumnTypes.Boolean)
                {
                    var checkboxStep = (CheckboxOptionsStepEdit)fieldInfo.StepList.First(s => s is CheckboxOptionsStepEdit);
                    fieldDefinition.MainLabel = checkboxStep.MainLabel;
                    fieldDefinition.UndefinedLabel = checkboxStep.UndefinedLabel;
                    fieldDefinition.TrueLabel = checkboxStep.TrueLabel;
                    fieldDefinition.FalseLabel = checkboxStep.FalseLabel;
                    fieldDefinition.IsSwitchToggle = checkboxStep.IsSwitchToggle;
                }

                if (fieldDefinition.ColumnType == ColumnTypes.Image)
                {
                    var pictureStep = fieldInfo.StepList.OfType<PictureSetupStepEdit>().First();

                    fieldDefinition.SearchImageWidth = pictureStep.SearchWidth;
                    fieldDefinition.SearchImageHeight = pictureStep.SearchHeight;
                    fieldDefinition.DetailsImageWidth = pictureStep.DetailsWidth;
                    fieldDefinition.DetailsImageHeight = pictureStep.DetailsHeight;
                    fieldDefinition.UseOriginalImageSize = pictureStep.UseOriginalSize;
                }
            }
            finally
            {
                context.VisitedFields.Remove(tuple);
            }

            return fieldDefinition;
        }
コード例 #2
0
ファイル: ReferenceHelper.cs プロジェクト: mparsin/Elements
        private ReferenceDisplayFieldDefinition GetDisplayField(ReferenceHelperContext context, FieldInfoDto fieldInfo, bool throwOnError)
        {
            if (context.VisitedFields.Contains(Tuple.Create(fieldInfo.DefinedIn, fieldInfo.SystemName)))
                throw new CircularReferenceException("Circular reference detected.");

            var publishedProcess = Cache.GetProcessInfo(fieldInfo.DefinedIn);
            var fieldDefinition = new ReferenceDisplayFieldDefinition
                                      {
                                          Name = fieldInfo.Name,
                                          SystemName = fieldInfo.SystemName,
                                          ColumnType = (ColumnTypes)Enum.Parse(typeof(ColumnTypes), fieldInfo.DataType),
                                          DefinedIn = GetProcessDefinition(publishedProcess),
                                          IsRichTextField = fieldInfo.IsRichTextField,
                                      };

            if (fieldDefinition.SystemName == Constants.CurrentStateColumnName)
            {
                fieldDefinition.ReferencedProcess = GetProcessDefinition(Constants.StateProcessName);

                var fd = GetFieldDefinition(context, Constants.StateProcessName, Constants.Name, throwOnError);
                fd.Order = 1;
                fd.Guid = Guid.NewGuid();
                fd.ShowOnDetails = true;
                fd.ShowOnSearch = true;

                fieldDefinition.Subfields.Add(fd);

                return fieldDefinition;
            }

            if (fieldDefinition.SystemName.Equals(Constants.VersionDate))
            {
                fieldDefinition.DateTimeFormat = DateTimeFormat.DateTime;
                return fieldDefinition;
            }

            // System fields are not stored in the database.
            if (fieldDefinition.SystemName.Equals(Constants.IdColumnName, StringComparison.OrdinalIgnoreCase)
                || fieldDefinition.SystemName.Equals(Constants.VersionNumber))
            {
                return fieldDefinition;
            }

            var tuple = Tuple.Create(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

            try
            {
                context.VisitedFields.Add(tuple);

                if (fieldDefinition.IsRef)
                {
                    var crStep = Cache.GetCrossReferenceRequiredStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    if (!crStep.CrossRefProcessId.HasValue)
                        throw new InvalidReferenceFieldExpcetion(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName, "Cross reference process is null.");

                    var referencedProcess = Cache.GetProcessInfo(crStep.CrossRefProcessId.Value);

                    fieldDefinition.ReferencedProcess = GetProcessDefinition(referencedProcess);

                    if (fieldDefinition.ColumnType == ColumnTypes.MultiReference && !string.IsNullOrEmpty(crStep.LinkFieldSystemName))
                    {
                        var referenceField = GetJoinField(referencedProcess.SystemName, crStep.LinkFieldSystemName);

                        if (referenceField.ColumnType != ColumnTypes.Reference)
                            throw new InvalidReferenceFieldExpcetion(fieldInfo.DefinedIn, fieldInfo.SystemName, "Invalid link field type.");

                        if (referenceField.ReferencedProcess.SystemName != fieldInfo.DefinedIn)
                            throw new InvalidReferenceFieldExpcetion(fieldInfo.DefinedIn, fieldInfo.SystemName, "Invalid link field.");

                        fieldDefinition.ReferenceField = referenceField;
                    }

                    var order = 0;
                    ReferenceDisplayFieldDefinition fd;

                    foreach (var displayField in crStep.DisplayFields)
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, displayField.FullPath, throwOnError);

                        ++order;
                        fd.Order = order;
                        fd.Guid = displayField.Guid;
                        fd.ShowOnDetails = true;
                        fd.ShowOnSearch = false;
                        fieldDefinition.Subfields.Add(fd);
                    }

                    fd = fieldDefinition.Subfields.FirstOrDefault(x => x.FullPath == crStep.DisplayFieldName);

                    if (fd != null)
                    {
                        fd.ShowOnSearch = true;
                    }
                    else
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, crStep.DisplayFieldName, throwOnError);

                        fd.Order = 1;
                        fd.Guid = Guid.NewGuid();
                        fd.ShowOnDetails = false;
                        fd.ShowOnSearch = true;
                        fieldDefinition.Subfields.Add(fd);
                    }
                }

                if (fieldDefinition.IsReverseRef)
                {
                    var rcrStep = Cache.GetReverseCrossReferenceRequiredStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    if (!rcrStep.ReverseCrossRefProcessId.HasValue)
                        throw new InvalidReferenceFieldExpcetion(
                            fieldDefinition.DefinedIn.SystemName,
                            fieldDefinition.SystemName,
                            "Reverse cross reference process is null.");

                    var referencedProcess = Cache.GetProcessInfo(rcrStep.ReverseCrossRefProcessId.Value);

                    var rcrOptions = Cache.GetReverseCrossReferenceOptionsStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    var referenceField = GetJoinField(referencedProcess.SystemName, rcrStep.CrossRefFieldName);

                    fieldDefinition.ShowLatestVersion = rcrOptions.ShowLatestVersion && referencedProcess.ProcessOption == ProcessOption.VersionEnabled;
                    fieldDefinition.ReferenceField = referenceField;

                    var order = 0;
                    ReferenceDisplayFieldDefinition fd;

                    foreach (var displayField in rcrStep.SelectedDisplayFields.OrderBy(df => df.Order))
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, displayField.FullPath, throwOnError);

                        if (fd != null)
                        {
                            ++order;
                            fd.Order = order;
                            fd.Guid = displayField.Guid;
                            fd.ShowOnDetails = true;
                            fd.ShowOnSearch = false;
                            fieldDefinition.Subfields.Add(fd);
                        }
                    }

                    fd = fieldDefinition.Subfields.FirstOrDefault(x => x.FullPath == rcrStep.DisplayFieldName);

                    if (fd != null)
                        fd.ShowOnSearch = true;
                    else
                    {
                        fd = GetFieldDefinition(context, referencedProcess.SystemName, rcrStep.DisplayFieldName, throwOnError);

                        fd.Order = 1;
                        fd.Guid = Guid.NewGuid();
                        fd.ShowOnDetails = false;
                        fd.ShowOnSearch = true;

                        fieldDefinition.Subfields.Add(fd);
                    }
                }

                if (fieldDefinition.ColumnType == ColumnTypes.Numeric)
                {
                    var numericStep = Cache.GetNumericRequiredStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    fieldDefinition.NumericType = NumericTypes.Numeric;

                    if (numericStep.NumberOfDigits == 0 && numericStep.Minimum >= int.MinValue && numericStep.Maximum <= int.MaxValue
                        && (NumericTypes)numericStep.NumericType == NumericTypes.Numeric)
                    {
                        fieldDefinition.ColumnType = ColumnTypes.Integer;
                    }

                    fieldDefinition.NumericType = (NumericTypes)numericStep.NumericType;
                    fieldDefinition.NumberOfDigits = numericStep.NumberOfDigits;
                }

                if (fieldDefinition.ColumnType == ColumnTypes.DateTime)
                {
                    var dateTimeStep = Cache.GetDateTimeRequiredStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    fieldDefinition.DateTimeFormat = DateTimeFormat.DateTime;

                    DateTimeFormat format;

                    if (Enum.TryParse(dateTimeStep.DateTimeFormat, true, out format))
                        fieldDefinition.DateTimeFormat = format;
                }

                if (fieldDefinition.ColumnType == ColumnTypes.Boolean)
                {
                    var checkboxStep = Cache.GetCheckboxOptionsStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    fieldDefinition.MainLabel = checkboxStep.MainLabel;
                    fieldDefinition.UndefinedLabel = checkboxStep.IsSwitchToggle ? checkboxStep.UndefinedLabel : string.Empty;
                    fieldDefinition.TrueLabel = checkboxStep.IsSwitchToggle ? checkboxStep.TrueLabel : true.ToString();
                    fieldDefinition.FalseLabel = checkboxStep.IsSwitchToggle ? checkboxStep.FalseLabel : false.ToString();
                    fieldDefinition.IsSwitchToggle = checkboxStep.IsSwitchToggle;
                }

                if (fieldDefinition.ColumnType == ColumnTypes.Image)
                {
                    var pictureStep = Cache.GetPictureStep(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

                    fieldDefinition.SearchImageWidth = pictureStep.SearchWidth;
                    fieldDefinition.SearchImageHeight = pictureStep.SearchHeight;
                    fieldDefinition.DetailsImageWidth = pictureStep.DetailsWidth;
                    fieldDefinition.DetailsImageHeight = pictureStep.DetailsHeight;
                    fieldDefinition.UseOriginalImageSize = pictureStep.UseOriginalSize;
                }
            }
            finally
            {
                context.VisitedFields.Remove(tuple);
            }

            return fieldDefinition;
        }
コード例 #3
0
ファイル: ReferenceHelper.cs プロジェクト: mparsin/Elements
        public ReferenceDisplayFieldDefinition GetCurrentStateFieldDefinition(ReferenceHelperContext context, ProcessEdit publishedProcess)
        {
            if (context.VisitedFields.Contains(Tuple.Create(publishedProcess.SystemName, Constants.CurrentStateColumnName)))
            {
                throw new CircularReferenceException("Circular reference detected.");
            }

            var fieldDefinition = new ReferenceDisplayFieldDefinition
                                      {
                                          Name = "Current State", //LanguageService.Translate("CurrentState"),
                                          SystemName = Constants.CurrentStateColumnName,
                                          ColumnType = ColumnTypes.Reference,
                                          DefinedIn = GetProcessDefinition(publishedProcess),
                                          ReferencedProcess = GetProcessDefinition(Constants.StateProcessName),
                                      };

            var tuple = Tuple.Create(fieldDefinition.DefinedIn.SystemName, fieldDefinition.SystemName);

            try
            {
                context.VisitedFields.Add(tuple);

                var subfield = new ReferenceDisplayFieldDefinition
                                   {
                                       Name = Constants.Name,
                                       SystemName = Constants.Name,
                                       ColumnType = ColumnTypes.String,
                                       DefinedIn = GetProcessDefinition(fieldDefinition.ReferencedProcess.SystemName),
                                       Guid = Guid.NewGuid(),
                                       ShowOnDetails = true,
                                       ShowOnSearch = true,
                                   };

                fieldDefinition.Subfields.Add(subfield);
            }
            finally
            {
                context.VisitedFields.Remove(tuple);
            }

            return fieldDefinition;
        }
コード例 #4
0
ファイル: ReferenceHelper.cs プロジェクト: mparsin/Elements
        /// <summary>
        /// Gets the field definition.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="process">
        /// The process.
        /// </param>
        /// <param name="path">
        /// The field path.
        /// </param>
        /// <param name="throwOnError">
        /// True to throw an exception on error; otherwise, false.
        /// </param>
        /// <returns>
        /// The ReferenceDisplayFieldDefinition.
        /// </returns>
        public ReferenceDisplayFieldDefinition GetFieldDefinition(ReferenceHelperContext context, ProcessEdit process, string path, bool throwOnError)
        {
            var index = path.IndexOf('.');
            var fieldName = path;

            if (index >= 0)
            {
                fieldName = path.Substring(0, index);
            }

            var fieldInfos = process.GetAllFields();
            var fieldInfo = fieldInfos.FirstOrDefault(x => x.SystemName == fieldName);

            if (fieldInfo == null)
            {
                if (throwOnError)
                    throw new Exception(string.Format(@"Field '{0}' not found in process '{1}'.", fieldName, process.SystemName));

                return null;
            }

            if (index >= 0 && index < path.Length - 1)
            {
                var joinField = GetJoinField(fieldInfo);

                if (joinField == null)
                    return null;

                var fieldDefinition = GetFieldDefinition(context, joinField.ReferencedProcess.SystemName, path.Substring(index + 1, path.Length - index - 1), throwOnError);

                fieldDefinition.JoinFields.Insert(0, joinField);

                return fieldDefinition;
            }

            return GetDisplayField(context, fieldInfo, throwOnError);
        }
コード例 #5
0
ファイル: ReferenceHelper.cs プロジェクト: mparsin/Elements
 /// <summary>
 /// Gets the field definition.
 /// </summary>
 /// <param name="context">
 /// The context.
 /// </param>
 /// <param name="process">
 /// The process.
 /// </param>
 /// <param name="path">
 /// The field path.
 /// </param>
 /// <returns>
 /// The ReferenceDisplayFieldDefinition.
 /// </returns>
 public ReferenceDisplayFieldDefinition GetFieldDefinition(ReferenceHelperContext context, ProcessEdit process, string path)
 {
     return GetFieldDefinition(context, process, path, false);
 }
コード例 #6
0
ファイル: ReferenceHelper.cs プロジェクト: mparsin/Elements
        /// <summary>
        /// Gets the field definition.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="processName">
        /// Name of the process.
        /// </param>
        /// <param name="path">
        /// The field path.
        /// </param>
        /// <param name="throwOnError">
        /// True to throw an exception on error; otherwise, false.
        /// </param>
        /// <returns>
        /// The ReferenceDisplayFieldDefinition.
        /// </returns>
        public ReferenceDisplayFieldDefinition GetFieldDefinition(ReferenceHelperContext context, string processName, string path, bool throwOnError)
        {
            var index = path.IndexOf('.');
            var fieldName = path;

            if (index >= 0)
            {
                fieldName = path.Substring(0, index);
            }

            FieldInfoDto fieldInfo;

            if (fieldName.Equals(Constants.IdColumnName, StringComparison.OrdinalIgnoreCase))
            {
                fieldInfo = CreateIdFieldInfo(processName);
            }
            else
                if (fieldName.Equals(Constants.CurrentStateColumnName, StringComparison.OrdinalIgnoreCase))
            {
                fieldInfo = CreateCurrentStateFieldInfo(processName);
            }
            else if (fieldName.Equals(Constants.VersionNumber, StringComparison.OrdinalIgnoreCase))
            {
                fieldInfo = CreateVersionFieldInfo(processName, fieldName, ColumnTypes.String);
            }
            else if (fieldName.Equals(Constants.VersionDate, StringComparison.OrdinalIgnoreCase))
            {
                fieldInfo = CreateVersionFieldInfo(processName, fieldName, ColumnTypes.DateTime);
            }
            else
            {
                fieldInfo = Cache.GetProcessFields(processName).FirstOrDefault(x => x.SystemName == fieldName);
            }

            if (fieldInfo == null)
            {
                if (throwOnError)
                    throw new Exception(string.Format(@"Field '{0}' not found in process '{1}'.", fieldName, processName));

                return null;
            }

            if (index >= 0 && index < path.Length - 1)
            {
                var joinField = GetJoinField(fieldInfo);

                if (joinField == null)
                    return null;

                var fieldDefinition = GetFieldDefinition(context, joinField.ReferencedProcess.SystemName, path.Substring(index + 1, path.Length - index - 1), throwOnError);

                if (fieldDefinition == null)
                    return null;

                fieldDefinition.JoinFields.Insert(0, joinField);

                return fieldDefinition;
            }

            return GetDisplayField(context, fieldInfo, throwOnError);
        }