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

core.pure.treepath.treePath.pure Maven / Gradle / Ivy

There is a newer version: 4.57.1
Show newest version
// Copyright 2020 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::treepath::*;

Class meta::pure::metamodel::treepath::PropertyPathTreeNode extends meta::pure::functions::collection::TreeNode{
   property : AbstractProperty[0..1];
   
   children(){
      $this.childrenData->cast(@PropertyPathTreeNode)
   }:PropertyPathTreeNode[*];
}

function meta::pure::metamodel::treepath::buildPropertyPathTree(dfts:LambdaFunction<{T[1]->Any[*]}>[*]):PropertyPathTreeNode[1]
{
   let threads = $dfts->map(dft|^PropertyPathTreeNode(childrenData=$dft.expressionSequence->at(0)->buildPropertyPath([])));
   $threads->mergePropertyPaths();
}

function meta::pure::metamodel::treepath::tp_removeAutomap(v:ValueSpecification[1]):ValueSpecification[1]
{
   $v->match([fe:FunctionExpression[1] | if($fe.functionName=='map',| let left = $fe.parametersValues->at(0);
                                                                      let prop = $fe.parametersValues->at(1)->cast(@InstanceValue).values->at(0)->cast(@LambdaFunction).expressionSequence->at(0)->cast(@FunctionExpression);
                                                                      let leftUnMapped = $left->tp_removeAutomap();
                                                                      ^$prop(parametersValues=$leftUnMapped);
                                                                   ,| $fe);,
               v:ValueSpecification[1] |  $v]);
}

function <> meta::pure::metamodel::treepath::buildPropertyPath(vs:ValueSpecification[1], child:PropertyPathTreeNode[0..1]):PropertyPathTreeNode[1]
{
   $vs->evaluateAndDeactivate()
      ->match([ r:RoutedValueSpecification[1] | $r.value->buildPropertyPath($child),
                v:VariableExpression[1]  | if($child->isNotEmpty(),|$child->toOne(),|assert(false,'Unsupported Deep Fetch Path');^PropertyPathTreeNode();),
                fe:FunctionExpression[1] | let unMappedFe = $fe->tp_removeAutomap()->cast(@FunctionExpression);
                                           let property = $unMappedFe.func->cast(@AbstractProperty);
                                           let parent = ^PropertyPathTreeNode(property=$property, childrenData=$child);
                                           $unMappedFe.parametersValues->map(p|$p->buildPropertyPath($parent))->toOne();
             ]);
}

function <> meta::pure::metamodel::treepath::mergePropertyPaths(roots:PropertyPathTreeNode[*]):PropertyPathTreeNode[1]
{
   let distinctTypes = $roots.property->type()->distinct();
   assert($distinctTypes->size()==1,| 'Deep fetch Property paths should be of the same Type: '+$distinctTypes.name->makeString());
   let mergedPaths = $roots.children()->fold({n, a| $a->mergeChildPropertyPathTreeNodes($n)}, []->cast(@PropertyPathTreeNode)); 
   ^PropertyPathTreeNode(childrenData=$mergedPaths);
}

function <> meta::pure::metamodel::treepath::mergeChildPropertyPathTreeNodes(dfns:PropertyPathTreeNode[*], n:PropertyPathTreeNode[1]):PropertyPathTreeNode[*]
{  let mergeNode = $dfns->filter(d|$d.property == $n.property);
   if( $mergeNode->isEmpty(),|$dfns->concatenate($n);
                            ,|assert($mergeNode->size() == 1,'Deep fetch tree merging found more than one merge compatible deep fetch nodes');
                              let oneMergeNode = $mergeNode->at(0);
                              let mergedChildren = $mergeNode.children()->concatenate($n.children())->fold({n, a| $a->mergeChildPropertyPathTreeNodes($n) }, []->cast(@PropertyPathTreeNode));
                              let mergeNodeWithMergedChildren = ^$oneMergeNode(childrenData=$mergedChildren);
                              $dfns->filter(n|$n != $oneMergeNode)->concatenate($mergeNodeWithMergedChildren);
                            );
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy