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

core_analytics_class.modelCoverage.analytics.pure Maven / Gradle / Ivy

There is a newer version: 4.57.1
Show newest version
// Copyright 2023 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::analytics::class::modelCoverage::utility::*;
import meta::analytics::class::modelCoverage::*;
import meta::pure::milestoning::*;

Class meta::analytics::class::modelCoverage::ClassModelCoverageAnalysisResult
{
  classes: Class[*];
  enumerations: Enumeration[*];
  associations: Association[*];
  profiles: Profile[*];
}

function meta::analytics::class::modelCoverage::getClassModelCoverage(_classes: Class[*]):ClassModelCoverageAnalysisResult[1]
{
  // superTypes
  let superClasses = $_classes->map(c | $c->superTypes());
  let classes = $_classes->concatenate($superClasses);

  // 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 = []
    ))
  ));

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

  // Remove duplicate classes.
  let prunedClassPaths = $prunedClasses->map(c | $c->elementToPath());
  let prunedStubClasses = $prunedAssociationClasses->concatenate($prunedPropertyClasses)
                                                    ->removeDuplicates()->filter(c | !$prunedClassPaths->contains($c->elementToPath()));
  let coveredClasses = $prunedClasses->concatenate($prunedStubClasses);

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

  ^ClassModelCoverageAnalysisResult
  (
    classes = $coveredClasses,
    profiles = $prunedProfiles,
    enumerations = $prunedEnumerations,
    associations = $prunedAssociations
  );
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy