public override string GetValue(GridValue.GridControl control, Property property, ICollection <ArtifactDependency> dependencies) { // cancel if there's no values if (control.Value == null || control.Value.HasValues == false) { return(null); } var docTypeGridEditorContent = JsonConvert.DeserializeObject <DocTypeGridEditorValue>(control.Value.ToString()); // if an 'empty' dtge item has been added - it has no ContentTypeAlias set .. just return and don't throw. if (docTypeGridEditorContent == null || string.IsNullOrWhiteSpace(docTypeGridEditorContent.ContentTypeAlias)) { return(null); } // check if the doc type exist - else abort packaging var contentType = _contentTypeService.GetContentType(docTypeGridEditorContent.ContentTypeAlias); if (contentType == null) { throw new InvalidOperationException( $"Could not resolve the Content Type for the Doc Type Grid Editor property: {docTypeGridEditorContent.ContentTypeAlias}"); } // add content type as a dependency dependencies.Add(new ArtifactDependency(contentType.GetUdi(), false, ArtifactDependencyMode.Match)); // find all properties var propertyTypes = contentType.CompositionPropertyTypes; foreach (var propertyType in propertyTypes) { // test if there's a value for the given property object value; if (!docTypeGridEditorContent.Value.TryGetValue(propertyType.Alias, out value) || value == null) { continue; } Udi udi; // if the value is an Udi then add it as a dependency if (Udi.TryParse(value.ToString(), out udi)) { dependencies.Add(new ArtifactDependency(udi, false, ArtifactDependencyMode.Match)); continue; } // throws if not found - no need for a null check var propValueConnector = ValueConnectors.Get(propertyType); var mockProperty = new Property(propertyType, value); var parsedValue = propValueConnector.GetValue(mockProperty, dependencies); // test if the value is a json object (thus could be a nested complex editor) // if that's the case we'll need to add it as a json object instead of string to avoid it being escaped var jtokenValue = parsedValue != null && parsedValue.DetectIsJson() ? JToken.Parse(parsedValue) : null; if (jtokenValue != null) { docTypeGridEditorContent.Value[propertyType.Alias] = jtokenValue; } else { docTypeGridEditorContent.Value[propertyType.Alias] = parsedValue; } } var resolvedValue = JsonConvert.SerializeObject(docTypeGridEditorContent); return(resolvedValue); }
/// <inheritdoc/> public override string GetValue(GridValue.GridControl control, Property property, ICollection <ArtifactDependency> dependencies) { // cancel if there's no values if (control.Value == null || control.Value.HasValues == false) { return(null); } // Often there is only one entry in cell.Value, but with LeBlender // min/max you can easily get 2+ entries so we'll walk them all var newItemValue = new List <object>(); foreach (var properties in control.Value) { // create object to store resolved properties var resolvedProperties = new JObject(); foreach (var leBlenderPropertyWrapper in properties) { if (leBlenderPropertyWrapper.HasValues == false) { continue; } var leBlenderProperty = leBlenderPropertyWrapper.First.ToObject <LeBlenderGridCellValue>(); // get the data type of the property var dataType = _dataTypeService.GetDataTypeDefinitionById(leBlenderProperty.DataTypeGuid); if (dataType == null) { throw new ArgumentNullException( $"Unable to find the data type for editor '{leBlenderProperty.EditorName}' ({leBlenderProperty.EditorAlias} {leBlenderProperty.DataTypeGuid}) referenced by '{property.Alias}'."); } // add the datatype as a dependency dependencies.Add(new ArtifactDependency(dataType.GetUdi(), false, ArtifactDependencyMode.Exist)); // if it's null or undefined value there is no need to do any more processing if (leBlenderProperty.Value.Type == JTokenType.Null || leBlenderProperty.Value.Type == JTokenType.Undefined) { resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); continue; } Udi udi; // if the value is an Udi then add it as a dependency if (Udi.TryParse(leBlenderProperty.Value.ToString(), out udi)) { dependencies.Add(new ArtifactDependency(udi, false, ArtifactDependencyMode.Exist)); resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); continue; } var tempDependencies = new List <Udi>(); // try to convert the value with the macro parser - this is mainly for legacy editors var value = _macroParser.ReplaceAttributeValue(leBlenderProperty.Value.ToString(), dataType.PropertyEditorAlias, tempDependencies, Direction.ToArtifact); foreach (var dependencyUdi in tempDependencies) { // if the macro parser was able to convert the value it will mark the Udi as dependency // and we want that added as a artifact dependency dependencies.Add(new ArtifactDependency(dependencyUdi, false, ArtifactDependencyMode.Exist)); } // test if the macroparser converted the value to an Udi if (Udi.TryParse(value, out udi)) { leBlenderProperty.Value = value; resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); continue; } // if the macro parser didn't convert the value then try to find a value connector that can and convert it var propertyType = new PropertyType(dataType.PropertyEditorAlias, dataType.DatabaseType); propertyType.DataTypeDefinitionId = dataType.Id; var propValueConnector = ValueConnectors.Get(propertyType); if (leBlenderProperty.Value.Type == JTokenType.Array) { // if the value is an array then we should try and convert each item instead of the whole array var array = new JArray(); foreach (var child in leBlenderProperty.Value) { var mockProperty = new Property(propertyType, child.Value <object>()); var convertedValue = propValueConnector.GetValue(mockProperty, dependencies); array.Add(new JValue(convertedValue)); } leBlenderProperty.Value = array; } else { var mockProperty = new Property(propertyType, leBlenderProperty.Value); value = propValueConnector.GetValue(mockProperty, dependencies); leBlenderProperty.Value = value; } resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); } newItemValue.Add(resolvedProperties); } return(JsonConvert.SerializeObject(newItemValue)); }
public override void SetValue(GridValue.GridControl control, Property property) { var emptyValue = control.Value.ToString(); if (string.IsNullOrWhiteSpace(emptyValue)) { return; } // For some reason the control value isn't properly parsed so we need this extra step to parse it into a JToken control.Value = JToken.Parse(control.Value.ToString()); // cancel if there's no values if (control.Value == null || control.Value.HasValues == false) { return; } var docTypeGridEditorContent = JsonConvert.DeserializeObject <DocTypeGridEditorValue>(control.Value.ToString()); if (docTypeGridEditorContent == null) { return; } // check if the doc type exist - else abort packaging var contentType = _contentTypeService.GetContentType(docTypeGridEditorContent.ContentTypeAlias); if (contentType == null) { throw new InvalidOperationException( $"Could not resolve the Content Type for the Doc Type Grid Editor property: {docTypeGridEditorContent.ContentTypeAlias}"); } // find all properties var propertyTypes = contentType.CompositionPropertyTypes; foreach (var propertyType in propertyTypes) { // test if there's a value for the given property object value; if (!docTypeGridEditorContent.Value.TryGetValue(propertyType.Alias, out value) || value == null) { continue; } // throws if not found - no need for a null check var propValueConnector = ValueConnectors.Get(propertyType); var mockProperty = new Property(propertyType); var mockContent = new Content("mockContentGrid", -1, new ContentType(-1), new PropertyCollection(new List <Property> { mockProperty })); propValueConnector.SetValue(mockContent, mockProperty.Alias, value.ToString()); var convertedValue = mockContent.GetValue(mockProperty.Alias); // integers needs to be converted into strings for DTGE to work if (convertedValue is int) { docTypeGridEditorContent.Value[propertyType.Alias] = convertedValue.ToString(); } else if (convertedValue == null) { //Assign the null back - otherwise the check for JSON will fail as we cant convert a null to a string //NOTE: LinkPicker2 for example if no link set is returning a null as opposed to empty string docTypeGridEditorContent.Value[propertyType.Alias] = null; } else { // test if the value is a json object (thus could be a nested complex editor) // if that's the case we'll need to add it as a json object instead of string to avoid it being escaped var jtokenValue = convertedValue.ToString().DetectIsJson() ? JToken.Parse(convertedValue.ToString()) : null; if (jtokenValue != null) { docTypeGridEditorContent.Value[propertyType.Alias] = jtokenValue; } else { docTypeGridEditorContent.Value[propertyType.Alias] = convertedValue; } } } control.Value = JToken.FromObject(docTypeGridEditorContent); }
/// <inheritdoc/> public override void SetValue(GridValue.GridControl control, Property property) { var value = control.Value.ToString(); if (string.IsNullOrWhiteSpace(value)) { return; } // For some reason the control value isn't properly parsed so we need this extra step to parse it into a JToken control.Value = JToken.Parse(control.Value.ToString()); // cancel if there's no values or it didn't parse if (control.Value == null || control.Value.HasValues == false) { return; } // Often there is only one entry in cell.Value, but with LeBlender // min/max you can easily get 2+ entries so we'll walk them all var newItemValue = new JArray(); foreach (var properties in control.Value) { // create object to store resolved properties var resolvedProperties = new JObject(); foreach (var leBlenderPropertyWrapper in properties) { if (leBlenderPropertyWrapper.HasValues == false) { continue; } var leBlenderProperty = leBlenderPropertyWrapper.First.ToObject <LeBlenderGridCellValue>(); // get the data type of the property var dataType = _dataTypeService.GetDataTypeDefinitionById(leBlenderProperty.DataTypeGuid); if (dataType == null) { throw new ArgumentNullException( $"Unable to find the data type for editor '{leBlenderProperty.EditorName}' ({leBlenderProperty.EditorAlias} {leBlenderProperty.DataTypeGuid}) referenced by '{property.Alias}'."); } // if it's null or undefined value there is no need to do any more processing if (leBlenderProperty.Value.Type == JTokenType.Null || leBlenderProperty.Value.Type == JTokenType.Undefined) { resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); continue; } Udi udi; // if the value is an Udi then add it as a dependency and move on if (Udi.TryParse(leBlenderProperty.Value.ToString(), out udi)) { // if the value was converted with the macro parser it needs to be converted back again // the macro parser should just return the value if it doesn't support the editor leBlenderProperty.Value = _macroParser.ReplaceAttributeValue(leBlenderProperty.Value.ToString(), dataType.PropertyEditorAlias, null, Direction.FromArtifact); resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); continue; } var propertyType = new PropertyType(dataType.PropertyEditorAlias, dataType.DatabaseType, MockPropertyTypeAlias); propertyType.DataTypeDefinitionId = dataType.Id; // get the value connector for the property type var propValueConnector = ValueConnectors.Get(propertyType); // we need to create a mocked property that we can parse in to the value connector var mockProperty = new Property(propertyType); var mockContent = new Content("mockContent", -1, new ContentType(-1), new PropertyCollection(new List <Property> { mockProperty })); if (leBlenderProperty.Value.Type == JTokenType.Array) { // if the value is an array then we should try and convert each item var array = new JArray(); foreach (var child in leBlenderProperty.Value) { propValueConnector.SetValue(mockContent, mockProperty.Alias, child.Value <object>().ToString()); var convertedValue = mockContent.GetValue(mockProperty.Alias); // if the value stored is json then we should try to deserialize it into an object // because some property editors like the Related Links editor doesn't work unless its done convertedValue = convertedValue is string && convertedValue.ToString().DetectIsJson() ? JsonConvert.DeserializeObject(convertedValue.ToString()) : convertedValue; array.Add(convertedValue); } leBlenderProperty.Value = array; } else { propValueConnector.SetValue(mockContent, mockProperty.Alias, leBlenderProperty.Value.ToString()); var convertedValue = mockContent.GetValue(mockProperty.Alias); leBlenderProperty.Value = new JValue(convertedValue); } resolvedProperties.Add(leBlenderProperty.EditorAlias, JObject.FromObject(leBlenderProperty)); } newItemValue.Add(resolvedProperties); } control.Value = newItemValue; }