All Downloads are FREE. Search and download functionalities are using the official Maven repository.

core_diagram.analytics.analytics.pure Maven / Gradle / Ivy

There is a newer version: 4.66.0
Show newest version
// Copyright 2022 Goldman Sachs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import meta::pure::metamodel::diagram::analytics::modelCoverage::*;
import meta::pure::milestoning::*;

Class meta::pure::metamodel::diagram::analytics::modelCoverage::DiagramModelCoverageAnalysisResult
{
  classes: Class[*];
  enumerations: Enumeration[*];
  associations: Association[*];
  profiles: Profile[*];
}

function meta::pure::metamodel::diagram::analytics::modelCoverage::getDiagramModelCoverage(diagrams: meta::pure::metamodel::diagram::Diagram[*]):DiagramModelCoverageAnalysisResult[1]
{
  let classViews = $diagrams->map(d|$d.classViews)->fold({a, b| $a->concatenate($b)}, []);
  let generalizationViews = $diagrams->map(d|$d.generalizationViews)->fold({a, b| $a->concatenate($b)}, []);
  let classes = $classViews.class->filter(t|$t->instanceOf(Class))->cast(@Class)->removeDuplicates();

  // associations
  let allPropertiesFromAssociations = $classes.propertiesFromAssociations;
  let allQualifiedPropertiesFromAssociations = $classes.qualifiedPropertiesFromAssociations;
  let associations = $allPropertiesFromAssociations.owner->filter(t|$t->instanceOf(Association))->cast(@Association)->removeDuplicates();
  let associationClasses = $associations.properties->map(p|$p.genericType.rawType)
    ->filter(t|$t->instanceOf(Class))->cast(@Class)->removeDuplicates()->filter(c|!$classes->contains($c));
  
  // properties
  let allProperties = $classes.properties;
  let allQualifiedProperties = $classes.qualifiedProperties;
  let foundClasses = $classes->concatenate($associationClasses);
  let propertyTypes = $allProperties->map(p|$p.genericType.rawType)->concatenate($allQualifiedProperties->map(p|$p.genericType.rawType));
  let propertyClasses = $propertyTypes->filter(t|$t->instanceOf(Class))->cast(@Class)->removeDuplicates()->filter(c|!$foundClasses->contains($c));

  // enumerations
  let enumerations = $propertyTypes->filter(t|$t->instanceOf(Enumeration))->cast(@Enumeration)->removeDuplicates();
  
  // NOTE: following, we prune the tagged values and stereotypes from the enumerations, associations, and classes
  // so we don't have to return them, if in the future, we need to return these (as this analytics require to do so)
  // we should reconsider these optimization
  let prunedEnumerations = $enumerations->map(e|^$e(
    stereotypes = [],
    taggedValues = [],
    values = meta::pure::functions::meta::enumValues($e)->map(v|^$v(
      stereotypes = [],
      taggedValues = []
    ))->toOneMany() // this is a hack to work around a problem with validation on size of enumeration values
  ));

  let prunedClasses = $classes->map(c|^$c(
    properties = $c.properties->reverseMilestoningTransforms()->map(p|^$p(
      stereotypes = [],
      taggedValues = []
    )),
    qualifiedProperties = $c.qualifiedProperties->reverseMilestoningTransforms()->cast(@QualifiedProperty)->map(p|^$p(
      stereotypes = [],
      taggedValues = []
    )),
    // skip supertype/generalization relationship that is not shown in the diagrams
    generalizations = $c.generalizations->filter(g|$generalizationViews->exists(gV|$gV.from.classView.class == $c && $gV.to.classView.class == $g.general.rawType))
  ));

  // NOTE: for classes found from association and properties only, we just need to stub them
  let prunedPropertyClasses = $propertyClasses->map(c|^Class(
    name = $c.name,
    package = $c.package
  ));
  let prunedAssociationClasses = $associationClasses->map(c|^Class(
    name = $c.name,
    package = $c.package
  ));

  // NOTE: prune here so we don't have to do analytics to find the used profiles
  let prunedAssociations = $associations->map(a|
    let props = $a.properties->reverseMilestoningTransforms()->cast(@Property)->map(p|^$p(
      stereotypes = [],
      taggedValues = []
    ));
    let newProps = [$props->at(0), $props->at(1)];
    ^$a(
      stereotypes = [],
      taggedValues = [],
      properties = $newProps,
      qualifiedProperties = $a.qualifiedProperties->reverseMilestoningTransforms()->cast(@QualifiedProperty)->map(p|^$p(
        stereotypes = [],
        taggedValues = []
      ))
    );
  );

  // profile
  // NOTE: we don't support showing tagged values and stereotypes for properties at the moment
  let profiles = $classes->map(class|$class.taggedValues->map(tv|$tv.tag.profile)
    ->concatenate($class.stereotypes->map(st|$st.profile))
    ->cast(@Profile)->removeDuplicates());
  
  // TODO?: prune profile - e.g. we can prune profile to limit to used tags and stereotypes only
  let prunedProfiles = $profiles->map(p|^Profile(
    name = $p.name,
    package = $p.package,
    p_tags = $p.p_tags,
    p_stereotypes = $p.p_stereotypes
  ));

  ^DiagramModelCoverageAnalysisResult
  (
    classes = $prunedClasses->concatenate($prunedPropertyClasses)->concatenate($prunedAssociationClasses),
    profiles = $prunedProfiles,
    enumerations = $prunedEnumerations,
    associations = $prunedAssociations
  );
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy