/// <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(); }
/// <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)); }
/// <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); } }
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> /// 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); } }