public GenericParserHelper(DslSyntax syntax, string overrideKeyword = null) { DslSyntax = syntax; ConceptType conceptType = DslSyntax.GetConceptType(typeof(TConceptInfo), overrideKeyword); GenericParser = new GenericParser(conceptType); }
/// <summary> /// RolePlayerPositionChangeRule: typeof(ORMSolutions.ORMArchitect.ORMAbstraction.UniquenessIncludesConceptTypeChild) /// Reorder the columns in a uniqueness constraint when the order changes /// </summary> private static void UniquenessConstraintRoleOrderChanged(RolePlayerOrderChangedEventArgs e) { Uniqueness uniqueness; LinkedElementCollection <UniquenessConstraint> constraints; int constraintCount; if (null != (uniqueness = e.SourceElement as Uniqueness) && e.SourceDomainRole.Id == UniquenessIncludesConceptTypeChild.UniquenessDomainRoleId && 0 != (constraintCount = (constraints = UniquenessConstraintIsForUniqueness.GetUniquenessConstraint(uniqueness)).Count)) { LinkedElementCollection <ConceptTypeChild> conceptTypeChildren = uniqueness.ConceptTypeChildCollection; int conceptTypeChildCount = conceptTypeChildren.Count; for (int i = 0; i < constraintCount; ++i) { LinkedElementCollection <Column> constraintColumns = constraints[i].ColumnCollection; int constraintColumnCount = constraintColumns.Count; if (constraintColumnCount == conceptTypeChildCount) { constraintColumns.Move(e.OldOrdinal, e.NewOrdinal); } else { // UNDONE: The question of exactly how many columns are associated with a reference to // a conceptTypeChild is highly non-trivial. Punt on the issue for now by regenerating // the model. ConceptType conceptType = uniqueness.ConceptType; if (conceptType != null) { RebuildAbstractionModel(conceptType.Model); } } } } }
public Concepts(ConceptType type) { _type = type; _concepts = new Dictionary <ConceptMode, List <Concept> >(); _relations = new List <Relation>(); _subgroups = new List <PropertyGroup>(); }
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); } } } }
public InternalConceptCheck(ConceptType conceptType, string formulaValue, string formulaTotal) { ConceptPaymentDI = new ConceptPaymentDI(); ConceptPaymentDI.ConceptType = conceptType; ConceptPaymentDI.FormulaTotal = formulaTotal; ConceptPaymentDI.FormulaValue = formulaValue; }
private static void ValidateConceptTypeNameChanged(ConceptType conceptType) { if (null != conceptType) { FrameworkDomainModel.DelayValidateElement(conceptType, DelayValidateConceptTypeNameChanged); } }
public string GetDocumentation(ConceptType conceptType, string linePrefix = null) { if (rhetosProjectContext.Documentation == null) { return("*No XML documentation information was found for this Rhetos App*"); } if (!rhetosProjectContext.Documentation.TryGetValue(conceptType.AssemblyQualifiedName, out var conceptDocumentation)) { return(""); } var documentation = $"{conceptDocumentation.Summary}"; if (!string.IsNullOrEmpty(conceptDocumentation.Remarks)) { documentation += $"\n\nRemarks:\n{conceptDocumentation.Remarks}\n"; } if (!string.IsNullOrEmpty(documentation) && !string.IsNullOrEmpty(linePrefix)) { documentation = linePrefix + documentation.Replace("\n", $"\n{linePrefix}"); } return(documentation); }
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); } } } } } }
public Concept(string name, ConceptType type, ConceptMode mode) { _name = name; _type = type; _mode = mode; _related = new List <Concept>(); _certainty = 0; _subgroupNameName = null; }
/// <summary> /// DeleteRule: typeof(ConceptTypeIsForObjectType) /// </summary> private static void ConceptTypeBridgeDetachedRule(ElementDeletedEventArgs e) { ConceptType conceptType = ((ConceptTypeIsForObjectType)e.ModelElement).ConceptType; if (!conceptType.IsDeleted && TestRebuildAbstractionModel(conceptType.Model)) { AddTransactedModelElement(conceptType, ModelElementModification.AbstractionElementDetached); } }
/// <summary> /// DeleteRule: typeof(ConceptTypeChildHasPathFactType) /// </summary> private static void ConceptTypeChildPathBridgeDetachedRule(ElementDeletedEventArgs e) { ConceptTypeChild child = ((ConceptTypeChildHasPathFactType)e.ModelElement).ConceptTypeChild; ConceptType conceptType = child.Parent; if (conceptType != null && !conceptType.IsDeleted && TestRebuildAbstractionModel(conceptType.Model)) { AddTransactedModelElement(conceptType, ModelElementModification.AbstractionElementDetached); } }
/// <summary> /// for many-to-many associations; it is assumed that IsSimpleManyToManyAssociation has been /// called on the passed-in concept type and returned true /// </summary> /// <param name="parentConceptType"></param> /// <param name="notifyAdded"></param> /// <param name="associationCounter"></param> private static void CreateBinaryAssociation(ConceptType parentConceptType, INotifyElementAdded notifyAdded, ref int associationCounter) { if (BinaryAssociationHasConceptType.GetBinaryAssociation(parentConceptType).Count == 0) { LinkedElementCollection <ConceptTypeChild> associationChildren = ConceptTypeHasChildAsPartOfAssociation.GetTargetCollection(parentConceptType); ConceptTypeChild relation1, relation2; ConceptType ct1, ct2; if (null != (relation1 = associationChildren[0]) && null != (relation2 = associationChildren[1]) && null != (ct1 = relation1.Target as ConceptType) && null != (ct2 = relation2.Target as ConceptType)) { // create association BinaryAssociation b = new BinaryAssociation(parentConceptType.Store, new PropertyAssignment[] { new PropertyAssignment(BinaryAssociation.NumberDomainPropertyId, associationCounter++) }); //new BinaryAssociationHasConceptTypeChild(b, relation); BinaryAssociationHasConceptType.GetConceptType(b).Add(parentConceptType); Role r1 = new Role(parentConceptType.Store, new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, ct1.Name) }); Role r2 = new Role(parentConceptType.Store, new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, ct2.Name) }); b.RoleCollection.Add(r1); b.RoleCollection.Add(r2); EntityType sourceEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(ct1); EntityType targetEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(ct2); sourceEntity.RoleCollection.Add(r1); targetEntity.RoleCollection.Add(r2); sourceEntity.BarkerErModel.BinaryAssociationCollection.Add(b); //determine whether roles are mandatory or optional //TODO //set multi-values r1.IsMultiValued = true; r2.IsMultiValued = true; //notify elements added if (notifyAdded != null) { notifyAdded.ElementAdded(b, true); notifyAdded.ElementAdded(r1, true); notifyAdded.ElementAdded(r2, true); } } } }
private Concept(ConceptId conceptId, ConceptName name, Difficulty difficulty, ConceptType type, params SubcategoryObject[] subcategories) : base(conceptId) { if (Difficulty == null) { throw new ArgumentNullException(nameof(difficulty)); } this.name = name; Difficulty = difficulty; Type = type; this.subcategories = subcategories; guessed = false; }
private static void UpdateTablesForConceptType(ConceptType conceptType, Predicate <ConceptType> conceptTypeFilter, Predicate <Table> tableFilter) { Table primaryTable = TableIsPrimarilyForConceptType.GetTable(conceptType); LinkedElementCollection <Table> secondaryTables = TableIsAlsoForConceptType.GetTable(conceptType); if (primaryTable != null && (tableFilter == null || !tableFilter(primaryTable))) { UpdateTablePresentationSize(primaryTable); } foreach (Table secondaryTable in secondaryTables) { if (tableFilter == null || !tableFilter(secondaryTable)) { UpdateTablePresentationSize(secondaryTable); } } Predicate <ConceptType> recurseConceptTypeFilter = delegate(ConceptType testConceptType) { return(testConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(testConceptType))); }; Predicate <Table> recurseTableFilter = delegate(Table testTable) { return(testTable == primaryTable || secondaryTables.Contains(testTable)); }; foreach (ConceptType relatingConceptType in ConceptTypeRelatesToConceptType.GetRelatingConceptTypeCollection(conceptType)) { if (relatingConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(relatingConceptType))) { continue; } UpdateTablesForConceptType( relatingConceptType, recurseConceptTypeFilter, recurseTableFilter); } foreach (ConceptType assimilatedConceptType in ConceptTypeAssimilatesConceptType.GetAssimilatedConceptTypeCollection(conceptType)) { if (assimilatedConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(assimilatedConceptType))) { continue; } UpdateTablesForConceptType( assimilatedConceptType, recurseConceptTypeFilter, recurseTableFilter); } }
static ConceptType createConcept(Variable var) { ConceptType concept = new ConceptType(); concept.id = var.Name.CleanID(); List <TextType> name = new List <TextType>(); { TextType enName = new TextType(); enName.lang = "en"; enName.Value = var.Name; name.Add(enName); } concept.Name = name.ToArray(); return(concept); }
private static void DelayValidateConceptTypeNameChanged(ModelElement element) { if (!element.IsDeleted) { ConceptType conceptType = (ConceptType)element; Table table1 = TableIsPrimarilyForConceptType.GetTable(conceptType); if (null != table1) { ValidateSchemaNamesChanged(table1.Schema); } foreach (Table table2 in TableIsAlsoForConceptType.GetTable(conceptType)) { ValidateSchemaNamesChanged(table2.Schema); } } }
public static string ConceptToString(ConceptType type) { switch (type) { case ConceptType.Person: return("person"); case ConceptType.Place: return("place"); case ConceptType.Idea: return("idea"); default: return("thing"); } }
private static void UpdateEntitiesForConceptType(ConceptType conceptType, Predicate <ConceptType> conceptTypeFilter, Predicate <EntityType> entityFilter) { EntityType primaryEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(conceptType); if (primaryEntity != null && (entityFilter == null || !entityFilter(primaryEntity))) { UpdateEntityPresentationSize(primaryEntity); } Predicate <ConceptType> recurseConceptTypeFilter = delegate(ConceptType testConceptType) { return(testConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(testConceptType))); }; Predicate <EntityType> recurseEntityFilter = delegate(EntityType testEntity) { return(testEntity == primaryEntity); }; foreach (ConceptType relatingConceptType in ConceptTypeRelatesToConceptType.GetRelatingConceptTypeCollection(conceptType)) { if (relatingConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(relatingConceptType))) { continue; } UpdateEntitiesForConceptType( relatingConceptType, recurseConceptTypeFilter, recurseEntityFilter); } foreach (ConceptType assimilatedConceptType in ConceptTypeAssimilatesConceptType.GetAssimilatedConceptTypeCollection(conceptType)) { if (assimilatedConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(assimilatedConceptType))) { continue; } UpdateEntitiesForConceptType( assimilatedConceptType, recurseConceptTypeFilter, recurseEntityFilter); } }
private static bool IsSimpleManyToManyAssociation(ConceptType conceptType) { LinkedElementCollection <ConceptTypeChild> associationChildren = ConceptTypeHasChildAsPartOfAssociation.GetTargetCollection(conceptType); ConceptTypeChild child0; ConceptTypeChild child1; if (associationChildren.Count == 2 && !((child0 = associationChildren[0]) is InformationType) && !((child1 = associationChildren[1]) is InformationType)) { ReadOnlyCollection <ConceptTypeChild> allChildren = ConceptTypeChild.GetLinksToTargetCollection(conceptType); if (allChildren.Count == 2) { return (child0 == allChildren[0] && child1 == allChildren[1] || child0 == allChildren[1] && child1 == allChildren[0]); } } 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); }
private RhetosSignature CreateRhetosSignature(ConceptType conceptType) { var prefix = " "; var signature = ConceptTypeTools.SignatureDescription(conceptType); var documentation = $"{prefix}* defined by {conceptType.AssemblyQualifiedName}"; var xmlDocumentation = GetDocumentation(conceptType, prefix); if (!string.IsNullOrEmpty(xmlDocumentation)) { documentation = $"{xmlDocumentation}\n{documentation}"; } return(new RhetosSignature() { ConceptType = conceptType, Parameters = ConceptTypeTools.GetParameters(conceptType), Signature = signature, Documentation = documentation }); }
public void SideloadCertaintyState(string certaintyJson) { UpdateEpisim(certaintyJson); var certainties = JSON.Parse(certaintyJson); JSONArray cCertainties = certainties["c"].AsArray; foreach (string cCertainty in cCertainties.Values) { string[] split1 = cCertainty.Split(Jsonifier.CertaintySep); string conceptString = split1[0]; string certaintyString = split1[1]; string[] split2 = conceptString.Split(Jsonifier.JsonRelationConnector); ConceptType type = (ConceptType)Int32.Parse(split2[0]); ConceptMode mode = (ConceptMode)Int32.Parse(split2[1]); int idx = Int32.Parse(split2[2]); GetConcepts(type).GetConcept(idx, mode).Certainty = Double.Parse(certaintyString); } JSONArray rCertainties = certainties["r"].AsArray; foreach (string rCertainty in rCertainties.Values) { string[] split1 = rCertainty.Split(Jsonifier.CertaintySep); string relationString = split1[0]; string certaintyString = split1[1]; string[] split2 = relationString.Split(Jsonifier.JsonRelationConnector); ConceptType type = (ConceptType)Int32.Parse(split2[0]); ConceptMode oMode = (ConceptMode)Int32.Parse(split2[1]); int oIdx = Int32.Parse(split2[2]); ConceptMode dMode = (ConceptMode)Int32.Parse(split2[3]); int dIdx = Int32.Parse(split2[4]); Concept origin = GetConcepts(type).GetConcept(oIdx, oMode); Concept destination = GetConcepts(type).GetConcept(dIdx, dMode); GetRelation(origin, destination).Certainty = Double.Parse(certaintyString); } }
private static void CreateAttributesAndBinaryRelationships(ConceptType conceptType, INotifyElementAdded notifyAdded, ref int associationCounter) { List <Attribute> attributesForConceptType = new List <Attribute>(); foreach (InformationType informationType in InformationType.GetLinksToInformationTypeFormatCollection(conceptType)) { attributesForConceptType.Add(CreateAttributeForInformationType(informationType, new Stack <ConceptTypeChild>())); } foreach (ConceptTypeRelatesToConceptType conceptTypeRelation in ConceptTypeRelatesToConceptType.GetLinksToRelatedConceptTypeCollection(conceptType)) { if (!CreateBinaryAssociation(conceptTypeRelation, conceptType, conceptTypeRelation.RelatedConceptType, notifyAdded, ref associationCounter)) { //if binary association was not created - let's create an attribute for it attributesForConceptType.AddRange(GetAttributesForConceptTypeRelation(conceptTypeRelation, new Stack <ConceptTypeChild>())); } } foreach (ConceptTypeAssimilatesConceptType conceptTypeAssimilation in ConceptTypeAssimilatesConceptType.GetLinksToAssimilatedConceptTypeCollection(conceptType)) { if (!conceptTypeAssimilation.RefersToSubtype) { CreateBinaryAssociation(conceptTypeAssimilation, conceptType, conceptTypeAssimilation.AssimilatedConceptType, notifyAdded, ref associationCounter); } } EntityType conceptTypeEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(conceptType); if (conceptTypeEntity != null) { conceptTypeEntity.AttributeCollection.AddRange(attributesForConceptType); if (notifyAdded != null) { foreach (Attribute attr in attributesForConceptType) { notifyAdded.ElementAdded(attr, true); } } } }
private int GetActiveParameterForValidConcept(ConceptType conceptType) { var activeParameter = 0; // we have parsed some members successfully for this concept type if (LastTokenParsed.ContainsKey(conceptType)) { activeParameter = ConceptTypeTools.IndexOfParameter(conceptType, LastMemberReadAttempt[conceptType]); // if we have just typed a keyword OR have stopped typing a parameter (by pressing space, etc.), we need to advance to next parameter // keyword scenario is possible in nested concepts, where we already have valid parameters and are just typing a keyword var lineChr = new LineChr(Line, Chr); var atLastParsed = GetTokenAtPosition(lineChr) == LastTokenParsed[conceptType] || GetTokenLeftOfPosition(lineChr) == LastTokenParsed[conceptType]; var atKeyword = string.Equals(conceptType.Keyword, LastTokenParsed[conceptType].Value, StringComparison.InvariantCultureIgnoreCase); if (atKeyword || !atLastParsed) { activeParameter++; } } return(activeParameter); }
public static string SignatureDescription(ConceptType conceptType) { var keys = new List <string>(); var parameters = new List <string>(); foreach (var member in GetParameters(conceptType)) { if (member.IsKey) { keys.Add(ConceptMemberDescription(member)); } else { parameters.Add(ConceptMemberDescription(member)); } } var keyword = conceptType.GetKeywordOrTypeName(); var keysDesc = string.Join(".", keys.Select(key => $"<{key}>")); var paramDesc = string.Join(" ", parameters.Select(parameter => $"<{parameter}>")); return($"{keyword} {keysDesc} {paramDesc}"); }
public List <ConceptType> ValidConceptsForParent(ConceptType parentConceptType) { var result = new List <ConceptType>(); foreach (var conceptType in rhetosProjectContext.DslSyntax.ConceptTypes) { if (conceptType == parentConceptType) { continue; } var members = conceptType.Members; var parentNestedMember = members.FirstOrDefault(member => member.IsParentNested); var firstMember = members.FirstOrDefault(); // is first member valid? if (firstMember == null || !firstMember.IsKey || !firstMember.IsConceptInfo) { firstMember = null; } var parentMember = parentNestedMember ?? firstMember; if (parentMember == null) { continue; } if (parentMember.IsConceptInfoInterface || (parentMember.ConceptType?.IsAssignableFrom(parentConceptType) ?? false)) { result.Add(conceptType); } } return(result); }
private static bool AllStepsMandatory(EntityType entity, IEnumerable <ConceptTypeChild> links) { bool allStepsMandatory = true; ConceptType lastTarget = null; bool firstPass = true; foreach (ConceptTypeChild child in links) { if (!child.IsMandatory) { ConceptTypeAssimilatesConceptType assimilation = child as ConceptTypeAssimilatesConceptType; if (assimilation != null) { // The IsMandatory property applies when stepping parent-to-target, However, stepping target-to-parent // is always considered mandatory. See if we're in this situation. if (firstPass) { lastTarget = EntityTypeIsPrimarilyForConceptType.GetConceptType(entity); } if (lastTarget != null && lastTarget == assimilation.Target) { lastTarget = assimilation.Parent; firstPass = false; continue; } } allStepsMandatory = false; break; } lastTarget = child.Target as ConceptType; firstPass = false; } return(allStepsMandatory); }
/// <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> /// Generates the appropriate <see cref="ConceptTypeChild">concept type children</see> in <paramref name="parentConceptType"/> /// for <paramref name="factTypeMapping"/>. /// </summary> /// <param name="factTypeMappings"> /// The set of all decided <see cref="FactTypeMapping">fact type mappings</see>. /// </param> /// <param name="parentConceptType"> /// The <see cref="ConceptType"/> into which <see cref="ConceptTypeChild">concept type children</see> should be generated. /// </param> /// <param name="parentConceptTypeHasDeepAway"> /// Test if the parent concept type has a deep mapping away from it. Handles some cyclic cases by making a potential assimilation /// into a reference. Delay calculated because this is not always needed. /// </param> /// <param name="factTypeMapping"> /// The <see cref="FactTypeMapping"/> for which <see cref="ConceptTypeChild">concept type children</see> should be generated. /// </param> /// <param name="factTypePath"> /// The path of <see cref="FactType">fact types</see> leading from <paramref name="parentConceptType"/> to <paramref name="factTypeMapping"/> /// </param> /// <param name="isMandatorySoFar"> /// Indicates whether every step in <paramref name="factTypePath"/> is mandatory for the parent concept type (towards object type). /// </param> private static void GenerateConceptTypeChildrenForFactTypeMapping(FactTypeMappingDictionary factTypeMappings, ConceptType parentConceptType, ref bool? parentConceptTypeHasDeepAway, FactTypeMapping factTypeMapping, List<FactType> factTypePath, bool isMandatorySoFar) { // Push the current fact type onto the path. factTypePath.Add(factTypeMapping.FactType); bool isMandatory = isMandatorySoFar && (factTypeMapping.TowardsRoleMandatory); ConceptTypeChild newConceptTypeChild; ConceptType fromConceptType = ConceptTypeIsForObjectType.GetConceptType(factTypeMapping.FromObjectType); if (fromConceptType != null) { // The mapping is coming from a concept type, so we will create a concept type reference to it. // Set up the property assignments that are common to both kinds of concept type references. PropertyAssignment isMandatoryPropertyAssignment = new PropertyAssignment(ConceptTypeChild.IsMandatoryDomainPropertyId, isMandatory); string name = ResolveRoleName(factTypeMapping.FromRole); string oppositeName = ResolveRoleName(factTypeMapping.TowardsRole); // UNDONE: Yes, these are backwards, but they need to remain so for compatibility reasons until we do a file format change. PropertyAssignment namePropertyAssignment = new PropertyAssignment(ConceptTypeChild.NameDomainPropertyId, oppositeName); PropertyAssignment oppositeNamePropertyAssignment = new PropertyAssignment(ConceptTypeReferencesConceptType.OppositeNameDomainPropertyId, name); if (factTypeMapping.MappingDepth == MappingDepth.Deep) { // Since this is a deep mapping, we will create a concept type assimilation for it. SubtypeFact subtypeFact = factTypeMapping.FactType as SubtypeFact; // UNDONE: The handling here for IsPreferredForParent and IsPreferredForTarget may not be correct // if we have more than one fact type in the fact type path. bool isPreferredForTarget; if (subtypeFact != null) { // For subtype assimilations, IsPreferredForTarget matches the ProvidesPreferredIdentifier // property of the ORM subtype fact. isPreferredForTarget = subtypeFact.ProvidesPreferredIdentifier; } else { // For non-subtype assimilations, IsPreferredForTarget is true if the role played by the object // type corresponding to the parent concept type has the preferred identifying uniqueness constraint // for the target concept type. isPreferredForTarget = factTypeMapping.TowardsRole.SingleRoleAlethicUniquenessConstraint.IsPreferred; } bool isPreferredForParent = factTypeMapping.IsFromPreferredIdentifier; // The IsPreferredForParent property on concept type assimilations indicates that the assimilation, on its own, // provides the preferred identifier for the assimilating concept type. Although the IsFromPreferredIdentifier // property on the fact type mapping will be true even if the from role is part of a multi-role preferred identifier, // ORM currently doesn't allow a role with a single role alethic uniqueness constraint (which is required for this to // be a deep mapping) to be part of any other uniqueness constraint. However, this may change in the future as our // handling of derivations, implications, equivalences, and logical rules becomes more sophisticated. We assert here // in order to make this case easier to catch if it happens, since this method may need to be adjusted in that case // to ensure that it continues to produce correct results. Debug.Assert(!isPreferredForParent || factTypeMapping.FromRole.SingleRoleAlethicUniquenessConstraint.IsPreferred); newConceptTypeChild = new ConceptTypeAssimilatesConceptType(parentConceptType.Partition, new RoleAssignment[] { new RoleAssignment(ConceptTypeAssimilatesConceptType.AssimilatorConceptTypeDomainRoleId, parentConceptType), new RoleAssignment(ConceptTypeAssimilatesConceptType.AssimilatedConceptTypeDomainRoleId, fromConceptType) }, new PropertyAssignment[] { isMandatoryPropertyAssignment, namePropertyAssignment, oppositeNamePropertyAssignment, new PropertyAssignment(ConceptTypeAssimilatesConceptType.RefersToSubtypeDomainPropertyId, subtypeFact != null), new PropertyAssignment(ConceptTypeAssimilatesConceptType.IsPreferredForParentDomainPropertyId, isPreferredForParent), new PropertyAssignment(ConceptTypeAssimilatesConceptType.IsPreferredForTargetDomainPropertyId, isPreferredForTarget), }); } else { Debug.Assert(factTypeMapping.MappingDepth == MappingDepth.Shallow, "Collapse mappings should not come from object types that have a concept type."); // Since this is a shallow mapping, we will create a concept type relation for it. newConceptTypeChild = new ConceptTypeRelatesToConceptType(parentConceptType.Partition, new RoleAssignment[] { new RoleAssignment(ConceptTypeRelatesToConceptType.RelatingConceptTypeDomainRoleId, parentConceptType), new RoleAssignment(ConceptTypeRelatesToConceptType.RelatedConceptTypeDomainRoleId, fromConceptType) }, new PropertyAssignment[] { isMandatoryPropertyAssignment, namePropertyAssignment, oppositeNamePropertyAssignment }); } } else { // The mapping is not coming from a concept type, meaning that we either need an information // type for an atomic value type (which will already have an information type format created // for it), or we need to collapse the preferred identifier of an entity type or structured // value type. InformationTypeFormat fromInformationTypeFormat = InformationTypeFormatIsForValueType.GetInformationTypeFormat(factTypeMapping.FromObjectType); if (fromInformationTypeFormat != null) { // We have an information type format, which means that we need to create an information type. string name = ResolveRoleName(factTypeMapping.FromRole); newConceptTypeChild = new InformationType(parentConceptType.Partition, new RoleAssignment[] { new RoleAssignment(InformationType.ConceptTypeDomainRoleId, parentConceptType), new RoleAssignment(InformationType.InformationTypeFormatDomainRoleId, fromInformationTypeFormat) }, new PropertyAssignment[] { new PropertyAssignment(ConceptTypeChild.IsMandatoryDomainPropertyId, isMandatory), new PropertyAssignment(ConceptTypeChild.NameDomainPropertyId, name) }); } else { // We do not have an information type format, which means that we need to collapse the fact // types in the preferred identifier of the FromObjectType into the parent concept type. newConceptTypeChild = null; UniquenessConstraint preferredIdentifier = factTypeMapping.FromObjectType.PreferredIdentifier; Debug.Assert(preferredIdentifier != null); foreach (Role preferredIdentifierRole in preferredIdentifier.RoleCollection) { // NOTE: We don't need the ShouldIgnoreFactType filter here, because we would have ignored // this object type if we were ignoring any of the fact types in its preferred identifier. FactType preferredIdentifierFactType = preferredIdentifierRole.BinarizedFactType; FactTypeMapping preferredIdentifierFactTypeMapping = factTypeMappings[preferredIdentifierFactType]; if (preferredIdentifierFactType == factTypeMapping.FactType) { // We just got back to the fact that we were already mapping. This should only happen // when the object type has a single fact type in its preferred identifier and it is // deeply mapped away from the object type. Debug.Assert(preferredIdentifier.RoleCollection.Count == 1 && preferredIdentifierFactTypeMapping.MappingDepth == MappingDepth.Deep); // UNDONE: For now, we just ignore this fact type entirely. What we should be doing is: // 1) If everything along the path is mandatory, then we're done, since we know that instances of the parent // concept type always identify an instance of the object type that we're trying to map. // 2) Otherwise, check if there are any other relationships that would allow use to derive whether an instance // of the parent concept type identifies an instance of the object type that we're trying to map. Examples // of things that would allow us to do this would be a mandatory role played by the object type that we're // we're trying to map that gets absorbed into some concept type. The reference to an instance of this concept // type from it allows us to tell if this instance identifies an instance of the object type. // 3) If no other relationship allows us to derive this information, we need to add a boolean information type // that indicates for each instance of the parent concept type whether it identifies an instance of the object // type that we're trying to map. break; } // If we have a single fact type in the preferred identifier, it might be mapped // deeply away from the object type that we are collapsing. For this case, we need // to create a "fake" mapping and process it instead. if (preferredIdentifierFactTypeMapping.TowardsRole == preferredIdentifierRole) { // Make sure this is actually the situation we are trying to handle, since it shouldn't be possible in any other scenario. Debug.Assert(preferredIdentifier.RoleCollection.Count == 1 && preferredIdentifierFactTypeMapping.MappingDepth == MappingDepth.Deep); // UNDONE: Would we ever want to use a depth other than shallow here? Probably not, but it might be worth looking in to. FactTypeMappingFlags currentFlags = preferredIdentifierFactTypeMapping.Flags; preferredIdentifierFactTypeMapping = new FactTypeMapping(preferredIdentifierFactType, preferredIdentifierFactTypeMapping.TowardsRole, preferredIdentifierFactTypeMapping.FromRole, (currentFlags & FactTypeMappingFlags.Subtype) | GetFlags(false, 0 != (currentFlags & FactTypeMappingFlags.TowardsValueType), 0 != (currentFlags & FactTypeMappingFlags.TowardsRoleMandatory), 0 != (currentFlags & FactTypeMappingFlags.TowardsRoleImpliedMandatory), 0 != (currentFlags & FactTypeMappingFlags.FromValueType), 0 != (currentFlags & FactTypeMappingFlags.FromRoleMandatory), 0 != (currentFlags & FactTypeMappingFlags.FromRoleImpliedMandatory))); } else if (preferredIdentifierFactTypeMapping.MappingDepth == MappingDepth.Deep) { // Handle cyclic deep mapping scenario with collapsed entities. // The primary scenario here is: // 1) B is a subtype of A and identified by A's identifier // 2) A and B participate in an objectified 1-1 FactType // 3) The uniqueness constraint on the A role is the preferred identifier // 4) The A role is mandatory // In this case, without this code, you get an assimilation mapping B into A // and mapping A into B. We fix this case by forwarding a shallow mapping, // which generates a reference instad of an assimilation. if (!parentConceptTypeHasDeepAway.HasValue) { ObjectType objectType = ConceptTypeIsForObjectType.GetObjectType(parentConceptType); foreach (Role role in ConceptTypeIsForObjectType.GetObjectType(parentConceptType).PlayedRoleCollection) { FactType factType; FactTypeMapping testMapping; if (null != (factType = role.BinarizedFactType) && factTypeMappings.TryGetValue(factType, out testMapping) && testMapping.MappingDepth == MappingDepth.Deep && testMapping.FromObjectType == objectType) { preferredIdentifierFactTypeMapping = new FactTypeMapping(preferredIdentifierFactType, preferredIdentifierFactTypeMapping.FromRole, preferredIdentifierFactTypeMapping.TowardsRole, preferredIdentifierFactTypeMapping.Flags & ~FactTypeMappingFlags.DeepMapping); parentConceptTypeHasDeepAway = true; break; } } if (!parentConceptTypeHasDeepAway.HasValue) { parentConceptTypeHasDeepAway = false; } } else if (parentConceptTypeHasDeepAway.Value) { preferredIdentifierFactTypeMapping = new FactTypeMapping(preferredIdentifierFactType, preferredIdentifierFactTypeMapping.FromRole, preferredIdentifierFactTypeMapping.TowardsRole, preferredIdentifierFactTypeMapping.Flags & ~FactTypeMappingFlags.DeepMapping); } } GenerateConceptTypeChildrenForFactTypeMapping(factTypeMappings, parentConceptType, ref parentConceptTypeHasDeepAway, preferredIdentifierFactTypeMapping, factTypePath, isMandatory); } } } // If we created a new concept type child, populate its fact type path. if (newConceptTypeChild != null) { foreach (FactType pathFactType in factTypePath) { ConceptTypeChildHasPathFactType conceptTypeChildHasPathFactType = new ConceptTypeChildHasPathFactType(newConceptTypeChild, pathFactType); } } // Pop the current fact type off of the path. Debug.Assert(factTypePath[factTypePath.Count - 1] == factTypeMapping.FactType, "Fact type path stack is corrupt."); factTypePath.RemoveAt(factTypePath.Count - 1); }
private static void UpdateTablesForConceptType(ConceptType conceptType, Predicate<ConceptType> conceptTypeFilter, Predicate<Table> tableFilter) { Table primaryTable = TableIsPrimarilyForConceptType.GetTable(conceptType); LinkedElementCollection<Table> secondaryTables = TableIsAlsoForConceptType.GetTable(conceptType); if (primaryTable != null && (tableFilter == null || !tableFilter(primaryTable))) { UpdateTablePresentationSize(primaryTable); } foreach (Table secondaryTable in secondaryTables) { if (tableFilter == null || !tableFilter(secondaryTable)) { UpdateTablePresentationSize(secondaryTable); } } Predicate<ConceptType> recurseConceptTypeFilter = delegate(ConceptType testConceptType) { return testConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(testConceptType)); }; Predicate<Table> recurseTableFilter = delegate(Table testTable) { return testTable == primaryTable || secondaryTables.Contains(testTable); }; foreach (ConceptType relatingConceptType in ConceptTypeRelatesToConceptType.GetRelatingConceptTypeCollection(conceptType)) { if (relatingConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(relatingConceptType))) { continue; } UpdateTablesForConceptType( relatingConceptType, recurseConceptTypeFilter, recurseTableFilter); } foreach (ConceptType assimilatedConceptType in ConceptTypeAssimilatesConceptType.GetAssimilatedConceptTypeCollection(conceptType)) { if (assimilatedConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(assimilatedConceptType))) { continue; } UpdateTablesForConceptType( assimilatedConceptType, recurseConceptTypeFilter, recurseTableFilter); } }
/// <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); } }
private static void UpdateEntitiesForConceptType(ConceptType conceptType, Predicate<ConceptType> conceptTypeFilter, Predicate<EntityType> entityFilter) { EntityType primaryEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(conceptType); if (primaryEntity != null && (entityFilter == null || !entityFilter(primaryEntity))) { UpdateEntityPresentationSize(primaryEntity); } Predicate<ConceptType> recurseConceptTypeFilter = delegate(ConceptType testConceptType) { return testConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(testConceptType)); }; Predicate<EntityType> recurseEntityFilter = delegate(EntityType testEntity) { return testEntity == primaryEntity; }; foreach (ConceptType relatingConceptType in ConceptTypeRelatesToConceptType.GetRelatingConceptTypeCollection(conceptType)) { if (relatingConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(relatingConceptType))) { continue; } UpdateEntitiesForConceptType( relatingConceptType, recurseConceptTypeFilter, recurseEntityFilter); } foreach (ConceptType assimilatedConceptType in ConceptTypeAssimilatesConceptType.GetAssimilatedConceptTypeCollection(conceptType)) { if (assimilatedConceptType == conceptType || (conceptTypeFilter != null && conceptTypeFilter(assimilatedConceptType))) { continue; } UpdateEntitiesForConceptType( assimilatedConceptType, recurseConceptTypeFilter, recurseEntityFilter); } }
private static List <Attribute> GetPreferredIdentifierAttributesForConceptType(ConceptType conceptType, Stack <ConceptTypeChild> conceptTypeChildPath) { foreach (Uniqueness uniqueness in conceptType.UniquenessCollection) { if (uniqueness.IsPreferred) { LinkedElementCollection <ConceptTypeChild> uniquenessConceptTypeChildren = uniqueness.ConceptTypeChildCollection; List <Attribute> attributes = new List <Attribute>(uniquenessConceptTypeChildren.Count); foreach (ConceptTypeChild conceptTypeChild in uniquenessConceptTypeChildren) { InformationType informationType = conceptTypeChild as InformationType; if (informationType != null) { attributes.Add(CreateAttributeForInformationType(informationType, conceptTypeChildPath)); } else { Debug.Assert(conceptTypeChild is ConceptTypeRelatesToConceptType, "Uniquenesses can't contain ConceptTypeAssimilations."); attributes.AddRange(GetAttributesForConceptTypeRelation((ConceptTypeRelatesToConceptType)conceptTypeChild, conceptTypeChildPath)); } } return(attributes); } } Debug.Fail("Couldn't find preferred identifier for concept type."); throw new sys.InvalidOperationException(); }
public static Concept Create(Guid id, string name, int stars, ConceptType type, params SubcategoryObject[] subcategories) => new Concept(new ConceptId(id), new ConceptName(name), Difficulty.GetValue(stars), type, subcategories);