Skip to content

Commit

Permalink
Merge branch 'main' into chore_removeOptimize
Browse files Browse the repository at this point in the history
  • Loading branch information
PayalKhanna authored Feb 4, 2025
2 parents b427bc6 + 61c5ad4 commit ccf45d4
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package com.regnosys.rosetta.generator.java.function;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Map;

import javax.inject.Inject;

import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.extensions.InjectionExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import com.regnosys.rosetta.generator.java.RosettaJavaPackages;
import com.regnosys.rosetta.tests.RosettaTestInjectorProvider;
import com.regnosys.rosetta.tests.util.CodeGeneratorTestHelper;
Expand All @@ -8,16 +19,6 @@
import com.rosetta.model.lib.meta.Reference;
import com.rosetta.model.lib.meta.ReferenceWithMeta;
import com.rosetta.model.metafields.MetaFields;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.extensions.InjectionExtension;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import javax.inject.Inject;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

@ExtendWith(InjectionExtension.class)
@InjectWith(RosettaTestInjectorProvider.class)
Expand Down Expand Up @@ -185,12 +186,9 @@ result string (1..1)
assertEquals(expected, result);
}


@Disabled //TODO: is this syntax needed? if so we need to find a way to get key as a feature from a Data type
@Test
void canSetExternalKeyOnFunctionObjectOutput() {
var model = """
metaType key string
metaType reference string
Expand All @@ -204,10 +202,25 @@ myReference string (1..1)
output:
result Foo (1..1)
set result -> a: "someA"
set result -> key: myReference
""";

var code = generatorTestHelper.generateCode(model);

generatorTestHelper.writeClasses(code, "canSetExternalKeyOnFunctionObjectOutput");

var classes = generatorTestHelper.compileToClasses(code);
var myFunc = functionGeneratorHelper.createFunc(classes, "MyFunc");

var result = functionGeneratorHelper.invokeFunc(myFunc, RosettaModelObject.class, "someExternalReference");

var expected = generatorTestHelper.createInstanceUsingBuilder(classes, new RosettaJavaPackages.RootPackage("com.rosetta.test.model"), "Foo", Map.of(
"a", "someA",
"meta", MetaFields.builder().setExternalKey("someExternalReference")
));

assertEquals(expected, result);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.util.EcoreUtil
import com.regnosys.rosetta.rosetta.simple.Annotated
import java.util.function.Predicate
import com.regnosys.rosetta.types.RMetaAttribute

@Singleton // see `metaFieldsCache`
class RosettaEcoreUtil {
Expand Down Expand Up @@ -80,6 +81,30 @@ class RosettaEcoreUtil {
}
}

/*
* This method is resolving references during scoping which is not an advised approach.
* It could lead to poor performance as it is possible that it could be called upon to
* resolve across multiple files. For now this is acceptable as in reality it's not going
* going to get called to run across multiple files.
*
* TODO: find an alternative approach to this.
*
*/
def List<RosettaFeature> getMetaDescriptions(List<RMetaAttribute> metaAttributes, EObject context) {
val metas = metaAttributes.map[it.name].toList
if (!metas.isEmpty) {
configs.findMetaTypes(context).filter[
metas.contains(it.name.lastSegment.toString)
]
.map[it.EObjectOrProxy]
.map[EcoreUtil.resolve(it, context)]
.filter(RosettaFeature)
.toList
} else {
emptyList
}
}

@Deprecated // Use RDataType#getAllSuperTypes instead
def List<Data> getAllSuperTypes(Data data) {
val reversedResult = newLinkedHashSet
Expand Down Expand Up @@ -243,28 +268,8 @@ class RosettaEcoreUtil {
return '''«containerName»«name»'''
}

/*
* This method is resolving references during scoping which is not an advised approach.
* It could lead to poor performance as it is possible that it could be called upon to
* resolve across multiple files. For now this is acceptable as in reality it's not going
* going to get called to run across multiple files.
*
* TODO: find an alternative approach to this.
*
*/
private def List<RosettaFeature> getMetaDescriptions(RMetaAnnotatedType type, EObject context) {
val metas = type.metaAttributes.map[it.name].toList
if (!metas.isEmpty) {
configs.findMetaTypes(context).filter[
metas.contains(it.name.lastSegment.toString)
]
.map[it.EObjectOrProxy]
.map[EcoreUtil.resolve(it, context)]
.filter(RosettaFeature)
.toList
} else {
emptyList
}
type.metaAttributes.getMetaDescriptions(context)
}

@Deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ import static com.regnosys.rosetta.generator.java.util.ModelGeneratorUtil.*

import static extension com.regnosys.rosetta.types.RMetaAnnotatedType.withNoMeta
import com.regnosys.rosetta.generator.java.types.RJavaReferenceWithMeta
import com.regnosys.rosetta.types.RDataType
import com.regnosys.rosetta.generator.java.types.RJavaPojoInterface

class FunctionGenerator {

Expand Down Expand Up @@ -496,7 +498,7 @@ class FunctionGenerator {
}

private def String getPropertySetterName(JavaType outputExpressionType, JavaPojoProperty prop, RFeature segment) {
if (outputExpressionType instanceof RJavaWithMetaValue) {
if (outputExpressionType instanceof RJavaWithMetaValue || (segment instanceof RMetaAttribute && outputExpressionType instanceof RJavaPojoInterface)) {
segment.toPojoPropertyNames.toFirstUpper
} else {
prop.name.toFirstUpper
Expand All @@ -520,17 +522,18 @@ class FunctionGenerator {
RJavaFieldWithMeta: '''«IF seg instanceof RMetaAttribute».getOrCreateMeta()«ELSE».«prop.getOrCreateName»()«ENDIF»'''
RJavaReferenceWithMeta case seg instanceof RMetaAttribute && seg.name == "address": '''.«prop.getOrCreateName»()'''
RJavaReferenceWithMeta case !(seg instanceof RMetaAttribute): '''.getOrCreateValue()'''
RJavaPojoInterface case seg instanceof RMetaAttribute: '''.«prop.getOrCreateName»()'''
default: ''''''
}
}

//The type of the output expression to be set and the pojo property type are not the same when working with meta
private def JavaPojoProperty getPojoProperty(RFeature seg, JavaType outputExpressionType) {
if (seg instanceof RMetaAttribute && outputExpressionType.itemType instanceof RJavaFieldWithMeta) {
if (seg instanceof RMetaAttribute && (outputExpressionType instanceof RJavaFieldWithMeta || outputExpressionType instanceof RJavaPojoInterface)) {
(outputExpressionType as JavaPojoInterface).findProperty("meta")
} else if (seg instanceof RMetaAttribute && outputExpressionType.itemType instanceof RJavaReferenceWithMeta) {
} else if (seg instanceof RMetaAttribute && outputExpressionType instanceof RJavaReferenceWithMeta) {
(outputExpressionType as JavaPojoInterface).findProperty("reference")
} else if (outputExpressionType.itemType instanceof RJavaWithMetaValue) {
} else if (outputExpressionType instanceof RJavaWithMetaValue) {
(outputExpressionType as JavaPojoInterface).findProperty("value")
} else {
(outputExpressionType as JavaPojoInterface).findProperty(seg.name)
Expand All @@ -541,6 +544,7 @@ class FunctionGenerator {
return switch(seg.name) {
case "reference": "externalReference"
case "id": "externalKey"
case "key": "externalKey"
case "address": "reference"
default: seg.name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ import static extension com.regnosys.rosetta.types.RMetaAnnotatedType.withNoMeta
import com.regnosys.rosetta.rosetta.simple.Attribute
import com.regnosys.rosetta.rosetta.simple.AnnotationPath
import com.regnosys.rosetta.rosetta.simple.AnnotationDeepPath
import java.util.Random
import com.regnosys.rosetta.types.RAttribute

/**
* This class contains custom scoping description.
Expand Down Expand Up @@ -146,7 +148,16 @@ class RosettaScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
// Case handles the head of the segment
Operation: {
val receiverType = typeProvider.getRTypeOfSymbol(context.assignRoot)
return Scopes.scopeFor(receiverType.allFeatures(context, [t| !(t instanceof REnumType)]))

// All features accessible from reciever type including meta attributes
var features = receiverType.allFeatures(context, [t| !(t instanceof REnumType)])

// We also want to allow the scope provider to return the meta for type of the attribute (e.g. metatda key)
if (receiverType.RType instanceof RDataType) {
features = features + (receiverType.RType as RDataType).metaAttributes.getMetaDescriptions(context)
}

return Scopes.scopeFor(features)
}
// Case handles the tail of the segment
Segment: {
Expand Down

0 comments on commit ccf45d4

Please sign in to comment.