Skip to content

Commit ae37a61

Browse files
authored
Merge pull request #86 from lognaturel/jr-3.3.0
Validate forms with itemsets using external instances and custom refs
2 parents 7920441 + 6ddae03 commit ae37a61

File tree

7 files changed

+51
-106
lines changed

7 files changed

+51
-106
lines changed

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ sourceCompatibility = '1.8'
2828

2929
dependencies {
3030
compile group: 'net.sf.kxml', name: 'kxml2', version: '2.3.0'
31-
compile group: 'org.getodk', name: 'javarosa', version: '3.1.0'
31+
compile group: 'org.getodk', name: 'javarosa', version: '3.3.0'
3232
compile group: 'org.slf4j', name: 'slf4j-nop', version: '1.7.25'
33-
testCompile 'junit:junit:4.12'
33+
testCompile 'junit:junit:4.13.2'
3434
testCompile 'org.hamcrest:hamcrest-all:1.3'
3535
}
3636

src/org/opendatakit/validate/StubReference.java

+1-90
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,11 @@
22

33
import org.javarosa.core.reference.Reference;
44

5-
import java.io.File;
6-
import java.io.FileOutputStream;
75
import java.io.InputStream;
8-
import java.io.IOException;
96
import java.io.OutputStream;
107

11-
/**
12-
* Provides the local URI of a simple XML or CSV document. This allows forms with external secondary instances to
13-
* pass validation.
14-
*
15-
* The fake XML instance has the following structure:
16-
*
17-
* <pre>{@code
18-
* <root>
19-
* <item>
20-
* <name>an-xml-item</name>
21-
* <label>An XML Item</label>
22-
* </item>
23-
* </root>
24-
*}</pre>
25-
*
26-
* The fake CSV instance has the following structure:
27-
*
28-
* <pre>{@code
29-
* name,label
30-
* a-csv-item, "A CSV Item"
31-
*}</pre>
32-
*
33-
* This means only itemset declarations that define {@code name} as the node name referring to the select underlying
34-
* value and {@code label} as the node name referring to the label will pass validation.
35-
*
36-
* Passes validation:
37-
* <pre>{@code
38-
* <itemset nodeset="instance('lgas')/root/item[state=/nigeria_wards_external/state]">
39-
* <value ref="name"/>
40-
* <label ref="label"/>
41-
* </itemset>
42-
* }</pre>
43-
*
44-
* Fails validation:
45-
* <pre>{@code
46-
* <itemset nodeset="instance('lgas')/root/item[state=/nigeria_wards_external/state]">
47-
* <value ref="value"/>
48-
* <label ref="something-else"/>
49-
* </itemset>
50-
* }</pre>
51-
*
52-
*
53-
*
54-
*/
558
public class StubReference implements Reference {
569

57-
private String uri;
58-
59-
public StubReference(String URI) {
60-
uri = URI;
61-
}
62-
6310
@Override
6411
public boolean doesBinaryExist() {
6512
return true;
@@ -77,13 +24,7 @@ public String getURI() {
7724

7825
@Override
7926
public String getLocalURI() {
80-
if (uri.toLowerCase().startsWith("jr://file/")) {
81-
return getResourceAsFile("fake-itemset.xml").toURI().getPath();
82-
} else if (uri.toLowerCase().startsWith("jr://file-csv/")) {
83-
return getResourceAsFile("fake-itemset.csv").toURI().getPath();
84-
} else {
85-
return null;
86-
}
27+
return "Can't be found";
8728
}
8829

8930
@Override
@@ -98,40 +39,10 @@ public OutputStream getOutputStream() {
9839

9940
@Override
10041
public void remove() {
101-
10242
}
10343

10444
@Override
10545
public Reference[] probeAlternativeReferences() {
10646
return new Reference[0];
10747
}
108-
109-
// getResource() on a file will fail when Validate is run as a jar.
110-
// getResourceAsStream() is the workaround, but because we need a path,
111-
// we need to copy the stream to a temp file. The temp file is deleted
112-
// when the JVM exits
113-
// https://stackoverflow.com/a/35466006/152938
114-
private static File getResourceAsFile(String resourcePath) {
115-
try {
116-
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
117-
if (in == null) {
118-
return null;
119-
}
120-
121-
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
122-
tempFile.deleteOnExit();
123-
124-
try (FileOutputStream out = new FileOutputStream(tempFile)) {
125-
byte[] buffer = new byte[1024];
126-
int bytesRead;
127-
while ((bytesRead = in.read(buffer)) != -1) {
128-
out.write(buffer, 0, bytesRead);
129-
}
130-
}
131-
return tempFile;
132-
} catch (IOException e) {
133-
e.printStackTrace();
134-
return null;
135-
}
136-
}
13748
}

src/org/opendatakit/validate/StubReferenceFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ public boolean derives(String URI) {
1616

1717
@Override
1818
public Reference derive(String URI) {
19-
return new StubReference(URI);
19+
return new StubReference();
2020
}
2121

2222
@Override
2323
public Reference derive(String URI, String context) {
24-
return new StubReference(URI);
24+
return new StubReference();
2525
}
2626
}

src/test/java/org/opendatakit/validate/ValidateExternalSecondaryInstancesTest.java

+18-12
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,31 @@
1313

1414
public class ValidateExternalSecondaryInstancesTest {
1515
@Test
16-
public void supports_xlsforms_value_and_label_refs_in_itemsets_using_secondary_external_instances_xml() throws URISyntaxException {
17-
supports_xlsforms_value_and_label_refs_in_itemsets_using_secondary_external_instances("external_secondary_instance_xml.xml");
16+
public void supportsXlsformsDefaultValueAndLabelRefs_inItemsets_usingXMLExternalSecondaryInstance() throws URISyntaxException {
17+
final Path path = getPathOf("xml_external_instance.xml");
18+
final FormValidator validator = new FormValidator();
19+
20+
Output output = Output.runAndGet(() -> validator.validate(path.toString()));
21+
assertThat(output.err, isEmptyString());
22+
assertThat(output.std, containsString("Xform is valid"));
1823
}
1924

2025
@Test
21-
public void supports_xlsforms_value_and_label_refs_in_itemsets_using_secondary_external_instances_csv() throws URISyntaxException {
22-
supports_xlsforms_value_and_label_refs_in_itemsets_using_secondary_external_instances("external_secondary_instance_csv.xml");
26+
public void supportsXlsformsDefaultValueAndLabelRefs_inItemsets_usingCsvSecondaryExternalInstance() throws URISyntaxException {
27+
final Path path = getPathOf("csv_external_instance.xml");
28+
final FormValidator validator = new FormValidator();
29+
30+
Output output = Output.runAndGet(() -> validator.validate(path.toString()));
31+
assertThat(output.err, isEmptyString());
32+
assertThat(output.std, containsString("Xform is valid"));
2333
}
2434

25-
private void supports_xlsforms_value_and_label_refs_in_itemsets_using_secondary_external_instances(String secondaryInstancePath) throws URISyntaxException {
26-
final Path path = getPathOf(secondaryInstancePath);
35+
@Test
36+
public void supportsCustomValueAndLabelRefs_inItemsets_usingExternalSecondaryInstance() throws URISyntaxException {
37+
final Path path = getPathOf("external_instance_custom_refs.xml");
2738
final FormValidator validator = new FormValidator();
2839

29-
Output output = Output.runAndGet(new Runnable() {
30-
@Override
31-
public void run() {
32-
validator.validate(path.toString());
33-
}
34-
});
40+
Output output = Output.runAndGet(() -> validator.validate(path.toString()));
3541
assertThat(output.err, isEmptyString());
3642
assertThat(output.std, containsString("Xform is valid"));
3743
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0"?>
2+
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa">
3+
<h:head>
4+
<h:title>External Secondary Instance with xlsforms generated itemset value/label refs</h:title>
5+
<model>
6+
<instance>
7+
<data id="external-choices">
8+
<some-value/>
9+
<meta>
10+
<instanceID/>
11+
</meta>
12+
</data>
13+
</instance>
14+
<instance id="external-choices" src="jr://file-csv/external-choices.csv"/>
15+
<bind nodeset="/data/some-value" type="select1"/>
16+
<bind calculate="concat('uuid:', uuid())" nodeset="/data/meta/instanceID" readonly="true()" type="string"/>
17+
</model>
18+
</h:head>
19+
<h:body>
20+
<select1 ref="/data/some-value">
21+
<label>Value 1</label>
22+
<itemset nodeset="instance('external-choices')/root/item">
23+
<value ref="id"/>
24+
<label ref="a_custom_label"/>
25+
</itemset>
26+
</select1>
27+
</h:body>
28+
</h:html>

0 commit comments

Comments
 (0)