Skip to content

Commit

Permalink
allow references to be aggregated
Browse files Browse the repository at this point in the history
all unit-tests working - though perhaps there should be more functions generated to managed the aggregation in the instances.
  • Loading branch information
pahjbo committed Jun 18, 2024
1 parent 7345e90 commit 54258ab
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 35 deletions.
4 changes: 2 additions & 2 deletions models/sample/test/lifecycleTest.vo-dml.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<title></title>
<author>pharriso</author>
<version>0.1</version>
<lastModified>2024-05-16T19:27:45Z</lastModified>
<lastModified>2024-06-13T14:50:55Z</lastModified>
<import>
<name>null</name><!--should not be needed in modern vo-dml -->
<url>IVOA-v1.0.vo-dml.xml</url>
Expand Down Expand Up @@ -120,7 +120,7 @@
</datatype>
<multiplicity>
<minOccurs>1</minOccurs>
<maxOccurs>1</maxOccurs>
<maxOccurs>-1</maxOccurs>
</multiplicity>
</reference>
<composition>
Expand Down
2 changes: 1 addition & 1 deletion models/sample/test/lifecycleTest.vodsl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ otype ATest2 {
it is more a lifecycle matter really - as long as there is nothing that can
* delete the referredTo otype */

refagg references ReferredTo "";
refagg @+ references ReferredTo "";
atest : ATest as composition "";

refcont references ReferredLifeCycle ""; // potentially not OK (should be an error if referenced by something outside the object tree) - here the referred otype is also contained, so the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void setUp() throws Exception {
a.contained = contained;
a.refandcontained = refcont;
});
atest2 = new ATest2(referredTo, atest, refcont.get(0));
atest2 = new ATest2(Arrays.asList(referredTo), atest, refcont.get(0));
atest3 =
new ATest3(
contained, refcont.get(0)); // TODO this will create contradictions.... how best to test
Expand Down Expand Up @@ -98,22 +98,26 @@ void MultiContainedJPATest() {

@Test
void copyTest() {

model.createContext();
ATest atestprime = new ATest(atest);
atest.ref1.test1 = 4;
atest.ref1.test1 = 4; //change the original
assertEquals(4, atestprime.ref1.test1); // the reference should have changed

//now just change one of the contained
atest.contained.get(0).test2 = "changed";
assertEquals(
"firstcontained",
atestprime.contained.get(0)
.test2); // new objects created for the contained so changing original
// should not affect the prime
.test2); // new objects created for the contained so changing original should not affect the prime

//now clone something with "contained" references
ATest2 atest2prime = new ATest2(atest2);

atest2.atest.refandcontained.get(0).test3 = "changed2";
assertEquals("changed2", atest2.refcont.test3); // this is in atest3


//TODO this API feels unnatural...
atest2prime.updateClonedReferences();
assertEquals(
"rc1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public LifecycleTestModel createModel() {
a.contained = contained;
a.refandcontained = refcont;
});
atest2 = new ATest2( referredTo, atest, refcont.get(0));
atest2 = new ATest2( Arrays.asList(referredTo), atest, refcont.get(0));

LifecycleTestModel model = new LifecycleTestModel();
model.addContent(atest);
Expand Down
49 changes: 34 additions & 15 deletions tools/xslt/common-structure-functions.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,11 @@ note - only define functions in here as it is included in the schematron rules
</xsl:function>


<!-- returns the types that are referenced in the models -->
<xsl:function name="vf:referencesInModels" as="xsd:string*">
<xsl:sequence select="distinct-values($models//reference/datatype/vodml-ref)"/>
</xsl:function>
<!-- returns the types that are contained references in models -->
<xsl:function name="vf:containedReferencesInModels" as="xsd:string*">
<xsl:sequence select="distinct-values($models//reference/datatype/vodml-ref[vf:isContained(.)])"/>
</xsl:function>
Expand Down Expand Up @@ -219,8 +221,16 @@ note - only define functions in here as it is included in the schematron rules
</xsl:function>


<!-- return the type hierarchy focussed on the type as argument -->
<xsl:function name="vf:typeHierarchy" as="xsd:string*">
<xsl:param name="vodml-ref" as="xsd:string"/>
<xsl:sequence>
<xsl:for-each select="(vf:baseTypes($vodml-ref),$models/key('ellookup',$vodml-ref),vf:subTypes($vodml-ref))">
<xsl:value-of select="vf:asvodmlref(.)"/>
</xsl:for-each>
</xsl:sequence>
</xsl:function>
<!-- is the type (sub or base) used as a reference -->

<xsl:function name="vf:referredTo" as="xsd:boolean">
<xsl:param name="vodml-ref" as="xsd:string"/>
<xsl:sequence select="vf:referredToInModels($vodml-ref,$models/vo-dml:model/name/text())"/>
Expand All @@ -231,13 +241,7 @@ note - only define functions in here as it is included in the schematron rules

<xsl:choose>
<xsl:when test="$models/key('ellookup',$vodml-ref)">
<xsl:variable name="hier" as="xsd:string *">
<xsl:sequence>
<xsl:for-each select="(vf:baseTypes($vodml-ref),$models/key('ellookup',$vodml-ref),vf:subTypes($vodml-ref))">
<xsl:value-of select="vf:asvodmlref(.)"/>
</xsl:for-each>
</xsl:sequence>
</xsl:variable>
<xsl:variable name="hier" select="vf:typeHierarchy($vodml-ref)"/>
<!-- <xsl:message>refs <xsl:value-of select="concat ($vodml-ref,' ',count($models//reference/datatype[vodml-ref = $hier])> 0,' h=',string-join($hier,','))"/></xsl:message>-->
<xsl:value-of select="count($models/vo-dml:model[name = $modelsToSearch]//reference/datatype[vodml-ref = $hier])> 0"/>
</xsl:when>
Expand All @@ -247,6 +251,27 @@ note - only define functions in here as it is included in the schematron rules
</xsl:choose>
</xsl:function>

<!-- is the type (sub or base) used as a contained reference -->
<xsl:function name="vf:isContainedReference" as="xsd:boolean">
<xsl:param name="vodml-ref" as="xsd:string"/>
<xsl:sequence select="vf:isContainedReferenceInModels($vodml-ref,$models/vo-dml:model/name/text())"/>
</xsl:function>
<xsl:function name="vf:isContainedReferenceInModels" as="xsd:boolean">
<xsl:param name="vodml-ref" as="xsd:string"/>
<xsl:param name="modelsToSearch" as="xsd:string*"/>
<xsl:choose>
<xsl:when test="$models/key('ellookup',$vodml-ref)">
<xsl:variable name="hier" select="vf:typeHierarchy($vodml-ref)"/>
<!-- <xsl:message>refs <xsl:value-of select="concat ($vodml-ref,' ',count($models//reference/datatype[vodml-ref = $hier])> 0,' h=',string-join($hier,','))"/></xsl:message>-->
<xsl:value-of select="count($models/vo-dml:model[name = $modelsToSearch]//reference/datatype[vodml-ref = $hier and vf:isContained(.)])> 0"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">type '<xsl:value-of select="$vodml-ref"/>' not in considered models</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

<!-- vodml-ids of referrers to the type in the argument -->
<xsl:function name="vf:referredBy" as="xsd:string*">
<xsl:param name="vodml-ref" as="xsd:string"/>
<xsl:sequence select="vf:referredByInModels($vodml-ref,$models/vo-dml:model/name/text())"/>
Expand All @@ -257,13 +282,7 @@ note - only define functions in here as it is included in the schematron rules
<xsl:param name="modelsToSearch" as="xsd:string*"/>
<xsl:choose>
<xsl:when test="$models/key('ellookup',$vodml-ref)">
<xsl:variable name="hier" as="xsd:string *">
<xsl:sequence>
<xsl:for-each select="(vf:baseTypes($vodml-ref),$models/key('ellookup',$vodml-ref),vf:subTypes($vodml-ref))">
<xsl:value-of select="vf:asvodmlref(.)"/>
</xsl:for-each>
</xsl:sequence>
</xsl:variable>
<xsl:variable name="hier" select="vf:typeHierarchy($vodml-ref)"/>
<!-- <xsl:message>refs <xsl:value-of select="concat ($vodml-ref,' ',count($models//reference/datatype[vodml-ref = $hier])> 0,' h=',string-join($hier,','))"/></xsl:message>-->
<xsl:sequence select="for $i in $models/vo-dml:model[name = $modelsToSearch]//(objectType|dataType)[reference/datatype/vodml-ref = $hier] return vf:asvodmlref($i)"/> <!-- FIXME do datypes too - and proper vodml ids -->
</xsl:when>
Expand Down
16 changes: 13 additions & 3 deletions tools/xslt/jpa.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,19 @@
// TODO [NOT_SUPPORTED_REFERENCE]
</xsl:when>
<xsl:otherwise>
<!-- require manual management of references - do not remove referenced entity : do not cascade delete -->
@jakarta.persistence.ManyToOne( cascade = { jakarta.persistence.CascadeType.REFRESH } )
@jakarta.persistence.JoinColumn( nullable = <xsl:apply-templates select="." mode="nullable"/> )
<xsl:choose>
<xsl:when test="xsd:int(multiplicity/maxOccurs) != 1">
<!-- TODO should not really leave join table naming to JPA - should be explicit-->
<!-- require manual management of references - do not remove referenced entity : do not cascade delete -->
@jakarta.persistence.ManyToMany( cascade = { jakarta.persistence.CascadeType.REFRESH } )
</xsl:when>
<xsl:otherwise>
<!-- require manual management of references - do not remove referenced entity : do not cascade delete -->
@jakarta.persistence.ManyToOne( cascade = { jakarta.persistence.CascadeType.REFRESH } )
@jakarta.persistence.JoinColumn( nullable = <xsl:apply-templates select="." mode="nullable"/> )

</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Expand Down
49 changes: 41 additions & 8 deletions tools/xslt/vo-dml2java.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,10 @@
</xsl:choose>
<xsl:value-of select="').collect(java.util.stream.Collectors.toList())'"/>
</xsl:variable>

<xsl:choose>
<xsl:when test="vf:referredTo($m/datatype/vodml-ref)">
<xsl:when test="vf:isContainedReference($m/datatype/vodml-ref)">
<!-- FIXME this is probably not the right place to do this - better to do it in the clone of the type itself -->
<xsl:value-of select="concat('var cache = org.ivoa.vodml.ModelContext.current().cache(',$jt,'.class)')"/>;
<xsl:value-of select="concat('var cloned = ',$assn)"/>;
<xsl:value-of select="concat('cache.setValues(other.',vf:javaMemberName($m/name),', cloned)')"/>;
Expand Down Expand Up @@ -902,7 +904,7 @@ package <xsl:value-of select="$path"/>;
<xsl:when test="xsd:int(multiplicity/maxOccurs) gt 1">
protected <xsl:value-of select="concat($type,'[] ',vf:javaMemberName(name))"/>;
</xsl:when>
<xsl:when test="xsd:int(multiplicity/maxOccurs) lt 0">
<xsl:when test="xsd:int(multiplicity/maxOccurs) lt 0"> <!-- IMPL - this probably should not be allowed -->
protected <xsl:value-of select="concat('java.util.List',$lt,$type,$gt,' ',vf:javaMemberName(name))"/>;
</xsl:when>
<xsl:otherwise>
Expand Down Expand Up @@ -1175,7 +1177,7 @@ package <xsl:value-of select="$path"/>;
}
</xsl:template>

<xsl:template match="composition[multiplicity/maxOccurs != 1]" mode="jpawalker">
<xsl:template match="(composition[multiplicity/maxOccurs != 1]|reference[multiplicity/maxOccurs != 1])" mode="jpawalker">
for( <xsl:value-of select="vf:FullJavaType(datatype/vodml-ref, true())"/> c : <xsl:value-of select="vf:javaMemberName(name)"/> ) {
c.forceLoad();
}
Expand Down Expand Up @@ -1271,7 +1273,7 @@ package <xsl:value-of select="$path"/>;



<xsl:template match="reference" mode="declare"><!-- IMPL could be the same as attribute - actually more usefully so if reference allowed to have >1 multiplicity -->
<xsl:template match="reference" mode="declare">
<xsl:variable name="type" select="vf:JavaType(datatype/vodml-ref)"/>
/**
* ReferenceObject <xsl:value-of select="name"/> :
Expand All @@ -1284,13 +1286,21 @@ package <xsl:value-of select="$path"/>;
<xsl:apply-templates select="." mode="JAXBAnnotation"/>
<xsl:call-template name="vodmlAnnotation"/>
<xsl:apply-templates select="." mode="openapiAnnotation"/>
protected <xsl:value-of select="$type"/>&bl;<xsl:value-of select="vf:javaMemberName(name)"/> = null;
<xsl:choose>
<xsl:when test="xsd:int(multiplicity/maxOccurs) lt 0"> <!-- IMPL are allowing for multiplicity > 1 i.e. aggregation-->
protected <xsl:value-of select="concat('java.util.List',$lt,$type,$gt,' ',vf:javaMemberName(name))"/>;
</xsl:when>
<xsl:otherwise>
protected <xsl:value-of select="$type"/>&bl;<xsl:value-of select="vf:javaMemberName(name)"/> = null;
</xsl:otherwise>
</xsl:choose>

</xsl:template>




<xsl:template match="reference" mode="getset">
<xsl:template match="reference[multiplicity/maxOccurs = 1]" mode="getset">
<xsl:variable name="type" select="vf:JavaType(datatype/vodml-ref)"/>
<xsl:variable name="name">
<xsl:call-template name="upperFirst">
Expand All @@ -1313,10 +1323,33 @@ package <xsl:value-of select="$path"/>;
}
</xsl:template>

<xsl:template match="reference[multiplicity/maxOccurs != 1]" mode="getset"> <!-- IMPL could use the same rule as composition? -->
<xsl:variable name="type" select="vf:JavaType(datatype/vodml-ref)"/>
<xsl:variable name="name">
<xsl:call-template name="upperFirst">
<xsl:with-param name="val" select="name"/>
</xsl:call-template>
</xsl:variable>
/**
* Returns <xsl:value-of select="name"/> Reference<br/>
* @return <xsl:value-of select="name"/> Reference
*/
public List&lt;<xsl:value-of select="$type"/>&gt;&bl;get<xsl:value-of select="$name"/>() {
return this.<xsl:value-of select="vf:javaMemberName(name)"/>;
}
/**
* Defines <xsl:value-of select="name"/> Reference
* @param p<xsl:value-of select="$name"/> references to set
*/
public void set<xsl:value-of select="$name"/>(final List&lt;<xsl:value-of select="$type"/>&gt; p<xsl:value-of select="$name"/>) {
this.<xsl:value-of select="vf:javaMemberName(name)"/> = p<xsl:value-of select="$name"/>;
}
</xsl:template>



<xsl:template match="reference" mode="setProperty">
<!-- deprecated - references work differently now
<xsl:template match="reference[multiplicity/maxOccurs != 1]" mode="setProperty">
<xsl:variable name="type" select="vf:JavaType(datatype/vodml-ref)"/>
<xsl:variable name="name">
<xsl:call-template name="upperFirst">
Expand All @@ -1331,7 +1364,7 @@ package <xsl:value-of select="$path"/>;
set<xsl:value-of select="$name"/>((<xsl:value-of select="$type"/>)pValue);
return true;
}
</xsl:template>
</xsl:template> -->

<xsl:template match="literal" >
/**
Expand Down

0 comments on commit 54258ab

Please sign in to comment.