Example #1
0
		/// <summary>
		/// Get all value roles including all roles directly attached to the provided
		/// object type and any roles descended from this one through prefererred identifiers.
		/// Walks the opposite direction of <see cref="Role.GetValueRoles()"/>
		/// </summary>
		/// <param name="anchorType">The <see cref="ObjectType"/> to walk descended roles for</param>
		/// <param name="unattachedRole">A role to test that is not currently attached to the anchorType.
		/// If unattachedRole is not null, then only this role will be tested. Otherwise, all current played
		/// roles will be walked.</param>
		/// <param name="unattachedPreferredIdentifier">A preferred identifier to test that is not currently
		/// attached to the anchorType.</param>
		/// <param name="visitor">A <see cref="ValueRoleVisitor"/> callback delegate.</param>
		public static void WalkDescendedValueRoles(ObjectType anchorType, Role unattachedRole, UniquenessConstraint unattachedPreferredIdentifier, ValueRoleVisitor visitor)
		{
			ValueTypeHasDataType dataTypeLink = anchorType.GetDataTypeLink();
			if (null == unattachedPreferredIdentifier &&
				null != (dataTypeLink = anchorType.GetDataTypeLink()))
			{
				ObjectType unattachedRolePlayer;
				WalkDescendedValueRoles(
					(unattachedRole != null) ? new Role[] { unattachedRole } as IList<Role> : anchorType.PlayedRoleCollection,
					RolePathObjectTypeRoot.GetLinksToRolePathCollection(anchorType),
					dataTypeLink,
					anchorType.ValueConstraint,
					null,
					(null == unattachedRole || null == (unattachedRolePlayer = unattachedRole.RolePlayer)) ? false : !unattachedRolePlayer.IsValueType,
					visitor);
			}
			else
			{
				LinkedElementCollection<Role> roles;
				UniquenessConstraint preferredIdentifier;
				if (null != (preferredIdentifier = unattachedPreferredIdentifier ?? anchorType.ResolvedPreferredIdentifier) &&
					(roles = preferredIdentifier.RoleCollection).Count == 1)
				{
					Role currentRole = roles[0];
					Role[] valueRoles = currentRole.GetValueRoles();
					if (valueRoles != null)
					{
						ValueConstraint nearestValueConstraint = null;
						int valueRolesCount = valueRoles.Length;
						for (int i = valueRolesCount - 1; i >= 0; --i)
						{
							nearestValueConstraint = valueRoles[i].ValueConstraint;
							if (nearestValueConstraint != null)
							{
								break;
							}
						}
						ObjectType valueType = valueRoles[0].RolePlayer;
						dataTypeLink = valueType.GetDataTypeLink();
						if (nearestValueConstraint == null)
						{
							nearestValueConstraint = valueType.ValueConstraint;
						}
						RoleBase nextSkipRole = currentRole.OppositeRoleAlwaysResolveProxy;
						if (nextSkipRole != null)
						{
							WalkDescendedValueRoles(
								(unattachedRole != null) ? new Role[] { unattachedRole } as IList<Role> : anchorType.PlayedRoleCollection,
								RolePathObjectTypeRoot.GetLinksToRolePathCollection(anchorType),
								dataTypeLink,
								nearestValueConstraint,
								nextSkipRole.Role,
								true,
								visitor);
						}
					}
				}
			}
		}