public static void SetProperties()

in src/main/csharp/Util/IntrospectionSupport.cs [164:282]


        public static void SetProperties(object target,
            StringDictionary valueMap,
			StringDictionary nameMap)
        {
			Tracer.DebugFormat("SetProperties called with target: {0}",
				target.GetType().Name);

			// Application of specified values is recursive. If a key does not
			// correspond to a member of the current target object, it is
			// supposed to refer to a sub-member of such a member. Since member
			// keys can contain dot characters, an attempt is made to find the
			// "longest" key corresponding to a member of the current object
			// (this identifies the "sub-target"), and extract the remaining
			// key characters as a sub-key to sub-members.
			// The following dictionary indexes keys to "sub-targets", and
			// "sub-key"/value pairs to assign to "sub-targets".
			Dictionary<string, StringDictionary> subTargetMap = null;

			foreach(string key in valueMap.Keys)
			{
				if(nameMap.ContainsKey(key))
				{
					// Key refers to a member of the current target
					string memberName = nameMap[key];
					MemberInfo member = FindMemberInfo(target, memberName);
					if(member == null)
					{
						// Should not happen if the nameMap was indeed created
						// for the current target object...
						throw new NMSException(string.Format(
							"No such property or field: {0} on class: {1}",
							memberName, target.GetType().Name));
					}

					// Set value
					try
					{
						if(member.MemberType == MemberTypes.Property)
						{
							PropertyInfo property = (PropertyInfo)member;
							object value = ConvertValue(valueMap[key],
								property.PropertyType);
							property.SetValue(target, value, null);
						}
						else
						{
							FieldInfo field = (FieldInfo)member;
							object value = ConvertValue(valueMap[key],
								field.FieldType);
							field.SetValue(target, value);
						}
					}
					catch(Exception ex)
					{
						throw NMSExceptionSupport.Create(
							"Error while attempting to apply option.", ex);
					}
                }
				else
				{
					// Key does NOT refers to a member of the current target
					// Extract maximal member key + subkeys
					string memberKey = key;
					int dotPos = memberKey.LastIndexOf('.');
					bool memberFound = false;
					while(!memberFound && dotPos > 0)
					{
						memberKey = memberKey.Substring(0, dotPos);
						if(nameMap.ContainsKey(memberKey))
						{
							memberKey = nameMap[memberKey];
							memberFound = true;
						}
						else
						{
							dotPos = memberKey.LastIndexOf('.');
						}
					}

					if(!memberFound)
					{
						throw new NMSException(string.Format(
							"Unknown property or field: {0} on class: {1}",
							key, target.GetType().Name));
					}

					// Register memberKey, subKey and value for further processing
					string subKey = key.Substring(dotPos + 1);
					StringDictionary subValueMap;

					if(subTargetMap == null)
					{
						subTargetMap = new Dictionary<string, StringDictionary>();
					}

					if(!subTargetMap.TryGetValue(memberKey, out subValueMap))
					{
						subValueMap = new StringDictionary();
						subTargetMap.Add(memberKey, subValueMap);
					}

					// In theory, we can't have the same subkey twice, since
					// they were unique subkeys from another dictionary.
					// Therefore, no need to check for subValueMap.ContainsKey.
					subValueMap.Add(subKey, valueMap[key]);
				}
            }

			// Now process any compound assignments.
			if(subTargetMap != null)
			{
				foreach(string subTargetKey in subTargetMap.Keys)
				{
					MemberInfo member = FindMemberInfo(target, subTargetKey);
					object subTarget = GetUnderlyingObject(member, target);
					SetProperties(subTarget, subTargetMap[subTargetKey]);
				}
			}
        }