Members are properties are parts of a shape, they are used to identify sub shapes that the parent shape owns
Inheritance: BaseModel
        /// <summary>
        /// Inspects list member to determine if the original list shape in the model has been
        /// substituted and if so, whether a member suffix should be used to extract the value
        /// for use in the query. An example usage would be the replacement of IpRange (in EC2)
        /// within an IpRangeList - we treat as a list of strings, yet need to get to the 
        /// IpRange.CidrIp member in the query marshalling. Note that we also have some EC2 
        /// operations where we don't want this submember extraction too even though the
        /// same substitite is in use.
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public static string DetermineAWSQueryListMemberSuffix(Operation operation, Member member)
        {
            if (member.Shape.ModelListShape == null)
                return null;

            string suffixMember = null;
            var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(member.ModelShape.ModelListShape.Name);
            if (substituteShapeData != null && substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
            {
                var useSuffix = true;
                if (substituteShapeData[CustomizationsModel.ListMemberSuffixExclusionsKey] != null)
                {
                    var exclusions = substituteShapeData[CustomizationsModel.ListMemberSuffixExclusionsKey];
                    foreach (JsonData excl in exclusions)
                    {
                        if (string.Equals(operation.Name, (string)excl, StringComparison.Ordinal))
                        {
                            useSuffix = false;
                            break;
                        }
                    }
                }

                if (useSuffix)
                    suffixMember = (string)substituteShapeData[CustomizationsModel.EmitFromMemberKey];
            }

            return suffixMember;
        }
        // The "locationName" must always be lower-cased (first letter only) when used with EC2's
        // variant of AWSQuery. MarshallLocationName isn't consistently set.
        public static string DetermineAWSQueryBaseUnmarshallName(Member member)
        {
            if (!member.model.IsEC2Protocol)
                return member.MarshallName;

            var baseExpression = string.IsNullOrEmpty(member.MarshallLocationName)
                ? member.MarshallName
                : member.MarshallLocationName;

            return TransformUnmarshallLocationName(true, baseExpression);
        }
        // List members in EC2 are always considered flattened, so we drop the 'member' prefix
        public static string DetermineAWSQueryListMemberPrefix(Member member)
        {
            if (member.model.IsEC2Protocol || member.Shape.IsFlattened)
                return string.Empty;

            if (member.Shape.IsList)
                return "member";

            if (member.Shape.IsMap)
                return "entry";

            throw new Exception("Unknown member type for list member prefix determination");
        }
        // returns the unmarshall expression for a member
        public static string DetermineAWSQueryTestExpression(Member member)
        {
            var isEC2Protocol = member.model.IsEC2Protocol;
            var testExpression = DetermineAWSQueryBaseUnmarshallName(member);
            if (member.IsList)
            {
                if (!member.Shape.IsFlattened)
                {
                    testExpression += "/";
                    if (member.Shape.ListMarshallName != null)
                        testExpression += member.Shape.ListMarshallName;
                    else
                        testExpression += "member";

                    // If the list element shape has a customization replacing it
                    // with another shape, extend the expression with any subexpression
                    // to the value member that the replaced shape has. This allows us to 
                    // handle collections of EC2's AttributeValue shape which is replaced 
                    // by a 'string' and we unmarshall the collection using the shape's 'value' 
                    // member.
                    var listShape = member.Shape.ModelListShape;
                    var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(listShape.Name);
                    if (substituteShapeData != null)
                    {
                        if (substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
                        {
                            var valueMember = (string)substituteShapeData[CustomizationsModel.EmitFromMemberKey];
                            if (isEC2Protocol)
                                testExpression += "/" + TransformUnmarshallLocationName(true, valueMember);
                            else
                                testExpression += "/" + valueMember;
                        }
                        else
                        {
                            if (listShape.ValueMarshallName != null)
                                testExpression += "/" + listShape.ValueMarshallName;
                        }
                    }
                }
                else
                {
                    testExpression = member.Shape.ListMarshallName;
                }
            }
            else if (member.IsMap)
            {
                if (!member.Shape.IsFlattened)
                    testExpression += "/entry";
            }
            else
            {
                var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(member.ModelShape.Name);
                if (substituteShapeData != null && substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
                {
                    var valueMember = (string)substituteShapeData[CustomizationsModel.EmitFromMemberKey];
                    var subMember = member.ModelShape.Members.Single(m => m.PropertyName.Equals(valueMember, StringComparison.Ordinal));

                    var subExpression = string.IsNullOrEmpty(subMember.MarshallLocationName)
                        ? subMember.MarshallName
                        : subMember.MarshallLocationName;

                    if (!string.IsNullOrEmpty(subExpression))
                        testExpression += "/" + subExpression;
                }
            }

            return testExpression;
        }
        // The marshal name must always be up-cased (first letter only) when used with EC2's
        // variant of AWSQuery. We can also apply operation-specific customizations for marshal
        // names
        public static string DetermineAWSQueryMarshallName(Member member, Operation operation)
        {
            var isEC2Protocol = member.model.IsEC2Protocol;
            CustomizationsModel.OperationModifiers modifiers = null;
            if (operation != null)
                modifiers = operation.OperationModifiers;

            var marshallName = new StringBuilder();
            if (modifiers != null)
            {
                var marshallOverride = modifiers.GetMarshallNameOverrides(member.OwningShape.Name, member.PropertyName);
                if (marshallOverride != null)
                {
                    var marshallOverrideName = !isEC2Protocol
                                                    ? marshallOverride.MarshallName
                                                    : (string.IsNullOrEmpty(marshallOverride.MarshallLocationName)
                                                        ? marshallOverride.MarshallName
                                                        : marshallOverride.MarshallLocationName);

                    marshallName.Append(TransformMarshallLocationName(isEC2Protocol, marshallOverrideName));
                }
            }

            // if the operation didn't override the marshal location, is there a property modifier doing so?
            if (marshallName.Length == 0 && member.PropertyModifier != null)
            {
                var locationName = TransformMarshallLocationName(isEC2Protocol, member.PropertyModifier.LocationName);
                marshallName.Append(locationName);
            }

            // if the marshal name still isn't set, fall back to the model
            if (marshallName.Length == 0)
            {
                var modelMarshallName = !isEC2Protocol
                                            ? member.MarshallName
                                            : (string.IsNullOrEmpty(member.MarshallLocationName)
                                                ? member.MarshallName
                                                : member.MarshallLocationName);

                marshallName.Append(TransformMarshallLocationName(isEC2Protocol, modelMarshallName));
            }

            // also check if we need to emit from a submember as a result of shape substitution
            var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(member.ModelShape.Name);
            if (substituteShapeData != null && substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
            {
                var valueMember = (string) substituteShapeData[CustomizationsModel.EmitFromMemberKey];
                var subMember = member.ModelShape.Members.Single(m => m.PropertyName.Equals(valueMember, StringComparison.Ordinal));
                if (subMember != null)
                {
                    var subExpression = string.IsNullOrEmpty(subMember.MarshallLocationName)
                        ? subMember.MarshallName
                        : subMember.MarshallLocationName;

                    marshallName.AppendFormat(".{0}", TransformMarshallLocationName(isEC2Protocol, subExpression));
                }
            }

            return marshallName.ToString();
        }
        /// <summary>
        /// Determines if a property modifier for the member is suppressing automatic marshall
        /// generation code for the field. If true, custom code in the pipeline will handle the
        /// member.
        /// </summary>
        /// <param name="member"></param>
        /// <param name="operation"></param>
        /// <returns></returns>
        public static bool UseCustomMarshall(Member member, Operation operation)
        {
            if (member.PropertyModifier != null && member.PropertyModifier.IsSetUseCustomMarshall)
                return member.PropertyModifier.UseCustomMarshall;

            if (member.PropertyInjector != null && member.PropertyInjector.IsSetUseCustomMarshall)
                return member.PropertyInjector.UseCustomMarshall;

            return false;
        }
        private void ValidateProperty(string parameterBase, Type type, object propertyValue, string propertyName, Member member)
        {
            if (IsScalarValue(type))
            {
                var key = parameterBase;
                if (!string.IsNullOrEmpty(key))
                    key += ".";

                key += GeneratorHelpers.DetermineAWSQueryMarshallName(member, this.Operation);

                Assert.IsTrue(this.Parameters.ContainsKey(key), "Failed to find query key " + key);
            }
            else
            {
                if (type.GetInterface("System.Collections.IList") != null)
                {
                    var list = propertyValue as System.Collections.IList;
                    for (var i = 0; i < list.Count; i++)
                    {
                        var item = list[i];
                        var queryKey = ConstructMemberQueryKey(parameterBase, member, i+1);
                        if (IsScalarValue(item.GetType()))
                        {
                            Assert.IsTrue(this.Parameters.ContainsKey(queryKey), "Failed to find query key " + queryKey);
                        }
                        else
                        {
                            Validate(queryKey, item, member.Shape.ListShape);
                        }
                    }
                }
                else if (type.GetInterface("System.Collections.IDictionary") != null)
                {
                    var map = propertyValue as System.Collections.IDictionary;
                    var i = 1;
                    foreach (var key in map.Keys)
                    {
                        object value = map[key];
                        var queryKey = ConstructMemberQueryKey(parameterBase, member, i);

                        Assert.IsTrue(this.Parameters.ContainsKey(queryKey + "." + member.Shape.KeyMarshallName), "Failed to find query key " + queryKey + "." + member.Shape.KeyMarshallName);

                        if (IsScalarValue(value.GetType()))
                        {
                            Assert.IsTrue(this.Parameters.ContainsKey(queryKey + "." + member.Shape.ValueMarshallName), "Failed to find query key " + queryKey + "." + member.Shape.ValueMarshallName);
                        }
                        else
                        {
                            Validate(queryKey + "." + member.Shape.ValueMarshallName, value, member.Shape.ValueShape);
                        }

                        i++;
                    }
                    
                }
                else
                {
                    var key = parameterBase;
                    if (!string.IsNullOrEmpty(key))
                        key += ".";

                    key += GeneratorHelpers.DetermineAWSQueryMarshallName(member, this.Operation);

                    Validate(key, propertyValue, member.Shape);
                }
            }
        }
        private string ConstructMemberQueryKey(string parameterBase, Member member, int memberIndex)
        {
            var queryKey = new StringBuilder(parameterBase);
            if (queryKey.Length > 0)
                queryKey.Append(".");

            queryKey.AppendFormat("{0}.", GeneratorHelpers.DetermineAWSQueryMarshallName(member, this.Operation));
            var memberPrefix = GeneratorHelpers.DetermineAWSQueryListMemberPrefix(member); // can return empty for EC2/AWSQuery
            if (!string.IsNullOrEmpty(memberPrefix))
                queryKey.AppendFormat("{0}.", memberPrefix);
            queryKey.Append(memberIndex);

            var memberSuffix = GeneratorHelpers.DetermineAWSQueryListMemberSuffix(this.Operation, member);
            if (memberSuffix != null)
                queryKey.AppendFormat(".{0}", memberSuffix);

            return queryKey.ToString();
        }
 /// <summary>
 /// Given a member and sample data, build a literal/instantation for the
 /// member's type with the sample data.
 /// </summary>
 /// <param name="member">The member in the model</param>
 /// <param name="data">Sample data to populate the literal with</param>
 /// <param name="cb">A CodeBuilder instance to write the code to.</param>
 public void GetSampleLiteral(Member member, JsonData data, CodeBuilder cb)
 {
     GetSampleLiteral(member.Shape, data, cb);
 }
        private void WriteArray(XmlWriter writer, Member member, Shape shape)
        {
            if (!shape.IsFlattened)
            {
                writer.WriteStartElement(GeneratorHelpers.DetermineAWSQueryBaseUnmarshallName(member));
            }

            for (int i = 0; i < shape.Name.Length % 5 + 2; i++)
            {
                writer.WriteStartElement(shape.ListMarshallName ?? "member");
                Write(writer, shape.ModelListShape);
                writer.WriteEndElement();
            }

            if (!shape.IsFlattened)
                writer.WriteEndElement();
        }
 /// <summary>
 /// Create a new OperationPaginatorConfigOption object
 /// and set whether or not it is a jmespath expression
 /// </summary>
 /// <param name="isJmesPath"> Whether or not it is a jmespath expression </param>
 /// <param name="member"> Member associated with the option </param>
 public OperationPaginatorConfigOption(bool isJmesPath, Member member)
 {
     IsJmesPath = isJmesPath;
     Member     = member;
 }
 /// <summary>
 /// Create a new OperationPaginatorConfigOption object
 /// and set whether or not it is a jmespath expression
 /// </summary>
 /// <param name="isJmesPath"> Whether or not it is a jmespath expression </param>
 /// <param name="member"> Member associated with the option </param>
 /// <param name="wrappedResultMember">If the result of this operation is wrapped in a response
 /// object. (workaround for SimpleWorkFlow) </param>
 public OperationPaginatorConfigOption(bool isJmesPath, string wrappedResultMember, Member member)
     : this(isJmesPath, member)
 {
     WrappedResultMember = wrappedResultMember;
 }
 /// <summary>
 /// Create a new OperationPaginatorConfigOption object
 /// and set whether or not it is a jmespath expression
 /// </summary>
 /// <param name="isJmesPath"> Whether or not it is a jmespath expression </param>
 /// <param name="member"> Member associated with the option </param>
 /// <param name="name"> String name of the option as found in paginator config </param>
 public OperationPaginatorConfigOption(bool isJmesPath, Member member, string name)
     : this(isJmesPath, member)
 {
     Name = name;
 }
Example #14
0
 /// <summary>
 /// Given a member and sample data, build a literal/instantation for the
 /// member's type with the sample data.
 /// </summary>
 /// <param name="member">The member in the model</param>
 /// <param name="data">Sample data to populate the literal with</param>
 /// <param name="cb">A CodeBuilder instance to write the code to.</param>
 public void GetSampleLiteral(Member member, JsonData data, CodeBuilder cb)
 {
     GetSampleLiteral(member.Shape, data, cb);
 }
Example #15
0
        // returns the unmarshall expression for a member
        public static string DetermineAWSQueryTestExpression(Member member)
        {
            var isEC2Protocol  = member.model.IsEC2Protocol;
            var testExpression = DetermineAWSQueryBaseUnmarshallName(member);

            if (member.IsList)
            {
                if (!member.Shape.IsFlattened)
                {
                    testExpression += "/";
                    if (member.Shape.ListMarshallName != null)
                    {
                        testExpression += member.Shape.ListMarshallName;
                    }
                    else
                    {
                        testExpression += "member";
                    }

                    // If the list element shape has a customization replacing it
                    // with another shape, extend the expression with any subexpression
                    // to the value member that the replaced shape has. This allows us to
                    // handle collections of EC2's AttributeValue shape which is replaced
                    // by a 'string' and we unmarshall the collection using the shape's 'value'
                    // member.
                    var listShape           = member.Shape.ModelListShape;
                    var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(listShape.Name);
                    if (substituteShapeData != null)
                    {
                        if (substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
                        {
                            var valueMember = (string)substituteShapeData[CustomizationsModel.EmitFromMemberKey];
                            if (isEC2Protocol)
                            {
                                testExpression += "/" + TransformUnmarshallLocationName(true, valueMember);
                            }
                            else
                            {
                                testExpression += "/" + valueMember;
                            }
                        }
                        else
                        {
                            if (listShape.ValueMarshallName != null)
                            {
                                testExpression += "/" + listShape.ValueMarshallName;
                            }
                        }
                    }
                }
                else
                {
                    testExpression = member.Shape.ListMarshallName;
                }
            }
            else if (member.IsMap)
            {
                if (!member.Shape.IsFlattened)
                {
                    testExpression += "/entry";
                }
            }
            else
            {
                var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(member.ModelShape.Name);
                if (substituteShapeData != null && substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
                {
                    var valueMember = (string)substituteShapeData[CustomizationsModel.EmitFromMemberKey];
                    var subMember   = member.ModelShape.Members.Single(m => m.PropertyName.Equals(valueMember, StringComparison.Ordinal));

                    var subExpression = string.IsNullOrEmpty(subMember.MarshallLocationName)
                        ? subMember.MarshallName
                        : subMember.MarshallLocationName;

                    if (!string.IsNullOrEmpty(subExpression))
                    {
                        testExpression += "/" + subExpression;
                    }
                }
            }

            return(testExpression);
        }
Example #16
0
        // The marshal name must always be up-cased (first letter only) when used with EC2's
        // variant of AWSQuery. We can also apply operation-specific customizations for marshal
        // names
        public static string DetermineAWSQueryMarshallName(Member member, Operation operation)
        {
            var isEC2Protocol = member.model.IsEC2Protocol;

            CustomizationsModel.OperationModifiers modifiers = null;
            if (operation != null)
            {
                modifiers = operation.OperationModifiers;
            }

            var marshallName = new StringBuilder();

            if (modifiers != null)
            {
                var marshallOverride = modifiers.GetMarshallNameOverrides(member.OwningShape.Name, member.PropertyName);
                if (marshallOverride != null)
                {
                    var marshallOverrideName = !isEC2Protocol
                                                    ? marshallOverride.MarshallName
                                                    : (string.IsNullOrEmpty(marshallOverride.MarshallLocationName)
                                                        ? marshallOverride.MarshallName
                                                        : marshallOverride.MarshallLocationName);

                    marshallName.Append(TransformMarshallLocationName(isEC2Protocol, marshallOverrideName));
                }
            }

            // if the operation didn't override the marshal location, is there a property modifier doing so?
            if (marshallName.Length == 0 && member.PropertyModifier != null)
            {
                var locationName = TransformMarshallLocationName(isEC2Protocol, member.PropertyModifier.LocationName);
                marshallName.Append(locationName);
            }

            // if the marshal name still isn't set, fall back to the model
            if (marshallName.Length == 0)
            {
                var modelMarshallName = !isEC2Protocol
                                            ? member.MarshallName
                                            : (string.IsNullOrEmpty(member.MarshallLocationName)
                                                ? member.MarshallName
                                                : member.MarshallLocationName);

                marshallName.Append(TransformMarshallLocationName(isEC2Protocol, modelMarshallName));
            }

            // also check if we need to emit from a submember as a result of shape substitution
            var substituteShapeData = member.model.Customizations.GetSubstituteShapeData(member.ModelShape.Name);

            if (substituteShapeData != null && substituteShapeData[CustomizationsModel.EmitFromMemberKey] != null)
            {
                var valueMember = (string)substituteShapeData[CustomizationsModel.EmitFromMemberKey];
                var subMember   = member.ModelShape.Members.Single(m => m.PropertyName.Equals(valueMember, StringComparison.Ordinal));
                if (subMember != null)
                {
                    var subExpression = string.IsNullOrEmpty(subMember.MarshallLocationName)
                        ? subMember.MarshallName
                        : subMember.MarshallLocationName;

                    marshallName.AppendFormat(".{0}", TransformMarshallLocationName(isEC2Protocol, subExpression));
                }
            }

            return(marshallName.ToString());
        }