/// <summary> /// Gets the pattern implementations. /// </summary> /// <param name="pattern">The pattern.</param> /// <param name="componentMatches">The component matches.</param> /// <returns>A list of pattern implementations that need to be checked on completeness</returns> private List <Dictionary <Component, List <ComponentMatch> > > GetPatternImplementations(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > componentMatches) { this.possibleImplementations = new List <Dictionary <Component, List <ComponentMatch> > >(); var singularComponentNames = graph.GetSingularComponentNames(); if (singularComponentNames.Count == 0) { // Todo. Not supported for v1. - Removed exception, just return null. return(null); } var startGraphComponent = graph.GetGraphComponent(singularComponentNames[0]); var startComponentMatches = componentMatches[startGraphComponent.Component]; foreach (var startComponentMatch in startComponentMatches) { this.possibleImplementations.Add(new Dictionary <Component, List <ComponentMatch> >() { { startGraphComponent.Component, new List <ComponentMatch>() { startComponentMatch } } }); } var foundComponents = new List <GraphComponent>() { startGraphComponent }; return(this.MapImplementations(graph, foundComponents, componentMatches)); }
/// <summary> /// Matches the component match types, with the implementations. /// </summary> /// <param name="graph">The graph.</param> /// <param name="possibleImplementation">The possible implementation.</param> private Dictionary <Component, List <ComponentMatch> > MatchImplementationComponentTypes(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > possibleImplementation) { var componentsToRemove = new List <Component>(); foreach (var componentToCheck in possibleImplementation) { var componentToCheckMatch = componentToCheck.Value[0]; var currentComponent = componentToCheck.Key; var currentGraphComponent = graph.GetGraphComponent(currentComponent.Name); var otherComponents = possibleImplementation.Where(i => i.Key != currentComponent); var otherGraphComponents = graph.GetGraphComponents(otherComponents.Select(c => c.Key.Name)); var currentComponentReferences = currentGraphComponent.References; var currentComponentReferencedBy = otherGraphComponents.Where(c => c.References.Any(r => r.ReferencedComponent == currentGraphComponent)); var typeMatch = true; foreach (var currentComponentReference in currentComponentReferences) { var knownParentTypes = this.GetSymbolInformation(possibleImplementation, currentComponentReference.ReferencedComponent.Component); typeMatch &= this.MatchUnknownChildWithKnownParent(componentToCheckMatch, knownParentTypes, currentComponentReference); } foreach (var referencedBy in currentComponentReferencedBy) { var knownChildTypes = this.GetSymbolInformation(possibleImplementation, referencedBy.Component); var reference = referencedBy.References.Single(r => r.ReferencedComponent == currentGraphComponent); typeMatch &= this.MatchKnownChildWithUnknownParent(knownChildTypes, componentToCheckMatch, reference); } // if there is no match, remove the first hit from the pattern. The pattern is incomplete. if (!typeMatch) { componentsToRemove.Add(currentGraphComponent.Component); } } foreach (var componentToRemove in componentsToRemove) { possibleImplementation.Remove(componentToRemove); } return(possibleImplementation); }
/// <summary> /// Matches the remaining component. /// </summary> /// <param name="graph">The graph.</param> /// <param name="remainingMatch">The remaining match.</param> /// <param name="foundComponents">The found components.</param> /// <returns>The component if it has been matched, null otherwise.</returns> private GraphComponent MatchRemainingComponent(PatternGraph graph, KeyValuePair <Component, List <ComponentMatch> > remainingMatch, List <GraphComponent> foundComponents) { var componentMatchFound = false; // check if the component inherits any found components var remainingMatchGraphComponent = graph.GetGraphComponent(remainingMatch.Key.Name); var foundComponentReferences = remainingMatchGraphComponent.References.Where(r => foundComponents.Contains(r.ReferencedComponent)); if (foundComponentReferences.Any()) { var componentRef = foundComponentReferences.First(); this.MatchComponentTypes(remainingMatchGraphComponent, componentRef.ReferencedComponent, componentRef, remainingMatch.Value, true); componentMatchFound = true; } else { // otherwise check if the component is inherited by any found components var referencedByFoundComponents = foundComponents.Where(c => c.References.Any(r => r.ReferencedComponent == remainingMatchGraphComponent)); if (referencedByFoundComponents.Any()) { var refByComponent = referencedByFoundComponents.First(); var refByComponentReference = refByComponent.References.Single(r => r.ReferencedComponent == remainingMatchGraphComponent); this.MatchComponentTypes(refByComponent, remainingMatchGraphComponent, refByComponentReference, remainingMatch.Value, false); componentMatchFound = true; } } if (componentMatchFound) { return(remainingMatchGraphComponent); } return(null); }