public void SetFields(ClassDeclarationSyntax classNode, AbstractionModel model) { try { var parser = new CodeParser() { AccessLevel = "public" }; var fields = parser .FilterByAccessLevel(parser.GetFields(classNode), accessLevel: "public") .Select(p => (p as FieldDeclarationSyntax).Declaration); foreach (var field in fields) { var fieldName = field.Variables.First().Identifier.ToString(); var fieldValue = field.Variables.First().Initializer?.Value.ToString() ?? "default"; var type = field.Type.ToString(); model.AddField(fieldName, fieldValue, type); if (field.HasLeadingTrivia) { var parsedDocumentation = GetDocumentation(field); model.AddDocumentation(fieldName, parsedDocumentation); } } } catch (Exception e) { Logging.Log($"Failed to set fields in AbstractionModelManager.\nError: {e}"); } }
public void SetDocumentation(ClassDeclarationSyntax classNode, AbstractionModel model) { try { var documentation = GetDocumentation(classNode); // Get port documentation var portDocs = new Dictionary <string, string>(); var lines = documentation.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var candidate = line.Trim(); if (Regex.IsMatch(candidate, @"^[0-9]")) { var inv = InverseStringFormat.GetInverseStringFormat(candidate, @"{portIndex}. {portType} {portName}: {portDescription}"); if (inv.ContainsKey("portName") && inv.ContainsKey("portDescription") && !string.IsNullOrEmpty(inv["portName"]) && !string.IsNullOrEmpty(inv["portDescription"])) { var port = model.GetPort(inv["portName"].Trim(' ', '\"', '\'')); if (port != null) { port.Description = inv["portDescription"].Trim(); } } } } model.AddDocumentation(documentation); } catch (Exception e) { Logging.Log($"Failed to set documentation in AbstractionModelManager.\nError: {e}"); } }
private static void RebuildAbstractionModel(AbstractionModel model) { if (model != null && !model.IsDeleted) { FrameworkDomainModel.DelayValidateElement(model, RebuildForAbstractionModelDelayed); } }
/// <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> /// ChangeRule: typeof(ORMSolutions.ORMArchitect.Core.ObjectModel.ORMModel) /// Synchronize the <see cref="P:AbstractionModel.Name">name</see> of the <see cref="AbstractionModel"/> /// with the <see cref="P:ORMModel.Name">name</see> of the <see cref="ORMModel"/> /// </summary> private static void ORMModelChangedRule(ElementPropertyChangedEventArgs e) { if (e.DomainProperty.Id == ORMModel.NameDomainPropertyId) { ORMModel model = (ORMModel)e.ModelElement; AbstractionModel abstractionModel = AbstractionModelIsForORMModel.GetAbstractionModel(model); if (abstractionModel != null) { abstractionModel.Name = model.Name; } } }
private static void FullyGenerateBarkerERModel(BarkerErModel barkerModel, AbstractionModel sourceModel, INotifyElementAdded notifyAdded) { LinkedElementCollection <EntityType> barkerEntities = barkerModel.EntityTypeCollection; LinkedElementCollection <ConceptType> conceptTypes = sourceModel.ConceptTypeCollection; Store store = barkerModel.Store; // Generate all Barker entities List <ConceptType> manyToMany = new List <ConceptType>(); foreach (ConceptType conceptType in conceptTypes) { if (!IsSimpleManyToManyAssociation(conceptType)) { EntityType entity = new EntityType( conceptType.Store, new PropertyAssignment[] { new PropertyAssignment(EntityType.NameDomainPropertyId, conceptType.Name) }); new EntityTypeIsPrimarilyForConceptType(entity, conceptType); barkerEntities.Add(entity); if (notifyAdded != null) { notifyAdded.ElementAdded(entity, true); } } else { manyToMany.Add(conceptType); } } // For every concept type create all attributes that they represent, map uniquenesses that they participate in. int associationCounter = 0; foreach (ConceptType conceptType in conceptTypes) { if (!manyToMany.Contains(conceptType)) { CreateAttributesAndBinaryRelationships(conceptType, notifyAdded, ref associationCounter); } else { CreateBinaryAssociation(conceptType, notifyAdded, ref associationCounter); } } // For each entity type in the Barker model generate relationships it plays and detemine which of its atrributes are mandatory and nullable. foreach (EntityType entity in barkerModel.EntityTypeCollection) { GenerateMandatoryConstraints(entity); } }
public AbstractionModel CreateDummyAbstractionModel(string type) { var model = new AbstractionModel() { Type = type, Name = "" }; model.AddImplementedPort("Port", "input"); model.AddAcceptedPort("Port", "output"); return(model); }
/// <summary> /// ChangeRule: typeof(ORMSolutions.ORMArchitect.ORMAbstraction.AbstractionModel) /// Update the schema name when the abstraction model name changes /// </summary> private static void AbstractionModelChangedRule(ElementPropertyChangedEventArgs e) { if (e.DomainProperty.Id == AbstractionModel.NameDomainPropertyId) { AbstractionModel abstractionModel = (AbstractionModel)e.ModelElement; Schema schema = SchemaIsForAbstractionModel.GetSchema(abstractionModel); if (schema != null && !schema.CustomName) { schema.Name = abstractionModel.Name; } } }
private static void RebuildForAbstractionModelDelayed(ModelElement element) { if (!element.IsDeleted) { AbstractionModel model = (AbstractionModel)element; BarkerErModel barkerModel = BarkerErModelIsForAbstractionModel.GetBarkerErModel(model); if (barkerModel != null) { barkerModel.BinaryAssociationCollection.Clear(); barkerModel.EntityTypeCollection.Clear(); barkerModel.ExclusiveArcCollection.Clear(); FullyGenerateBarkerERModel(barkerModel, model, null); } } }
public void SetType(ClassDeclarationSyntax classNode, AbstractionModel model) { var identifier = classNode.Identifier.ToString(); var type = identifier; model.Type = type; model.FullType = model.Type; // Generics if (classNode.TypeParameterList != null) { model.FullType += classNode.TypeParameterList.ToString(); var generics = classNode.TypeParameterList.Parameters; model.SetGenerics(generics.Select(s => s.ToString())); } }
private static void RebuildForAbstractionModelDelayed(ModelElement element) { if (!element.IsDeleted) { AbstractionModel model = (AbstractionModel)element; Schema schema = SchemaIsForAbstractionModel.GetSchema(model); if (schema != null) { // Clear any customizations to stop rules and events from modifying // the customizations during rebuild. SchemaCustomization initialCustomization = SchemaCustomization.SetCustomization(schema, null); schema.TableCollection.Clear(); schema.DomainCollection.Clear(); FullyGenerateConceptualDatabaseModel(schema, model, initialCustomization, null); SchemaCustomization.SetCustomization(schema, new SchemaCustomization(schema)); } } }
public AbstractionModel CreateAbstractionModel(string code, string path = "") { var model = new AbstractionModel(); model.SourceCode = code; model.CodeFilePath = path; var parser = new CodeParser(); var classNode = parser.GetClasses(code).First() as ClassDeclarationSyntax; SetType(classNode, model); SetImplementedPorts(classNode, model); SetAcceptedPorts(classNode, model); SetProperties(classNode, model); SetFields(classNode, model); SetConstructorArgs(classNode, model); SetDocumentation(classNode, model); _abstractionModels[model.Type] = model; return(model); }
public void SetProperties(ClassDeclarationSyntax classNode, AbstractionModel model) { try { var parser = new CodeParser() { AccessLevel = "public" }; var properties = parser .FilterByAccessLevel(parser.GetProperties(classNode), accessLevel: "public") .Select(p => (p as PropertyDeclarationSyntax)); foreach (var property in properties) { if (property == null) { continue; } var propertyName = property.Identifier.ValueText; model.AddProperty(propertyName, property.Initializer?.Value.ToString() ?? "default", type: property.Type.ToString()); if (property.HasLeadingTrivia) { var parsedDocumentation = GetDocumentation(property); model.AddDocumentation(propertyName, parsedDocumentation); } } } catch (Exception e) { Logging.Log($"Failed to set properties in AbstractionModelManager.\nError: {e}"); } }
public void SetConstructorArgs(ClassDeclarationSyntax classNode, AbstractionModel model) { try { var parser = new CodeParser(); var ctor = parser.GetConstructors(classNode).FirstOrDefault() as ConstructorDeclarationSyntax; if (ctor == null) { return; } var ctorArgs = ctor.ParameterList.Parameters; foreach (var arg in ctorArgs) { model.AddConstructorArg(arg.Identifier.ToString(), arg.Default?.Value.ToString() ?? "default", type: arg.Type.ToString()); } } catch (Exception e) { Logging.Log($"Failed to set constructor args in AbstractionModelManager.\nError: {e}"); } }
/// <summary> /// Initiate a model rebuild if a rebuild is not already under way /// </summary> /// <param name="model">The <see cref="AbstractionModel"/> to check for rebuilding</param> /// <returns><see langword="true"/> if the requested rebuild will occur.</returns> private static bool TestRebuildAbstractionModel(AbstractionModel model) { if (model == null) { return false; } AbstractionModelIsForORMModel link = AbstractionModelIsForORMModel.GetLinkToORMModel(model); bool allow = !(link != null && link.myRebuildingAbstractionModel); if (allow) { FrameworkDomainModel.DelayValidateElement(link.ORMModel, DelayValidateModel); } return allow; }
private static void DelayValidateModel(ModelElement element) { Dictionary<object, object> contextDictionary = element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo; if (contextDictionary.ContainsKey(Key)) { // Get the elements affected within the transaction Dictionary<ModelElement, int> elementList = (Dictionary<ModelElement, int>)contextDictionary[Key]; // Elements that were both added & deleted in the transaction can be ignored for map change analysis EliminateRedundantElements(elementList); // TODO: scan for changes that actually affect the model; all others can be filtered out if (elementList.Count == 0) { return; } } ORMModel model = (ORMModel)element; Store store = model.Store; // Get the link from the given ORMModel AbstractionModelIsForORMModel oialModelIsForORMModel = AbstractionModelIsForORMModel.GetLinkToAbstractionModel(model); AbstractionModel oialModel = null; // If the link exists, clear it out. There is no need to recreate it completely. if (oialModelIsForORMModel != null) { // Make sure the RebuildingAbstractionModel returns true during the rebuild oialModelIsForORMModel.myRebuildingAbstractionModel = true; try { oialModel = oialModelIsForORMModel.AbstractionModel; oialModel.ConceptTypeCollection.Clear(); oialModel.InformationTypeFormatCollection.Clear(); ReadOnlyCollection<FactTypeMapsTowardsRole> factTypeMaps = store.ElementDirectory.FindElements<FactTypeMapsTowardsRole>(false); int factTypeMapCount = factTypeMaps.Count; for (int i = factTypeMapCount - 1; i >= 0; --i) { FactTypeMapsTowardsRole factTypeMap = factTypeMaps[i]; if (factTypeMap.FactType.Model == model) { factTypeMap.Delete(); } } // Apply ORM to OIAL algorithm oialModelIsForORMModel.TransformORMtoOial(); } finally { oialModelIsForORMModel.myRebuildingAbstractionModel = false; } } else { oialModel = new AbstractionModel( store, new PropertyAssignment(AbstractionModel.NameDomainPropertyId, model.Name)); oialModelIsForORMModel = new AbstractionModelIsForORMModel(oialModel, model); // Set initial object exclusion states ORMElementGateway.Initialize(model, null); // Apply ORM to OIAL algorithm oialModelIsForORMModel.TransformORMtoOial(); } if (oialModel != null) { AbstractionModelGenerationSetting generationSetting = GenerationSettingTargetsAbstractionModel.GetGenerationSetting(oialModel); if (generationSetting == null) { generationSetting = new AbstractionModelGenerationSetting(store, new PropertyAssignment(AbstractionModelGenerationSetting.AlgorithmVersionDomainPropertyId, CurrentAlgorithmVersion)); new GenerationSettingTargetsAbstractionModel(generationSetting, oialModel); new GenerationStateHasGenerationSetting(GenerationState.EnsureGenerationState(store), generationSetting); } else { generationSetting.AlgorithmVersion = CurrentAlgorithmVersion; } } }
public void SetAcceptedPorts(ClassDeclarationSyntax classNode, AbstractionModel model) { SetPorts(classNode, model, isInputPort: false); }
private void SetPorts(ClassDeclarationSyntax classNode, AbstractionModel model, bool isInputPort = false) { try { if (isInputPort) { var parser = new CodeParser(); var baseList = (parser.GetBaseObjects(classNode)); var portNodeList = (baseList.First() as BaseListSyntax)?.Types.ToList(); if (portNodeList == null) { return; } var portSyntaxNodes = portNodeList.Where(n => MatchStartOfString(n.ToString(), ProgrammingParadigms)); var docLines = model.SourceCode.Split(new [] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var classDeclaration = docLines.First(line => line.Trim().Contains($"class {model.Type}")); var implementedPortNames = new List <string>(); if (classDeclaration.Contains("//")) { // Get implemented port names // string implementedPortsInlineComment = baseList.LastOrDefault()?.GetTrailingTrivia().ToString().Trim(new []{' ', '/', '\r', '\n'}) ?? ""; var implementedPortsInlineComment = classDeclaration.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault(); if (!string.IsNullOrEmpty(implementedPortsInlineComment)) { implementedPortNames = implementedPortsInlineComment.Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList(); } } var modelGenerics = model.GetGenerics(); var implementedPortCount = 0; foreach (var portSyntaxNode in portSyntaxNodes) { var port = new Port() { Type = portSyntaxNode.Type.ToString() }; if (implementedPortCount < implementedPortNames.Count) { port.Name = implementedPortNames[implementedPortCount]; } else { port.Name = "?" + port.Type; } // Handle reverse ports (e.g. IDataFlowB and IEventB) // var typeWithoutGenerics = TypeWithoutGenerics(port.Type); // port.IsReversePort = typeWithoutGenerics.EndsWith("B"); port.IsReversePort = IsReversePort(port.Type); if (port.IsReversePort) { port.IsInputPort = false; model.AddAcceptedPort(port.Type, port.Name, true); } else { port.IsInputPort = true; model.AddImplementedPort(port.Type, port.Name); } var indexList = new List <int>(); if (portSyntaxNode.Type is GenericNameSyntax gen) { var portGenerics = gen .DescendantNodesAndSelf().OfType <GenericNameSyntax>() .SelectMany(n => n.TypeArgumentList.Arguments.Select(a => a.ToString())) .ToHashSet(); foreach (var portGeneric in portGenerics) { var index = modelGenerics.IndexOf(portGeneric); if (index != -1) { indexList.Add(index); } } } model.AddPortGenericIndices(port.Name, indexList); implementedPortCount++; } } else { var parser = new CodeParser() { AccessLevel = "private" }; var privateFields = parser.GetFields(classNode); var portSyntaxNodes = privateFields.Where(n => n is FieldDeclarationSyntax field && (MatchStartOfString(field.Declaration.Type.ToString(), ProgrammingParadigms) || MatchStartOfString(field.Declaration.Type.ToString(), ProgrammingParadigms, prefix: "List<"))) .Select(s => s as FieldDeclarationSyntax); var modelGenerics = model.GetGenerics(); foreach (var portSyntaxNode in portSyntaxNodes) { var port = new Port() { Type = portSyntaxNode.Declaration.Type.ToString(), Name = portSyntaxNode.Declaration.Variables.First().Identifier.ToString(), }; port.Description = portSyntaxNode.HasLeadingTrivia ? ParsePortDocumentation(portSyntaxNode.GetLeadingTrivia().ToString()) : ""; // Handle reverse ports (e.g. IDataFlowB and IEventB) // var typeWithoutGenerics = TypeWithoutGenerics(port.Type); // port.IsReversePort = typeWithoutGenerics.EndsWith("B"); port.IsReversePort = IsReversePort(port.Type); if (port.IsReversePort) { port.IsInputPort = true; model.AddImplementedPort(port.Type, port.Name, isReversePort: true, description: port.Description); } else { port.IsInputPort = false; model.AddAcceptedPort(port.Type, port.Name, description: port.Description); } var indexList = new List <int>(); if (portSyntaxNode.Declaration.Type is GenericNameSyntax gen) { var portGenerics = gen .DescendantNodesAndSelf().OfType <GenericNameSyntax>() .SelectMany(n => n.TypeArgumentList.Arguments.Select(a => a.ToString()).Where(a => modelGenerics.Contains(a))) .ToHashSet(); foreach (var portGeneric in portGenerics) { var index = modelGenerics.IndexOf(portGeneric); if (index != -1) { indexList.Add(index); } } } model.AddPortGenericIndices(port.Name, indexList); } } } catch (Exception e) { Logging.Log($"Failed to set {(isInputPort ? "implemented" : "accepted")} ports in AbstractionModelManager.\nError: {e}"); } }
private static void ExcludeObjectType(ObjectType objectType, AbstractionModel model, bool forceCreate, NotifyORMElementExcluded notifyExcluded) { if (forceCreate || null == ExcludedORMModelElement.GetAbstractionModel(objectType)) { new ExcludedORMModelElement(objectType, model); if (notifyExcluded != null) { notifyExcluded(objectType); } // Excluding an object type leaves a FactType with a null role player, // so the associated fact types also need to be excluded. foreach (Role playedRole in objectType.PlayedRoleCollection) { ExcludeFactType(playedRole.FactType, model, false, notifyExcluded); RoleProxy proxy = playedRole.Proxy; if (proxy != null) { ExcludeFactType(proxy.FactType, model, false, notifyExcluded); } } if (!objectType.IsValueType) { // Excluding an object type can leave a downstream subtype without an // identifier, so exclude those as well. Note we only go one level deep // as this will recurse naturally on the next level. ObjectType.WalkSubtypes(objectType, delegate(ObjectType type, int depth, bool isPrimary) { switch (depth) { case 0: return ObjectTypeVisitorResult.Continue; case 1: if (isPrimary) { if (type.PreferredIdentifier == null) { ExcludeObjectType(type, model, false, notifyExcluded); } } return ObjectTypeVisitorResult.SkipChildren; default: return ObjectTypeVisitorResult.Stop; } }); } } }
private static void ExcludeFactType(FactType factType, AbstractionModel model, bool forceCreate, NotifyORMElementExcluded notifyExcluded) { if (forceCreate || null == ExcludedORMModelElement.GetAbstractionModel(factType)) { if (null == factType.Objectification || factType.UnaryRole != null) { new ExcludedORMModelElement(factType, model); } if (notifyExcluded != null) { notifyExcluded(factType); } foreach (IFactConstraint constraint in factType.FactConstraintCollection) { ObjectType preferredFor = constraint.Constraint.PreferredIdentifierFor; if (preferredFor != null) { ExcludeObjectType(preferredFor, model, false, notifyExcluded); } } Objectification objectification; if (null != (objectification = factType.ImpliedByObjectification)) { ExcludeObjectType(objectification.NestingType, model, false, notifyExcluded); } } }
public void SetImplementedPorts(ClassDeclarationSyntax classNode, AbstractionModel model) { SetPorts(classNode, model, isInputPort: true); }