Пример #1
0
			private static string GetImplicitBooleanValueTypeName(Role unaryRole)
			{
				string unaryRoleName = unaryRole.Name;
				ObjectType unaryRolePlayer = unaryRole.RolePlayer;
				FactType unaryFactType;
				IReading defaultReading;
				if (unaryRolePlayer != null && !string.IsNullOrEmpty(unaryRoleName))
				{
					// UNDONE: Localize the space? (Some languages may not use spaces between words.)
					return unaryRolePlayer.Name + " " + unaryRoleName;
				}
				else if (null != (defaultReading = (unaryFactType = unaryRole.FactType).GetDefaultReading()))
				{
					return string.Format(CultureInfo.InvariantCulture, defaultReading.Text.Replace('-', ' '), (unaryRolePlayer != null) ? unaryRolePlayer.Name.Replace('-', ' ') : ResourceStrings.ModelReadingEditorMissingRolePlayerText);
				}
				return unaryFactType.Name;
			}
		/// <summary>
		/// Attempts to fix a PopulationMandatoryError
		/// </summary>
		/// <param name="error">Error to be corrected</param>
		/// <param name="autoCorrectRole">The <see cref="Role"/> to correct the error for.</param>
		/// <param name="autoCorrectFactType">If the <paramref name="autoCorrectRole"/> is not specified, select
		/// a unique constrained role from this <see cref="FactType"/></param>
		/// <returns><see langword="true"/> if the error was automatically corrected.</returns>
		public bool AutoCorrectMandatoryError(PopulationMandatoryError error, Role autoCorrectRole, FactType autoCorrectFactType)
		{
			bool retVal = false;
			ObjectTypeInstance objectInstance = error.ObjectTypeInstance;
			LinkedElementCollection<Role> constraintRoles = error.MandatoryConstraint.RoleCollection;

			// If the constraint has multiple roles, then we need to pick
			// a role to activate. This is trivial for a simple mandatory
			// constraint, or if a role in the constraint is selected. However,
			// if we have only a FactType selection, then there may be multiple
			// potential roles in the constraint for ring situations.
			if (constraintRoles.Count == 1)
			{
				autoCorrectRole = constraintRoles[0];
				autoCorrectFactType = autoCorrectRole.FactType;
			}
			else
			{
				// We're only interested in one selected item, this code
				// path should not be running with multiple items selected.
				if (autoCorrectRole == null)
				{
					if (autoCorrectFactType != null)
					{
						foreach (Role testRole in constraintRoles)
						{
							if (testRole.FactType == autoCorrectFactType)
							{
								if (autoCorrectRole == null)
								{
									autoCorrectRole = testRole;
								}
								else
								{
									// Ambiguous selection, there is nothing further we can do
									autoCorrectRole = null;
									break;
								}
							}
						}
					}
				}
				else if (autoCorrectFactType == null)
				{
					autoCorrectFactType = autoCorrectRole.FactType;
				}
			}
			if (autoCorrectFactType != null)
			{
				// Verify the selection, which needs to be set before this method is called
				SubtypeFact subtypeFact;
				bool correctSelection;
				if (CurrentFrameVisibility != FrameVisibility.Visible)
				{
					// If the window is not active then it does not have a selection
					this.ShowNoActivate();
				}
				if (null != (subtypeFact = autoCorrectFactType as SubtypeFact) &&
					subtypeFact.ProvidesPreferredIdentifier)
				{
					ObjectType subtype = subtypeFact.Subtype;
					ObjectType selectedEntityType;
					FactType objectifiedFactType;
					correctSelection = (null != (selectedEntityType = SelectedEntityType) && selectedEntityType == subtype) ||
						(null != (objectifiedFactType = subtype.NestedFactType) && objectifiedFactType == SelectedFactType);
				}
				else if (!(correctSelection = SelectedFactType == autoCorrectFactType))
				{
					FactTypeInstanceImplication implication = new FactTypeInstanceImplication(autoCorrectFactType);
					correctSelection = implication.IsImplied && implication.ImpliedProxyRole == null && implication.IdentifyingSupertype != null && implication.ImpliedByEntityType == SelectedEntityType;
				}
				if (correctSelection)
				{
					this.Show();
					if (autoCorrectRole != null)
					{
						retVal = myEditor.AutoCorrectMandatoryError(error, autoCorrectRole);
					}
				}
			}
			return retVal;
		}
		/// <summary>
		/// If a role is actively selected, return the 0-based selection index,
		/// or -1 if the role is not actively selected.
		/// </summary>
		/// <param name="role">A role to test</param>
		/// <returns>0-based role index, or -1 if not selected</returns>
		public int GetActiveRoleIndex(Role role)
		{
			if (IsActive && mySelectedRoles != null)
			{
				return mySelectedRoles.IndexOf(role);
			}
			return -1;
		}
Пример #4
0
		/// <summary>
		/// Sets the isVisible property for the given Role
		/// </summary>
		private static void SetRoleNameDisplay(Role role, FactTypeShape parentShape, bool shouldDisplay, bool shouldRemove)
		{
			if (!shouldRemove)
			{
				Diagram.FixUpDiagram(role.FactType, role);
			}
			LinkedElementCollection<PresentationElement> pels = PresentationViewsSubject.GetPresentation(role);
			int pelCount = pels.Count;
			for (int i = pelCount - 1; i >= 0; --i)
			{
				RoleNameShape rns = pels[i] as RoleNameShape;
				if (rns != null &&
					(parentShape == null || rns.ParentShape == parentShape))
				{
					if (shouldRemove)
					{
						rns.Delete();
					}
					else
					{
						if (shouldDisplay)
						{
							rns.Show();
						}
						else
						{
							rns.Hide();
							rns.Size = SizeD.Empty;
						}
					}
				}
			}
		}
Пример #5
0
			/// <summary>
			/// Checks the <see cref="IConstraint"/>s on the binarized unary <see cref="FactType"/> as specified by
			/// the <see cref="FactType"/>'s <paramref name="unaryRole"/> and the <paramref name="implicitBooleanRole"/>.
			/// </summary>
			private static bool ValidateConstraints(Role unaryRole, Role implicitBooleanRole)
			{
				ConstraintRoleSequence unaryRoleUniquenessConstraint = unaryRole.SingleRoleAlethicUniquenessConstraint;
				if (unaryRoleUniquenessConstraint == null)
				{
					// The alethic single role uniqueness constraint is missing from the unary role.
					return false;
				}

				// Validate the constraints on the unary role
				foreach (ConstraintRoleSequence constraintRoleSequence in unaryRole.ConstraintRoleSequenceCollection)
				{
					IConstraint constraint = constraintRoleSequence.Constraint;
					switch (constraint.ConstraintType)
					{
						case ConstraintType.InternalUniqueness:
						case ConstraintType.ExternalUniqueness:
						case ConstraintType.Frequency:
							if (constraintRoleSequence != unaryRoleUniquenessConstraint)
							{
								// The unary role has a constraint attached to it that it shouldn't
								return false;
							}
							break;
					}
				}

				// Validate the constraints on the implicit boolean role
				foreach (ConstraintRoleSequence constraintRoleSequence in implicitBooleanRole.ConstraintRoleSequenceCollection)
				{
					IConstraint constraint = constraintRoleSequence.Constraint;
					switch (constraint.ConstraintType)
					{
						case ConstraintType.DisjunctiveMandatory:
						case ConstraintType.Equality:
						case ConstraintType.Exclusion:
						case ConstraintType.Ring:
						case ConstraintType.SimpleMandatory:
						case ConstraintType.Subset:
						case ConstraintType.InternalUniqueness:
							// The implicit boolean role has a constraint attached to it that it shouldn't
							return false;
					}
				}

				return true;
			}
Пример #6
0
		/// <summary>
		/// Resolve the name that will be used for a <see cref="ConceptTypeChild"/> given the <see cref="Role"/> it's resulting from.
		/// </summary>
		/// <param name="role">The <see cref="Role"/> that the <see cref="ConceptTypeChild"/> is resulting from.</param>
		/// <returns>The name to use for the <see cref="ConceptTypeChild"/>.</returns>
		private static string ResolveRoleName(Role role)
		{
			// HACK: This is only here until we implement a better alternative.
			string name = role.Name;

			if (String.IsNullOrEmpty(name))
			{
				name = role.RolePlayer.Name;
			}

			return name;
		}
Пример #7
0
			private static void ProcessRolePlayerDeleted(ObjectTypePlaysRole link, ObjectType rolePlayer, Role role)
			{
				if (role == null)
				{
					role = link.PlayedRole;
				}
				if (rolePlayer == null)
				{
					rolePlayer = link.RolePlayer;
				}
				FilterModifiedFactType(role.FactType, false);
				RoleProxy proxy = role.Proxy;
				if (proxy != null)
				{
					FilterModifiedFactType(proxy.FactType, false);
				}
				FilterModifiedObjectType(rolePlayer);
			}
Пример #8
0
		/// <summary>
		/// Creates a new <see cref="FactType"/> with the specified <paramref name="arity"/>.
		/// </summary>
		/// <param name="store">
		/// The <see cref="Store"/> in which the new <see cref="FactType"/> should be created.
		/// </param>
		/// <param name="group">
		/// The <see cref="ElementGroup"/> to which the new <see cref="FactType"/> and its <see cref="Role"/>s should
		/// be added.
		/// </param>
		/// <param name="arity">
		/// The number of <see cref="Role"/>s that the new <see cref="FactType"/> should contain.
		/// </param>
		/// <returns>
		/// The newly created <see cref="FactType"/>.
		/// </returns>
		/// <remarks>
		/// The new <see cref="FactType"/> is added to <paramref name="group"/> as a root element.
		/// </remarks>
		private static FactType AddFactType(Store store, ElementGroup group, int arity)
		{
			FactType factType = new FactType(store, null);
			group.AddGraph(factType, true);
			LinkedElementCollection<RoleBase> roles = factType.RoleCollection;
			for (int i = 0; i < arity; i++)
			{
				Role role = new Role(store);
				roles.Add(role);
				group.AddGraph(role);
			}
			return factType;
		}
Пример #9
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);
						}
					}
				}
			}
		}
Пример #10
0
		/// <summary>
		/// Recursively retrieve a sequence of roles that are
		/// allowed to have value constraints.
		/// </summary>
		/// <param name="currentRole">The current role to test</param>
		/// <param name="rolePlayer">The role player for the current role.</param>
		/// <param name="depth">The current depth. Pass in -1 to skip populating the output
		/// roles and 0 to seed recursion.</param>
		/// <param name="roles">An array of roles. The roles are in reverse order, so
		/// roles[0] will always have a ValueType as its RolePlayer.</param>
		/// <returns>true if the current role can have a value constraint</returns>
		private static bool GetValueRoles(Role currentRole, ObjectType rolePlayer, int depth, out Role[] roles)
		{
			roles = null;
			if (depth == 100 || depth == -101)
			{
				// Cycling
				return false;
			}
			if (rolePlayer != null)
			{
				if (rolePlayer.IsValueType)
				{
					if (depth < 0)
					{
						return true;
					}
					// This is the first element in the chain and
					// can be used to retrieve the value type.
					roles = new Role[depth + 1];
					roles[0] = currentRole;
				}
				else
				{
					UniquenessConstraint preferredIdentifier = rolePlayer.ResolvedPreferredIdentifier;
					LinkedElementCollection<Role> identifierRoles;
					Role nextRole;
					if (preferredIdentifier != null &&
						(identifierRoles = preferredIdentifier.RoleCollection).Count == 1 &&
						(nextRole = identifierRoles[0]).FactType != currentRole.FactType)
					{
						if (depth < 0)
						{
							return GetValueRoles(nextRole, nextRole.RolePlayer, depth - 1, out roles);
						}
						if (GetValueRoles(nextRole, nextRole.RolePlayer, depth + 1, out roles))
						{
							roles[roles.Length - depth - 1] = currentRole;
						}
					}
				}
			}
			return roles != null;
		}
Пример #11
0
			public void DisposeHelper()
			{
				myRole = null;
			}
Пример #12
0
			public void Initialize(Role role)
			{
				myRole = role;
			}
Пример #13
0
		/// <summary>
		/// Replaces <paramref name="existingRole"/> with <paramref name="replacementRole"/>, including altering all relationships
		/// in which <paramref name="existingRole"/> participates.
		/// </summary>
		public static void ReplaceRole(Role existingRole, Role replacementRole)
		{
			// Synchronize the names
			replacementRole.Name = existingRole.Name;

			// Alter the relationships that refer to existingRole to instead refer to replacementRole
			ReadOnlyCollection<ElementLink> elementLinks = DomainRoleInfo.GetAllElementLinks(existingRole);
			int elementLinksCount = elementLinks.Count;
			for (int i = 0; i < elementLinksCount; i++)
			{
				ElementLink elementLink = elementLinks[i];
				ReadOnlyCollection<DomainRoleInfo> domainRoles = elementLink.GetDomainRelationship().DomainRoles;
				DomainRoleInfo domainRoleInfo;
				if (DomainRoleInfo.GetSourceRolePlayer(elementLink) == existingRole)
				{
					Debug.Assert(DomainRoleInfo.GetTargetRolePlayer(elementLink) != existingRole, "We shouldn't have a relationship from ourselves to ourselves.");
					domainRoleInfo = domainRoles[0];
					Debug.Assert(domainRoleInfo.IsSource);
				}
				else
				{
					domainRoleInfo = domainRoles[1];
					Debug.Assert(!domainRoleInfo.IsSource);
				}
				DomainRoleInfo.SetRolePlayer(elementLink, domainRoleInfo.Id, replacementRole);
			}
		}
Пример #14
0
		/// <summary>
		/// Determines the index of a specific Role in the list, resolving
		/// RoleProxy elements as needed
		/// </summary>
		/// <param name="roleBaseCollection">The list in which to locate the role</param>
		/// <param name="value">The Role to locate in the list</param>
		/// <returns>index of object</returns>
		public static int IndexOf(LinkedElementCollection<RoleBase> roleBaseCollection, Role value)
		{
			int count = roleBaseCollection.Count;
			for (int i = 0; i < count; ++i)
			{
				if (roleBaseCollection[i].Role == value)
				{
					return i;
				}
			}
			return -1;
		}
Пример #15
0
					public ColumnPathStep(Role fromRole, ObjectType targetObjectType, ObjectType alternateObjectType, ColumnPathStepFlags flags)
					{
						myFromRole = fromRole;
						myObjectType = targetObjectType;
						myAlternateObjectType = alternateObjectType;
						myFlags = flags;
					}
Пример #16
0
		private static void GetMappingPatterns(Role towardsRole, Role fromRole, out MappingUniquenessPattern uniquenessPattern, out MappingMandatoryPattern mandatoryPattern)
		{
			if (towardsRole.FactType is SubtypeFact)
			{
				uniquenessPattern = MappingUniquenessPattern.Subtype;
				mandatoryPattern = (towardsRole is SubtypeMetaRole) ? MappingMandatoryPattern.TowardsRoleMandatory : MappingMandatoryPattern.OppositeRoleMandatory;
			}
			else
			{
				bool towardsRoleUnique;
				bool towardsRoleMandatory;
				bool towardsRoleImpliedMandatory;
				bool fromRoleUnique;
				bool fromRoleMandatory;
				bool fromRoleImpliedMandatory;
				bool oneToOne = false;
				GetUniqueAndMandatory(towardsRole, out towardsRoleUnique, out towardsRoleMandatory, out towardsRoleImpliedMandatory);
				GetUniqueAndMandatory(fromRole, out fromRoleUnique, out fromRoleMandatory, out fromRoleImpliedMandatory);
				uniquenessPattern = towardsRoleUnique ?
					((oneToOne = fromRoleUnique) ? MappingUniquenessPattern.OneToOne : MappingUniquenessPattern.OneToMany) :
					MappingUniquenessPattern.ManyToOne;
				if (oneToOne && (fromRoleImpliedMandatory ^ towardsRoleImpliedMandatory))
				{
					// Adjust mandatory patterns to ignore implied mandatory on naturally asymmetric
					// one-to-one relationships.
					if (fromRoleImpliedMandatory)
					{
						fromRoleMandatory = !towardsRoleMandatory;
					}
					else
					{
						towardsRoleMandatory = !fromRoleMandatory;
					}
				}
				mandatoryPattern = towardsRoleMandatory ?
					(fromRoleMandatory ? MappingMandatoryPattern.BothRolesMandatory : MappingMandatoryPattern.TowardsRoleMandatory) :
					(fromRoleMandatory ? MappingMandatoryPattern.OppositeRoleMandatory : MappingMandatoryPattern.NotMandatory);
			}
		}
Пример #17
0
		private static void GetUniqueAndMandatory(Role role, out bool hasUniqueness, out bool hasMandatory, out bool mandatoryIsImplied)
		{
			hasUniqueness = false;
			hasMandatory = false;
			mandatoryIsImplied = false;
			LinkedElementCollection<ConstraintRoleSequence> constraintRoleSequences = role.ConstraintRoleSequenceCollection;
			int roleSequenceCount = constraintRoleSequences.Count;
			for (int i = 0; i < roleSequenceCount; ++i)
			{
				ConstraintRoleSequence roleSequence = constraintRoleSequences[i];
				IConstraint constraint = roleSequence.Constraint;
				if (constraint != null && constraint.Modality == ConstraintModality.Alethic)
				{
					switch (constraint.ConstraintType)
					{
						case ConstraintType.SimpleMandatory:
							hasMandatory = true;
							if (hasUniqueness)
							{
								return;
							}
							break;
						case ConstraintType.InternalUniqueness:
							// Ignore spanning internal constraints, these are treated as external
							// uniquenesses in the binarized form
							if (roleSequence.RoleCollection.Count == 1)
							{
								hasUniqueness = true;
								if (hasMandatory)
								{
									return;
								}
							}
							break;
						case ConstraintType.ImpliedMandatory:
							if (roleSequence.RoleCollection.Count == 1)
							{
								hasMandatory = true;
								mandatoryIsImplied = true;
								if (hasUniqueness)
								{
									return;
								}
							}
							break;
					}
				}
			}
		}
Пример #18
0
		/// <summary>
		/// Helper method to recursively walk value roles. A value role
		/// is any role that is allowed to have a value constraint.
		/// </summary>
		/// <param name="playedRoles">Roles from an ObjectType to walk. The assumption is made that the
		/// owning ObjectType is either a value type or has a preferred identifier with exactly one role</param>
		/// <param name="dataTypeLink">The data type information for the constraint</param>
		/// <param name="pathRoots">The <see cref="RolePathObjectTypeRoot"/> relationships from a role path associated
		/// with the root path.</param>
		/// <param name="previousValueConstraint">The value constraint nearest this value role.
		/// Any value constraint on the current set of roles must be a subset of the previousValueConstraint.</param>
		/// <param name="skipRole">A role to skip. If the playedRoles came from a preferred identifier,
		/// then the skipRole is the opposite role.</param>
		/// <param name="walkSubtypes">true to walk subtypes. Should be true if the playedRoles come from an
		/// EntityType and false if they come from a ValueType</param>
		/// <param name="visitor">The callback delegate</param>
		/// <returns>true to continue iteration</returns>
		private static bool WalkDescendedValueRoles(IList<Role> playedRoles, IList<RolePathObjectTypeRoot> pathRoots, ValueTypeHasDataType dataTypeLink, ValueConstraint previousValueConstraint, Role skipRole, bool walkSubtypes, ValueRoleVisitor visitor)
		{
			int count = pathRoots.Count;
			for (int i = 0; i < count; ++i)
			{
				RolePathObjectTypeRoot pathRoot = pathRoots[i];
				if (!visitor(null, null, pathRoot, dataTypeLink, pathRoot.ValueConstraint, previousValueConstraint))
				{
					return false;
				}
			}
			count = playedRoles.Count;
			for (int i = 0; i < count; ++i)
			{
				Role role = playedRoles[i];
				SupertypeMetaRole supertypeRole;
				if (role == skipRole)
				{
					// Nothing to do
				}
				else if (null != (supertypeRole = role as SupertypeMetaRole))
				{
					if (walkSubtypes)
					{
						SubtypeFact subtypeFact = (SubtypeFact)role.FactType;
						ObjectType subtype;
						if (subtypeFact.ProvidesPreferredIdentifier &&
							null != (subtype = subtypeFact.Subtype) &&
							subtype.PreferredIdentifier == null)
						{
							if (!WalkDescendedValueRoles(subtype.PlayedRoleCollection, RolePathObjectTypeRoot.GetLinksToRolePathCollection(subtype), dataTypeLink, previousValueConstraint, null, true, visitor))
							{
								return false;
							}
						}
					}
				}
				else if (!(role is SubtypeMetaRole))
				{
					RoleValueConstraint currentValueConstraint = role.ValueConstraint;
					if (!visitor(role, null, null, dataTypeLink, currentValueConstraint, previousValueConstraint))
					{
						return false;
					}
					if (currentValueConstraint != null && !currentValueConstraint.IsDeleted)
					{
						previousValueConstraint = currentValueConstraint;
					}
					foreach (PathedRole pathedRole in PathedRole.GetLinksToRolePathCollection(role))
					{
						// UNDONE: VALUEROLE This does not correctly report a value constraint from a previous
						// path node. Note that this, as well as allowing value restrictions on supertype roles
						// (and possibly other patterns), can result in multiple previous value constraints, so
						// the callback signature may possibly need to be modified here. As of changeset 1442,
						// none of the callbacks use the previousValueConstraint information, so we can ignore
						// this for now.

						// Note that we visit for the pathed role even if no value constraint is present
						// to allow processing for this pathed role.
						if (!visitor(role, pathedRole, null, dataTypeLink, pathedRole.ValueConstraint, previousValueConstraint))
						{
							return false;
						}
					}

					// Walk sequences to find a single-role preferred identifier so
					// we can get to the next link.
					LinkedElementCollection<ConstraintRoleSequence> sequences = role.ConstraintRoleSequenceCollection;
					int sequencesCount = sequences.Count;
					for (int j = 0; j < sequencesCount; ++j)
					{
						UniquenessConstraint constraint = sequences[j] as UniquenessConstraint;
						ObjectType identifierFor;
						if (null != (constraint = sequences[j] as UniquenessConstraint) &&
							null != (identifierFor = constraint.PreferredIdentifierFor) &&
							constraint.RoleCollection.Count == 1)
						{
							RoleBase nextSkipRole = role.OppositeRoleAlwaysResolveProxy;
							if (nextSkipRole == null)
							{
								return false;
							}
							if (!WalkDescendedValueRoles(identifierFor.PlayedRoleCollection, RolePathObjectTypeRoot.GetLinksToRolePathCollection(identifierFor), dataTypeLink, previousValueConstraint, nextSkipRole.Role, true, visitor))
							{
								return false;
							}
						}
					}
				}
			}
			return true;
		}
        /// <summary>
        /// for regular relationships
        /// </summary>
        /// <param name="relation"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="notifyAdded"></param>
        /// <param name="associationCounter"></param>
        /// <returns></returns>
        private static bool CreateBinaryAssociation(ConceptTypeChild relation, ConceptType source, ConceptType target, INotifyElementAdded notifyAdded, ref int associationCounter)
        {
            if (BinaryAssociationHasConceptTypeChild.GetBinaryAssociation(relation).Count > 0)
            {
                //it has already been created
                return(true);
            }
            else if (EntityTypeIsPrimarilyForConceptType.GetEntityType(target) != null)
            {
                #region create association
                BinaryAssociation b = new BinaryAssociation(relation.Store,
                                                            new PropertyAssignment[] { new PropertyAssignment(BinaryAssociation.NumberDomainPropertyId, associationCounter++) });
                //new BinaryAssociationHasConceptTypeChild(b, relation);
                BinaryAssociationHasConceptTypeChild.GetConceptTypeChildPath(b).Add(relation);

                Role r1 = new Role(relation.Store,
                                   new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, source.Name) });

                Role r2 = new Role(relation.Store,
                                   new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, target.Name) });

                b.RoleCollection.Add(r1);
                b.RoleCollection.Add(r2);

                EntityType sourceEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(source);
                EntityType targetEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(target);
                sourceEntity.RoleCollection.Add(r1);
                targetEntity.RoleCollection.Add(r2);
                sourceEntity.BarkerErModel.BinaryAssociationCollection.Add(b);
                #endregion

                //determine whether roles are mandatory or optional
                List <ConceptTypeChild> links = new List <ConceptTypeChild>(1);
                links.Add(relation);
                r1.IsMandatory = AllStepsMandatory(targetEntity, links);
                if (relation is ConceptTypeAssimilatesConceptType)
                {
                    r2.IsMandatory = AllStepsMandatory(sourceEntity, links);
                }

                #region determine whether roles are multivalued or not - and possibly rename
                ORMCore.ObjectType           sourceObjectType = ConceptTypeIsForObjectType.GetObjectType(source);
                ORMCore.ObjectType           targetObjectType = ConceptTypeIsForObjectType.GetObjectType(target);
                ORMCore.UniquenessConstraint uSource = null, uTarget = null;
                foreach (ORMCore.FactType factType in ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(relation))
                {
                    Debug.Assert(factType.RoleCollection.Count == 2, "Error when mapping to Barker ER; the fact type is not binary");
                    foreach (ORMCore.RoleBase r in factType.RoleCollection)
                    {
                        //need to use RoleBase because we might run into RoleProxy
                        ORMCore.Role role = r.Role;
                        foreach (ORMCore.ConstraintRoleSequence constraintRoleSequence in role.ConstraintRoleSequenceCollection)
                        {
                            ORMCore.UniquenessConstraint uninquenessConstraint = constraintRoleSequence as ORMCore.UniquenessConstraint;
                            if (uninquenessConstraint != null &&                                        //check that it's a uniqueness constraint
                                uninquenessConstraint.Modality == ORMCore.ConstraintModality.Alethic && //check it's alethic
                                uninquenessConstraint.IsInternal)                                       //check it's internal
                            {
                                if (role.RolePlayer == sourceObjectType)
                                {
                                    uSource = uninquenessConstraint;
                                }
                                if (role.RolePlayer == targetObjectType)
                                {
                                    uTarget = uninquenessConstraint;
                                }
                            }
                        }
                    }
                    //name the roles properly
                    //TODO this is a hack; proper name generation is yet to be implemented
                    foreach (ORMCore.ReadingOrder order in factType.ReadingOrderCollection)
                    {
                        string text  = order.ReadingText;
                        int    first = text.IndexOf('}') + 1;
                        text = text.Substring(first, text.LastIndexOf('{') - first);
                        text = text.Trim();

                        if (!string.IsNullOrEmpty(text) &&
                            order.RoleCollection != null && order.RoleCollection.Count > 0 &&
                            order.RoleCollection[0].Role != null)
                        {
                            ORMCore.ObjectType o = order.RoleCollection[0].Role.RolePlayer;
                            if (o == sourceObjectType)
                            {
                                r1.PredicateText = text;
                            }
                            else if (o == targetObjectType)
                            {
                                r2.PredicateText = text;
                            }
                        }
                    }
                }
                if (uSource != null && uSource == uTarget)
                {
                    //it's many-to-many
                    r1.IsMultiValued = true;
                    r2.IsMultiValued = true;
                }
                else if (uSource == null || uTarget == null)
                {
                    //it's one-to-many
                    r1.IsMultiValued = uSource != null;
                    r2.IsMultiValued = uTarget != null;
                }
                else if (uSource != null && uTarget != null)
                {
                    //it's one-to-one
                    r1.IsMultiValued = false;
                    r2.IsMultiValued = false;
                }
                else
                {
                    Debug.Fail("Found a fact type with no uniqueness constraints!");
                }
                #endregion

                #region primary id?
                foreach (Uniqueness u in UniquenessIncludesConceptTypeChild.GetUniquenessCollection(relation))
                {
                    if (u.IsPreferred)
                    {
                        r1.IsPrimaryIdComponent = true;
                        break;
                    }
                }
                #endregion

                //notify elements added
                if (notifyAdded != null)
                {
                    notifyAdded.ElementAdded(b, true);
                    notifyAdded.ElementAdded(r1, true);
                    notifyAdded.ElementAdded(r2, true);
                }

                return(true);
            }
            else
            {
                //should not create binary association in this case
                return(false);
            }
        }
Пример #20
0
		/// <summary>
		///  Helper function to update the mandatory dot in response to events
		/// </summary>
		private static void UpdateDotDisplayOnMandatoryConstraintChange(Role role)
		{
			InvalidateRolePlayerLinks(role);
			if (OptionsPage.CurrentEntityRelationshipBinaryMultiplicityDisplay == EntityRelationshipBinaryMultiplicityDisplay.InformationEngineering)
			{
				// The opposite links also need updating
				RoleBase oppositeRole = role.OppositeRole;
				if (oppositeRole != null)
				{
					InvalidateRolePlayerLinks(oppositeRole.Role);
				}
			}
		}
Пример #21
0
		private static void NotifyRoleChanged(INotifySurveyElementChanged eventNotify, Role role)
		{
			foreach (ConstraintRoleSequence sequence in role.ConstraintRoleSequenceCollection)
			{
				UniquenessConstraint uniquenessConstraint;
				EntityTypeHasPreferredIdentifier identifierLink;
				if (null != (uniquenessConstraint = sequence as UniquenessConstraint) &&
					null != (identifierLink = EntityTypeHasPreferredIdentifier.GetLinkToPreferredIdentifierFor(uniquenessConstraint)))
				{
					NotifyErrorStateChanged(eventNotify, identifierLink);
				}
			}
			eventNotify.ElementChanged(role, SurveyGlyphQuestionTypes);
			eventNotify.ElementRenamed(role);
		}
Пример #22
0
		/// <summary>
		/// Helper function to invalidate roles
		/// </summary>
		private static void InvalidateRolePlayerLinks(Role role)
		{
			foreach (ObjectTypePlaysRole objectTypePlaysRole in DomainRoleInfo.GetElementLinks<ObjectTypePlaysRole>(role, ObjectTypePlaysRole.PlayedRoleDomainRoleId))
			{
				foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(objectTypePlaysRole))
				{
					ShapeElement shape = pel as ShapeElement;
					if (shape != null)
					{
						shape.Invalidate(true);
					}
				}
			}
		}
Пример #23
0
			/// <summary>
			/// Binarizes the unary <see cref="FactType"/> specified by <paramref name="unaryFactType"/>, defaulting
			/// to using open-world assumption. The caller is responsible for making sure <paramref name="unaryFactType"/>
			/// is in fact a unary fact type.
			/// </summary>
			public static void BinarizeUnary(FactType unaryFactType, INotifyElementAdded notifyAdded)
			{
				Store store = unaryFactType.Store;
				LinkedElementCollection<RoleBase> roleCollection = unaryFactType.RoleCollection;
				Debug.Assert(roleCollection.Count == 1, "Unaries should only have one role.");

				Role unaryRole = (Role)roleCollection[0];
				string implicitBooleanValueTypeName = GetImplicitBooleanValueTypeName(unaryRole);

				// UNDONE: We are using open-world assumption now
				// Setup the mandatory constraint (for closed-world assumption)
				//MandatoryConstraint mandatoryConstraint = MandatoryConstraint.CreateSimpleMandatoryConstraint(unaryRole);
				//mandatoryConstraint.Model = unaryFactType.Model;
				//if (notifyAdded != null)
				//{
				//    notifyAdded.ElementAdded(mandatoryConstraint, true);
				//}

				// Setup the uniqueness constraint (to make the newly binarized FactType valid)
				if (unaryRole.SingleRoleAlethicUniquenessConstraint == null)
				{
					UniquenessConstraint uniquenessConstraint = UniquenessConstraint.CreateInternalUniquenessConstraint(unaryFactType);
					uniquenessConstraint.RoleCollection.Add(unaryRole);
					uniquenessConstraint.Model = unaryFactType.Model;
					if (notifyAdded != null)
					{
						notifyAdded.ElementAdded(uniquenessConstraint, true);
					}
				}

				// Setup the boolean role (to make the FactType a binary)
				Role implicitBooleanRole = new Role(store, null);
				implicitBooleanRole.Name = unaryRole.Name;

				// Setup the boolean value type (because the boolean role needs a role player)
				ObjectType implicitBooleanValueType = new ObjectType(store, new PropertyAssignment(ObjectType.IsImplicitBooleanValueDomainPropertyId, true));
				Dictionary<object, object> contextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo;
				try
				{
					contextInfo[ORMModel.AllowDuplicateNamesKey] = null;
					implicitBooleanValueType.Name = implicitBooleanValueTypeName;
					implicitBooleanValueType.Model = unaryFactType.Model;
					if (notifyAdded != null)
					{
						notifyAdded.ElementAdded(implicitBooleanValueType, true);
					}
				}
				finally
				{
					contextInfo.Remove(ORMModel.AllowDuplicateNamesKey);
				}
				implicitBooleanValueType.DataType = store.ElementDirectory.FindElements<TrueOrFalseLogicalDataType>(false)[0];

				// Set value constraint on implicit boolean ValueType for open-world assumption
				ValueTypeValueConstraint implicitBooleanValueConstraint = implicitBooleanValueType.ValueConstraint
					= new ValueTypeValueConstraint(implicitBooleanValueType.Store, null);

				// Add the true-only ValueRange to the value constraint for open-world assumption
				implicitBooleanValueConstraint.ValueRangeCollection.Add(new ValueRange(store,
					new PropertyAssignment(ValueRange.MinValueDomainPropertyId, bool.TrueString),
					new PropertyAssignment(ValueRange.MaxValueDomainPropertyId, bool.TrueString)));

				// Make the boolean value type the role player for the implicit boolean role
				implicitBooleanRole.RolePlayer = implicitBooleanValueType;

				// Add the boolean role to the FactType
				roleCollection.Add(implicitBooleanRole);
				if (notifyAdded != null)
				{
					notifyAdded.ElementAdded(implicitBooleanRole, true);
				}
			}
			/// <summary>
			/// Create a connection between an ExternalConstraintShape and a FactType. Roles
			/// used in the connection are stored with the currently active connect action.
			/// </summary>
			/// <param name="sourceShapeElement">The source of the requested connection</param>
			/// <param name="targetShapeElement">The target of the requested connection</param>
			/// <param name="paintFeedbackArgs">PaintFeedbackArgs</param>
			public override void CreateConnection(ShapeElement sourceShapeElement, ShapeElement targetShapeElement, PaintFeedbackArgs paintFeedbackArgs)
			{
				ExternalConstraintShape constraintShape;
				IConstraint constraint;
				ExternalConstraintConnectAction action;
				IList<Role> selectedRoles;
				int rolesCount;
				if ((null != (constraintShape = sourceShapeElement as ExternalConstraintShape)) &&
					(null != (constraint = constraintShape.AssociatedConstraint)) &&
					(null != (action = (sourceShapeElement.Diagram as ORMDiagram).ExternalConstraintConnectAction)) &&
					(null != (selectedRoles = action.SelectedRoleCollection)) &&
					(0 != (rolesCount = selectedRoles.Count)))
				{
					SetComparisonConstraint mcConstraint;
					SetConstraint scConstraint;
					ConstraintRoleSequence modifyRoleSequence = null;
					if (null != (mcConstraint = constraint as SetComparisonConstraint))
					{
						ConstraintRoleSequence constraintRoleSequenceBeingEdited = action.ConstraintRoleSequenceToEdit;
						// Add a new role set
						if (null == constraintRoleSequenceBeingEdited)
						{
							LinkedElementCollection<SetComparisonConstraintRoleSequence> roleSequences = mcConstraint.RoleSequenceCollection;
							if (action.mySubtypeConnection)
							{
								// All editing is done as a single column, add role sequences to the constraint
								// instead of roles to the sequence
								Store store = mcConstraint.Store;
								for (int i = 0; i < rolesCount; ++i)
								{
									SetComparisonConstraintRoleSequence roleSequence = new SetComparisonConstraintRoleSequence(store);
									roleSequence.RoleCollection.Add(selectedRoles[i]);
									roleSequences.Add(roleSequence);
								}
							}
							else
							{
								SetComparisonConstraintRoleSequence roleSequence = new SetComparisonConstraintRoleSequence(mcConstraint.Store);
								LinkedElementCollection<Role> roles = roleSequence.RoleCollection;
								for (int i = 0; i < rolesCount; ++i)
								{
									roles.Add(selectedRoles[i]);
								}
								roleSequences.Add(roleSequence);
							}
						}
						else if (action.mySubtypeConnection)
						{
							LinkedElementCollection<SetComparisonConstraintRoleSequence> existingSequences = mcConstraint.RoleSequenceCollection;
							int existingSequenceCount = existingSequences.Count;
							// Pull out removed ones first
							for (int i = existingSequenceCount - 1; i >= 0; --i)
							{
								SetComparisonConstraintRoleSequence existingSequence = existingSequences[i];
								LinkedElementCollection<Role> sequenceRoles = existingSequence.RoleCollection;
								if (sequenceRoles.Count != 1 || !selectedRoles.Contains(sequenceRoles[0]))
								{
									existingSequences.Remove(existingSequence);
									--existingSequenceCount;
								}
							}
							Store store = mcConstraint.Store;
							for (int i = 0; i < rolesCount; ++i)
							{
								Role selectedRole = selectedRoles[i];
								int existingIndex = -1;
								for (int j = 0; j < existingSequenceCount; ++j)
								{
									if (existingSequences[j].RoleCollection[0] == selectedRole)
									{
										existingIndex = j;
										break;
									}
								}
								if (existingIndex == -1)
								{
									SetComparisonConstraintRoleSequence roleSequence = new SetComparisonConstraintRoleSequence(store);
									roleSequence.RoleCollection.Add(selectedRoles[i]);
									if (i < existingSequenceCount)
									{
										existingSequences.Insert(i, roleSequence);
									}
									else
									{
										existingSequences.Add(roleSequence);
									}
									++existingSequenceCount;
								}
								else if (existingIndex != i)
								{
									existingSequences.Move(existingIndex, i);
								}
							}
						}
						// Edit the existing role set.
						else
						{
							modifyRoleSequence = constraintRoleSequenceBeingEdited;
						}
					}
					else if (null != (scConstraint = constraint as SetConstraint))
					{
						// The single-column constraint is its own role set, just add the roles.
						modifyRoleSequence = scConstraint;
						switch (constraint.ConstraintType)
						{
							case ConstraintType.ExternalUniqueness:
							case ConstraintType.Frequency:
								// Translate selected unary roles back to the implied role
								bool duplicatedSelectedRoles = false;
								for (int i = 0; i < rolesCount; ++i)
								{
									Role testRole = selectedRoles[i];
									Role oppositeRole;
									ObjectType oppositeRolePlayer;
									if (null != (oppositeRole = testRole.OppositeRole as Role) &&
										null != (oppositeRolePlayer = oppositeRole.RolePlayer) &&
										oppositeRolePlayer.IsImplicitBooleanValue)
									{
										if (!duplicatedSelectedRoles)
										{
											duplicatedSelectedRoles = true;
											Role[] dupRoles = new Role[rolesCount];
											selectedRoles.CopyTo(dupRoles, 0);
											selectedRoles = dupRoles;
										}
										selectedRoles[i] = oppositeRole;
									}
								}
								break;
						}
					}
					if (modifyRoleSequence != null)
					{
						// Note that we don't just blow away the collection here, there are too
						// many side effects (such as removing the preferred identifier when a compatible
						// link is added)
						LinkedElementCollection<Role> roles = modifyRoleSequence.RoleCollection;
						int existingRolesCount = roles.Count;
						for (int i = existingRolesCount - 1; i >= 0; --i)
						{
							Role testRole = roles[i];
							if (!selectedRoles.Contains(testRole))
							{
								roles.Remove(testRole);
								--existingRolesCount;
							}
						}
						for (int i = 0; i < rolesCount; ++i)
						{
							Role selectedRole = selectedRoles[i];
							int existingIndex = roles.IndexOf(selectedRole);
							if (existingIndex == -1)
							{
								if (i < existingRolesCount)
								{
									roles.Insert(i, selectedRole);
								}
								else if (!roles.Contains(selectedRole))
								{
									roles.Add(selectedRole);
								}
								++existingRolesCount;
							}
							else if (existingIndex != i)
							{
								roles.Move(existingIndex, i);
							}
						}
					}
				}
			}
		private static void RedrawOwningFactType(Role role)
		{
			FactType factType = role.FactType;
			if (factType != null)
			{
				LinkedElementCollection<PresentationElement> pels = PresentationViewsSubject.GetPresentation(factType);
				int pelsCount = pels.Count;
				for (int i = 0; i < pelsCount; ++i)
				{
					ShapeElement shape = pels[i] as ShapeElement;
					if (shape != null)
					{
						shape.Invalidate(true);
					}
				}
			}
		}
Пример #26
0
		/// <summary>
		/// Removes the RoleNameShape from the associated Role
		/// </summary>
		public static void RemoveRoleNameShapeFromRole(Role role)
		{
			LinkedElementCollection<PresentationElement> pels = PresentationViewsSubject.GetPresentation(role);
			int pelCount = pels.Count;
			for (int i = pelCount - 1; i >= 0; --i)
			{
				RoleNameShape pel = pels[i] as RoleNameShape;
				if (pel != null)
				{
					pel.Delete();
				}
			}
		}