/*-
* Copyright 2015 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.dawnsci.nexus.file;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URI;
import org.eclipse.dawnsci.analysis.api.tree.GroupNode;
import org.eclipse.dawnsci.nexus.NexusException;
import org.eclipse.dawnsci.nexus.NexusFile;
import org.eclipse.dawnsci.nexus.TestUtils;
import org.eclipse.dawnsci.nexus.test.util.NexusTestUtils;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DatasetFactory;
import org.junit.BeforeClass;
import org.junit.Test;
public class NexusFileLinkTest {
static String testScratchDirectoryName;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
testScratchDirectoryName = TestUtils.generateDirectorynameFromClassname(NexusFileLinkTest.class.getCanonicalName());
TestUtils.makeScratchDirectory(testScratchDirectoryName);
}
@Test
public void testAuthority() throws Exception {
// explore how URI is decomposed
printURI(new URI("nxfile://top/file#/node"));
printURI(new URI("nxfile:///top/file#/node"));
printURI(new URI("nxfile://./top/file#/node"));
printURI(new URI("nxfile:///./top/file#/node"));
}
void printURI(URI uri) {
System.out.println("URI : " + uri);
System.out.println("Authority: " + uri.getAuthority());
System.out.println("Path : " + uri.getPath());
String a = uri.getAuthority();
String p = uri.getPath();
if (a != null) {
p = a + p;
}
System.out.println("Combined : " + p);
System.out.println("Fragment : " + uri.getFragment());
System.out.println("");
}
@Test
public void testExternalLinks() throws Exception {
Dataset a = DatasetFactory.createRange(10, Dataset.FLOAT32).reshape(2, 5);
a.setName("value");
String ename;
String tname;
NexusFile nf;
GroupNode g;
// create file where /e/f/g -> a so /e/f/g/b/c is available
ename = createExternalFile(testScratchDirectoryName + "external1.nxs", a);
tname = testScratchDirectoryName + "test1.nxs";
nf = NexusTestUtils.createNexusFile(tname);
nf.linkExternal(new URI("nxfile://./" + ename + "#/a"), "/e/f/g", true);
nf.close();
nf = NexusTestUtils.openNexusFileReadOnly(tname);
g = nf.getGroup("/e/f/g", false);
assertNotNull(g);
assertTrue(g.containsAttribute("top"));
assertEquals("world", g.getAttribute("top").getFirstElement());
g = nf.getGroup(g, "b", null, false);
g = nf.getGroup("/e/f/g/b", false);
assertNotNull(g);
g = nf.getGroup("/e/f/g/b/c", false);
assertNotNull(g);
assertTrue(g.containsDataNode("value"));
assertEquals(a, g.getDataNode("value").getDataset().getSlice());
nf.close();
// create file where /e/f/g/a -> a so /e/f/g/a/b/c is available
ename = createExternalFile(testScratchDirectoryName + "external2.nxs", a);
tname = testScratchDirectoryName + "test2.nxs";
nf = NexusTestUtils.createNexusFile(tname);
nf.linkExternal(new URI("nxfile://./" + ename + "#/a"), "/e/f/g/", true);
nf.close();
nf = NexusTestUtils.openNexusFileReadOnly(tname);
g = nf.getGroup("/e/f/g", false);
assertNotNull(g);
assertFalse(g.containsAttribute("top"));
g = nf.getGroup(g, "a", null, false);
assertNotNull(g);
assertTrue(g.containsAttribute("top"));
assertEquals("world", g.getAttribute("top").getFirstElement());
g = nf.getGroup(g, "b", null, false);
assertNotNull(g);
g = nf.getGroup("/e/f/g/a/b", false);
assertNotNull(g);
g = nf.getGroup("/e/f/g/a/b/c", false);
assertNotNull(g);
assertTrue(g.containsDataNode("value"));
assertEquals(a, g.getDataNode("value").getDataset().getSlice());
nf.close();
// create file where /e/f/d -> value so /e/f/d is available
ename = createExternalFile(testScratchDirectoryName + "external3.nxs", a);
createExternalFile(ename, a);
tname = testScratchDirectoryName + "test3.nxs";
nf = NexusTestUtils.createNexusFile(tname);
nf.linkExternal(new URI("nxfile://./" + ename + "#/a/b/c/value"), "/e/f/d", false);
nf.close();
nf = NexusTestUtils.openNexusFileReadOnly(tname);
g = nf.getGroup("/e/f", false);
assertNotNull(g);
assertTrue(g.containsDataNode("d"));
assertEquals(a, g.getDataNode("d").getDataset().getSlice());
assertEquals(a, nf.getData(g, "d").getDataset().getSlice());
assertEquals(a, nf.getData("/e/f/d").getDataset().getSlice());
nf.close();
// create file where /e/f/g -> c so /e/f/g/value is available
ename = createExternalFile(testScratchDirectoryName + "external4.nxs", a);
createExternalFile(ename, a);
tname = testScratchDirectoryName + "test4.nxs";
nf = NexusTestUtils.createNexusFile(tname);
nf.linkExternal(new URI("nxfile://./" + ename + "#/a/b/c/value"), "/e/f/g/", false);
nf.close();
nf = NexusTestUtils.openNexusFileReadOnly(tname);
g = nf.getGroup("/e/f/g", false);
assertNotNull(g);
assertTrue(g.containsDataNode("value"));
assertEquals(a, g.getDataNode("value").getDataset().getSlice());
assertEquals(a, nf.getData(g, "value").getDataset().getSlice());
assertEquals(a, nf.getData("/e/f/g/value").getDataset().getSlice());
nf.close();
}
// need to create a new external file as NAPI does not seem to cope well if an external file
// is used in several files
static boolean WORKAROUND_NAPI = true;
private String createExternalFile(String ename, Dataset d) throws NexusException {
if (!WORKAROUND_NAPI) {
ename = "test-scratch/external.nxs";
if (new File(ename).exists())
return ename;
}
NexusFile nf = NexusTestUtils.createNexusFile(ename);
GroupNode g = nf.getGroup("/a", true);
Dataset a = DatasetFactory.createFromObject("world");
a.setName("top");
nf.addAttribute(g, nf.createAttribute(a));
g = nf.getGroup("/a/b/c", true);
a = DatasetFactory.createFromObject("world");
a.setName("bottom");
nf.addAttribute(g, nf.createAttribute(a));
nf.createData(g, d);
nf.close();
return ename;
}
}