/// <summary> /// Serializes this <see cref="T:ORMSolutions.ORMArchitect.Views.RelationalView.RelationalDiagram"/>. /// </summary> /// <param name="writer">A <see cref="T:System.Xml.XmlWriter"/> that will write the custom serialization contents.</param> void IXmlSerializable.WriteXml(XmlWriter writer) { string rvNamespace = RelationalShapeDomainModel.XmlNamespace; // <RelationalDiagram> // <TableShape ObjectTypeRef="" Location="x, y" /> // ... // </RelationalDiagram> ISerializationContext serializationContext = ((ISerializationContextHost)Store).SerializationContext; writer.WriteStartElement(RelationalDiagramElementName, rvNamespace); writer.WriteAttributeString(IdAttributeName, serializationContext.GetIdentifierString(Id)); writer.WriteAttributeString(DisplayDataTypesAttributeName, XmlConvert.ToString(DisplayDataTypes)); writer.WriteAttributeString(SubjectRefAttributeName, serializationContext.GetIdentifierString(this.ModelElement.Id)); TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(PointD)); foreach (ShapeElement shapeElement in this.NestedChildShapes) { TableShape tableShape = shapeElement as TableShape; if (tableShape != null) { ConceptType conceptType; ObjectType objectType; if (null != (conceptType = TableIsPrimarilyForConceptType.GetConceptType((Table)tableShape.ModelElement)) && null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType))) { writer.WriteStartElement(TableShapeElementName, rvNamespace); writer.WriteAttributeString(ObjectTypeRefAttributeName, serializationContext.GetIdentifierString(objectType.Id)); writer.WriteAttributeString(LocationAttributeName, typeConverter.ConvertToInvariantString(tableShape.Location)); writer.WriteEndElement(); } } } writer.WriteEndElement(); }
private static void ValidateReferenceModeNamingChanged(ReferenceModeNamingCustomizesObjectType referenceModeNamingCustomizesObjectType) { if (null != referenceModeNamingCustomizesObjectType) { ORMCore.ObjectType objectType = referenceModeNamingCustomizesObjectType.ObjectType; if (objectType != null) { ConceptType conceptType = ConceptTypeIsForObjectType.GetConceptType(objectType); if (null == conceptType) { foreach (ORMCore.Role role in objectType.PlayedRoleCollection) { foreach (ConceptTypeChild conceptTypeChild in ConceptTypeChildHasPathFactType.GetConceptTypeChild(role.FactType)) { ValidateConceptTypeChildNameChanged(conceptTypeChild); } } } else { ValidateConceptTypeNameChanged(conceptType); } } } }
/// <summary> /// Customize childshape create to set an initial location for a <see cref="TableShape"/> /// </summary> protected override ShapeElement CreateChildShape(ModelElement element) { object tablePositionsObject; Dictionary <Guid, PointD> tablePositions; PointD initialLocation; ReferenceConstraintTargetsTable referenceConstraintTargetsTable; Table table; ConceptType conceptType; ObjectType objectType; if (null != (table = element as Table)) { if (element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo.TryGetValue(TablePositionDictionaryKey, out tablePositionsObject) && null != (tablePositions = tablePositionsObject as Dictionary <Guid, PointD>) && null != (conceptType = TableIsPrimarilyForConceptType.GetConceptType(table)) && null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)) && tablePositions.TryGetValue(objectType.Id, out initialLocation)) { return(new TableShape( this.Partition, new PropertyAssignment(TableShape.AbsoluteBoundsDomainPropertyId, new RectangleD(initialLocation, new SizeD(1, 0.3))))); } } else if (null != (referenceConstraintTargetsTable = element as ReferenceConstraintTargetsTable)) { return(new ForeignKeyConnector(Partition)); } return(base.CreateChildShape(element)); }
/// <summary> /// Customize childshape create to set an initial location for a <see cref="BarkerEntityShape"/> /// </summary> protected override ShapeElement CreateChildShape(ModelElement element) { object barkerEntityPositionsObject; Dictionary <Guid, PointD> barkerEntityPositions; PointD initialLocation; BarkerErModelContainsBinaryAssociation modelContainsAssociation; EntityType barkerEntity; ConceptType conceptType; ObjectType objectType; if (null != (barkerEntity = element as EntityType)) { if (element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo.TryGetValue(BarkerEntityPositionDictionaryKey, out barkerEntityPositionsObject) && null != (barkerEntityPositions = barkerEntityPositionsObject as Dictionary <Guid, PointD>) && null != (conceptType = EntityTypeIsPrimarilyForConceptType.GetConceptType(barkerEntity)) && null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)) && barkerEntityPositions.TryGetValue(objectType.Id, out initialLocation)) { return(new BarkerEntityShape( this.Partition, new PropertyAssignment(BarkerEntityShape.AbsoluteBoundsDomainPropertyId, new RectangleD(initialLocation, new SizeD(1, 0.3))))); } } else if (null != (modelContainsAssociation = element as BarkerErModelContainsBinaryAssociation)) { return(new AssociationConnector(Partition)); } return(base.CreateChildShape(element)); }
private static void UpdateNamesForObjectTypeDelayed(ModelElement element) { if (!element.IsDeleted) { ObjectType objectType = (ObjectType)element; string objectTypeName = objectType.Name; ConceptType conceptType = ConceptTypeIsForObjectType.GetConceptType(objectType); LinkedElementCollection <FactType> pathFactTypes; int factTypeCount; RoleBase towardsRole; RoleBase oppositeRole; if (null != conceptType) { // Precheck name to minimize downstream calls, the property change // will check itself. if (conceptType.Name != objectTypeName) { conceptType.Name = objectTypeName; foreach (ConceptTypeReferencesConceptType reference in ConceptTypeReferencesConceptType.GetLinksToReferencingConceptTypeCollection(conceptType)) { pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(reference); if (0 != (factTypeCount = pathFactTypes.Count) && null != (towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(pathFactTypes[factTypeCount - 1])) && null != (oppositeRole = towardsRole.OppositeRole)) { reference.OppositeName = ResolveRoleName(oppositeRole); } } foreach (ConceptTypeReferencesConceptType reference in ConceptTypeReferencesConceptType.GetLinksToReferencedConceptTypeCollection(conceptType)) { pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(reference); if (0 != (factTypeCount = pathFactTypes.Count) && null != (towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(pathFactTypes[factTypeCount - 1]))) { reference.Name = ResolveRoleName(towardsRole); } } } } InformationTypeFormat informationTypeFormat = InformationTypeFormatIsForValueType.GetInformationTypeFormat(objectType); if (null != informationTypeFormat) { if (informationTypeFormat.Name != objectTypeName) { informationTypeFormat.Name = objectTypeName; foreach (InformationType informationType in InformationType.GetLinksToConceptTypeCollection(informationTypeFormat)) { pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(informationType); if (0 != (factTypeCount = pathFactTypes.Count) && null != (towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(pathFactTypes[factTypeCount - 1])) && null != (oppositeRole = towardsRole.OppositeRole)) { informationType.Name = ResolveRoleName(oppositeRole); } } } } } }
/// <summary> /// Make sure we have our tracker attached to all loaded models. /// </summary> /// <param name="element">An ORMModel element</param> /// <param name="store">The context store</param> /// <param name="notifyAdded">The listener to notify if elements are added during fixup</param> protected sealed override void ProcessElement(ORMModel element, Store store, INotifyElementAdded notifyAdded) { AbstractionModel oil = AbstractionModelIsForORMModel.GetAbstractionModel(element); if (oil == null) { // UNDONE: DelayValidateModel currently deletes and recreates any existing // bridge relationship, so there is no point deleting it up front, we'll // just retrieve it later. Also note that DelayValidateModel does not call notifyAdded. DelayValidateModel(element); oil = AbstractionModelIsForORMModel.GetAbstractionModel(element); if (oil != null) { notifyAdded.ElementAdded(oil, true); } } else { AbstractionModelGenerationSetting generationSetting; bool regenerateForVersion = null == (generationSetting = GenerationSettingTargetsAbstractionModel.GetGenerationSetting(oil)) || generationSetting.AlgorithmVersion != CurrentAlgorithmVersion; bool excludedBridgedElement = false; ORMElementGateway.Initialize( element, regenerateForVersion ? (ORMElementGateway.NotifyORMElementExcluded) null : delegate(ORMModelElement modelElement) { if (excludedBridgedElement) { return; } ObjectType objectType; FactType factType; // Note that the types we're checking here are synchronized with the ORMElementGateway.ExclusionAdded method if (null != (objectType = modelElement as ObjectType)) { if (null != ConceptTypeIsForObjectType.GetLinkToConceptType(objectType) || null != InformationTypeFormatIsForValueType.GetLinkToInformationTypeFormat(objectType)) { excludedBridgedElement = true; } } else if (null != (factType = modelElement as FactType)) { if (null != FactTypeMapsTowardsRole.GetLinkToTowardsRole(factType) || ConceptTypeChildHasPathFactType.GetLinksToConceptTypeChild(factType).Count != 0) { excludedBridgedElement = true; } } }); if (regenerateForVersion || excludedBridgedElement) { // Something is very wrong, regenerate (does not regenerate the excluded elements we already have) DelayValidateModel(element); } } }
/// <summary> /// DeletingRule: typeof(ORMSolutions.ORMArchitect.ORMAbstractionToBarkerERBridge.EntityTypeIsPrimarilyForConceptType) /// Cache the position of the <see cref="BarkerEntityShape"/> corresponding to the object type being deleted /// </summary> private static void ConceptTypeDetachingFromEntityTypeRule(ElementDeletingEventArgs e) { EntityTypeIsPrimarilyForConceptType link = (EntityTypeIsPrimarilyForConceptType)e.ModelElement; ObjectType objectType; if (null != (objectType = ConceptTypeIsForObjectType.GetObjectType(link.ConceptType)) && !objectType.IsDeleting) { RememberBarkerEntityShapeLocations(objectType, link.EntityType); } }
/// <summary> /// DeletingRule: typeof(ORMSolutions.ORMArchitect.ORMToORMAbstractionBridge.ConceptTypeIsForObjectType) /// Cache the position of the <see cref="BarkerEntityShape"/> corresponding to the object type being deleted /// </summary> private static void ConceptTypeDetachingFromObjectTypeRule(ElementDeletingEventArgs e) { ConceptTypeIsForObjectType link = (ConceptTypeIsForObjectType)e.ModelElement; ObjectType objectType = link.ObjectType; EntityType barkerEntity; if (!objectType.IsDeleting && null != (barkerEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(link.ConceptType))) { RememberBarkerEntityShapeLocations(objectType, barkerEntity); } }
/// <summary> /// DeletingRule: typeof(ORMSolutions.ORMArchitect.ORMToORMAbstractionBridge.ConceptTypeIsForObjectType) /// Cache the position of the <see cref="TableShape"/> corresponding to the object type being deleted /// </summary> private static void ConceptTypeDetachingFromObjectTypeRule(ElementDeletingEventArgs e) { ConceptTypeIsForObjectType link = (ConceptTypeIsForObjectType)e.ModelElement; ObjectType objectType = link.ObjectType; Table table; if (!objectType.IsDeleting && null != (table = TableIsPrimarilyForConceptType.GetTable(link.ConceptType))) { RememberTableShapeLocations(objectType, table); } }
private bool GetTableKey(Table table, out Guid key) { ConceptType conceptType; ObjectType objectType; if (null != (conceptType = TableIsPrimarilyForConceptType.GetConceptType(table)) && null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType))) { key = objectType.Id; return(true); } key = Guid.Empty; return(false); }
/// <summary> /// Implements <see cref="IVerbalize.GetVerbalization"/> /// </summary> protected bool GetVerbalization(TextWriter writer, IDictionary <Type, IVerbalizationSets> snippetsDictionary, IVerbalizationContext verbalizationContext, VerbalizationSign sign) { // We are redirected to this point by the associated Table element ConceptType conceptType = this.ConceptType; ObjectType objectType; if (null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType))) { verbalizationContext.DeferVerbalization(objectType, DeferVerbalizationOptions.None, null); foreach (ConceptType alsoForConceptType in TableIsAlsoForConceptType.GetConceptType(this.Table)) { if (null != (objectType = ConceptTypeIsForObjectType.GetObjectType(alsoForConceptType))) { writer.WriteLine(); verbalizationContext.DeferVerbalization(objectType, DeferVerbalizationOptions.None, null); } } } return(false); }
/// <summary> /// Get a minimal unique identifier for a column based on mapped roles. The identifer /// will stop as soon as the fact type is used in a single column or in a partitioned /// or separated column. /// </summary> /// <param name="column">The <see cref="Column"/> to analyze</param> /// <param name="idList">Scratch list used to determine keys</param> /// <param name="minKeySize">The minimum number of ids that uniquely /// identify this column. The actually key may be longer than this /// minimimum for partitioned and separated tables. Key comparisons /// may be performed down to this minimum size.</param> /// <returns><see langword="true"/> if the key was available.</returns> private static bool BuildKey(Column column, List <Guid> idList, out int minKeySize) { idList.Clear(); int uniqueUseIndex = -1; minKeySize = 0; LinkedElementCollection <ConceptTypeChild> childNodes = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column); for (int i = childNodes.Count - 1; i >= 0; --i) { ConceptTypeChild child = childNodes[i]; bool uniqueChild = ColumnHasConceptTypeChild.GetLinksToColumn(child).Count == 1; LinkedElementCollection <FactType> pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(child); int factTypeCount = pathFactTypes.Count; InformationType infoType; ObjectType objectType; if (0 != (factTypeCount = pathFactTypes.Count)) { for (int j = factTypeCount - 1; j >= 0; --j) { FactType factType = pathFactTypes[j]; idList.Add(FactTypeMapsTowardsRole.GetTowardsRole(factType).Id); if (-1 == uniqueUseIndex && uniqueChild && ConceptTypeChildHasPathFactType.GetLinksToConceptTypeChild(factType).Count == 1) { minKeySize = idList.Count; uniqueUseIndex = minKeySize - 1; } } ConceptTypeAssimilatesConceptType assimilation; if (uniqueUseIndex != -1 && null != (assimilation = child as ConceptTypeAssimilatesConceptType) && AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) != AssimilationAbsorptionChoice.Absorb) { uniqueUseIndex = idList.Count - 1; } } else if (null != (infoType = child as InformationType) && null != (objectType = ConceptTypeIsForObjectType.GetObjectType(infoType.ConceptType))) { // Happens for a value column in an object type table, which has one concept type child idList.Add(objectType.Id); } } int count = idList.Count; if (0 == count) { return(false); } if (uniqueUseIndex != -1 && (uniqueUseIndex + 1) < count) { idList.RemoveRange(uniqueUseIndex + 1, count - uniqueUseIndex - 1); } if (minKeySize == 0) { minKeySize = idList.Count; } return(true); }
/// <summary> /// Generages the <see cref="ConceptType"/> objects along with any relationships that they have and adds them to the /// model. /// </summary> /// <param name="factTypeMappings">A dictionary of all the final decided FactTypeMapping objects.</param> private void GenerateConceptTypes(FactTypeMappingDictionary factTypeMappings) { ORMModel model = this.ORMModel; LinkedElementCollection<ObjectType> modelObjectTypes = model.ObjectTypeCollection; AbstractionModel oialModel = this.AbstractionModel; // For each object type in the model... foreach (ObjectType objectType in modelObjectTypes) { if (ShouldIgnoreObjectType(objectType)) { continue; } // If it should have a conctpt type... if (ObjectTypeIsConceptType(objectType, factTypeMappings)) { // Create the ConceptType object. PropertyAssignment name = new PropertyAssignment(ConceptType.NameDomainPropertyId, objectType.Name); ConceptType conceptType = new ConceptType(Store, name); ConceptTypeIsForObjectType conceptTypeIsForObjectType = new ConceptTypeIsForObjectType(conceptType, objectType); // Add it to the model. oialModel.ConceptTypeCollection.Add(conceptType); // If this conceptType is for a ValueType... if (objectType.IsValueType) { InformationTypeFormat valueTypeInformationTypeFormat = InformationTypeFormatIsForValueType.GetInformationTypeFormat(objectType); RoleAssignment conceptTypeRole = new RoleAssignment(InformationType.ConceptTypeDomainRoleId, conceptType); RoleAssignment informationTypeFormat = new RoleAssignment(InformationType.InformationTypeFormatDomainRoleId, valueTypeInformationTypeFormat); RoleAssignment[] roleAssignments = { conceptTypeRole, informationTypeFormat }; PropertyAssignment isMandatory = new PropertyAssignment(InformationType.IsMandatoryDomainPropertyId, true); PropertyAssignment informationTypeNameProperty = new PropertyAssignment(InformationType.NameDomainPropertyId, String.Concat(objectType.Name, "Value")); PropertyAssignment[] informationTypePropertyAssignments = { isMandatory, informationTypeNameProperty }; // ConceptType for conceptType gets an InformationType that references InformationTypeFormat for conceptType. InformationType informationType = new InformationType(Store, roleAssignments, informationTypePropertyAssignments); PropertyAssignment uniquenessNameProperty = new PropertyAssignment(Uniqueness.NameDomainPropertyId, String.Concat(objectType.Name, "Uniqueness")); PropertyAssignment isPreferred = new PropertyAssignment(Uniqueness.IsPreferredDomainPropertyId, true); PropertyAssignment[] uniquenessPropertyAssignments = { uniquenessNameProperty, isPreferred }; // Uniqueness constraint Uniqueness uniqueness = new Uniqueness(Store, uniquenessPropertyAssignments); UniquenessIncludesConceptTypeChild uniquenessIncludesConceptTypeChild = new UniquenessIncludesConceptTypeChild(uniqueness, informationType); conceptType.UniquenessCollection.Add(uniqueness); } } } }
/// <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); } }