Skip to content

Commit

Permalink
beginning of contained reference validation
Browse files Browse the repository at this point in the history
  • Loading branch information
pahjbo committed Feb 7, 2024
1 parent 04c0301 commit 499bbb3
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 15 deletions.
2 changes: 1 addition & 1 deletion doc/VODML-stdrec.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ models allows these to be used in a homogeneous manner and allows a
consistent definition of reuse of one model by another. The particular language
defined here includes a consistent identification mechanism for model which
allows these to be referenced in an explicit and uniform manner also from other
contexts, in particular from othe IVOA standard formats such as VOTable.
contexts, in particular from other IVOA standard formats such as VOTable.

The language defined in this specification is named VO-DML (VO Data Modeling
Language). VO-DML is a conceptual modeling language that is agnostic of
Expand Down
2 changes: 1 addition & 1 deletion models/sample/test/jpatest.vo-dml.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<uri/>
<title></title>
<version>1.0</version>
<lastModified>2023-12-19T14:14:15Z</lastModified>
<lastModified>2023-12-19T15:16:26Z</lastModified>
<import>
<name>null</name><!--should not be needed in modern vo-dml -->
<url>IVOA-v1.0.vo-dml.xml</url>
Expand Down
28 changes: 26 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>2023-06-08T07:49:03Z</lastModified>
<lastModified>2024-01-23T08:37:51Z</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 @@ -111,6 +111,18 @@
<vodml-id>ATest2</vodml-id>
<name>ATest2</name>
<description></description>
<composition>
<vodml-id>ATest2.atest</vodml-id>
<name>atest</name>
<description></description>
<datatype>
<vodml-ref>lifecycleTest:ATest</vodml-ref>
</datatype>
<multiplicity>
<minOccurs>1</minOccurs>
<maxOccurs>1</maxOccurs>
</multiplicity>
</composition>
<reference>
<vodml-id>ATest2.refagg</vodml-id>
<name>refagg</name>
Expand All @@ -120,7 +132,7 @@
</datatype>
<multiplicity>
<minOccurs>1</minOccurs>
<maxOccurs>1</maxOccurs><!-- FIXME would like to support unbounded here -->
<maxOccurs>1</maxOccurs>
</multiplicity>
</reference>
<reference>
Expand Down Expand Up @@ -152,5 +164,17 @@
<maxOccurs>-1</maxOccurs>
</multiplicity>
</composition>
<reference>
<vodml-id>ATest3.refBad</vodml-id>
<name>refBad</name>
<description></description>
<datatype>
<vodml-ref>lifecycleTest:ReferredLifeCycle</vodml-ref>
</datatype>
<multiplicity>
<minOccurs>1</minOccurs>
<maxOccurs>1</maxOccurs>
</multiplicity>
</reference>
</objectType>
</vo-dml:model>
11 changes: 8 additions & 3 deletions models/sample/test/lifecycleTest.vodsl
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,20 @@ otype ATest { //this does things as per current rules

otype ATest2 {

refagg @+ references ReferredTo ""; /* not liked because of "aggregation pattern", but really ok -
it is more a lifecycle matter really - as long as there is nothing that can
/* would like to make the multiplicity of below one-or-more - however this is not liked because
* of "aggregation pattern", but really ok for references -
it is more a lifecycle matter really - as long as there is nothing that can
* delete the referredTo otype */

refcont references ReferredLifeCycle ""; // potentially not OK (perhaps should be an error) - here the referred otype is also contained, so the
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
}

otype ATest3 { /* fails the "unique composition rule" in schematron if the one of the Contained instances is also contained in ATest,
* but this should be unlikely if a contained type instance is created at the same time as its container instance.
*/
contained : Contained @+ as composition ""; //vodsl tooling does not flag this- but the vodml schematron does.
refBad references ReferredLifeCycle ""; //this should be an error
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

package org.ivoa.dm.lifecycle;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.*;

import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -54,8 +54,8 @@ void setUp() throws Exception {
a.refandcontained = refcont;

});
atest2 = new ATest2(referredTo, refcont.get(0));
atest3 = new ATest3(contained);
atest2 = new ATest2(atest, referredTo, refcont.get(0));
atest3 = new ATest3(contained, refcont.get(0));//TODO this will create contradictions.... how best to test

model = new LifecycleTestModel();
model.addContent(atest);
Expand Down Expand Up @@ -94,6 +94,18 @@ void MultiContainedJPATest() {
em.getTransaction().commit();
dumpDbData(em, "lifecycle_dump.sql");
}

@Test
void copyTest() {
ATest atestprime = new ATest(atest);
atest.ref1.test1 = 4;
assertEquals(4, atestprime.ref1.test1); //the reference should have changed
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

ATest2 atest2prime = new ATest2(atest2);

}


}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public LifecycleTestModel createModel() {
a.refandcontained = refcont;

});
atest2 = new ATest2(referredTo, refcont.get(0));
atest2 = new ATest2(atest,referredTo, refcont.get(0));

LifecycleTestModel model = new LifecycleTestModel();
model.addContent(atest);
Expand Down
39 changes: 38 additions & 1 deletion tools/xslt/common-structure-functions.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ note - only define functions in here as it is included in the schematron rules
<!-- does the vodml-ref exist? -->
<xsl:function name="vf:vo-dml-ref-exists" as="xsd:boolean">
<xsl:param name="vodml-ref" />
<xsl:value-of select="count($models/key('ellookup',$vodml-ref)) =1 " />
<xsl:sequence select="count($models/key('ellookup',$vodml-ref)) =1 " />
</xsl:function>

<!-- return the base types for current type - note that this does not return the types in strict hierarchy order (not sure why!) -->
Expand Down Expand Up @@ -328,6 +328,43 @@ note - only define functions in here as it is included in the schematron rules
</xsl:choose>

</xsl:function>

<!-- returns all the contained type ids -->
<xsl:function name="vf:containedTypeIds" as="xsd:string*">
<xsl:param name="vodml-ref"/>
<xsl:choose>
<xsl:when test="$models/key('ellookup',$vodml-ref)">
<xsl:variable name="el" as="element()">
<xsl:copy-of select="$models/key('ellookup',$vodml-ref)" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$el/composition">
<xsl:sequence select="($el/composition/datatype/vodml-ref, for $v in $el/composition/datatype/vodml-ref return vf:containedTypeIds($v))"/>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">type <xsl:value-of select="$vodml-ref"/> not in considered models for base types</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

<xsl:function name="vf:isTypeContained" as="xsd:boolean">
<xsl:param name="type-vodml-ref" as="xsd:string" />
<xsl:param name="root-vodml-ref" as="xsd:string"/>
<xsl:variable name="root" select="$models/key('ellookup',$root-vodml-ref)"/>
<xsl:choose>
<xsl:when test="$root/composition">
<xsl:sequence select="$type-vodml-ref = vf:containedTypeIds($root-vodml-ref)"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="false()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>



<xsl:function name="vf:attributeIsDtype" as="xsd:boolean">
<xsl:param name="attr" as="element()"/>
<xsl:sequence select="$models/key('ellookup',$attr/datatype/vodml-ref)/name() = 'dataType'"/>
Expand Down
7 changes: 4 additions & 3 deletions tools/xslt/vo-dml-v1.0.sch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type <sch:value-of select="datatype/vodml-ref"/> of <sch:value-of select="$owner

<sch:rule context="reference">
<sch:let name="owner" value="vf:asvodmlref(current())"/>
<sch:let name="parent" value="vf:asvodmlref(current()/ancestor-or-self::objectType)"/>
<sch:assert test="vf:vo-dml-ref-exists(datatype/vodml-ref)" flag="error">
vodml-ref <sch:value-of select="datatype/vodml-ref"/> for type of <sch:value-of select="$owner"/> does not exist
</sch:assert>
Expand All @@ -150,9 +151,9 @@ type <sch:value-of select="datatype/vodml-ref"/> of <sch:value-of select="$owner
type <sch:value-of select="datatype/vodml-ref"/> of reference <sch:value-of select="$owner"/> is not an object type but a '<sch:value-of select="$target"/>'
</sch:assert>
<!--rules implementing a reference should not be used in composition - this does not work well with the current tooling, however, if references allowed unlimited multiplicities then... -->
<sch:report test="$composition" flag="warning">
Reference <sch:value-of select="./datatype/vodml-ref"/> used in <sch:value-of select="./vodml-id"/> is already in composition <sch:value-of select="$composition/vodml-id"/> which has lifecycle implications.
</sch:report>
<sch:assert test="$composition and not(vf:isTypeContained($target,$parent)) " flag="error">
Reference <sch:value-of select="./datatype/vodml-ref"/> used in <sch:value-of select="./vodml-id"/> is already in composition <sch:value-of select="$composition/vodml-id"/> which has lifecycle implications
</sch:assert>
</sch:rule>

<sch:rule context="objectType/composition">
Expand Down

0 comments on commit 499bbb3

Please sign in to comment.