From ca81b11bb5bf58d689ad69e08804e66f6012f997 Mon Sep 17 00:00:00 2001 From: Matthew Dickie Date: Mon, 23 May 2016 15:13:41 +0100 Subject: [PATCH] [DAQ-146] support adding nexus object to a collection Signed-off-by: Matthew Dickie --- .../impl/DefaultNexusEntryBuilderTest.java | 25 ++++++++++++-- .../builder/AbstractNexusObjectProvider.java | 10 ++++++ .../nexus/builder/NexusObjectProvider.java | 11 ++++++ .../impl/DefaultNexusEntryBuilder.java | 34 +++++++++++++++++-- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/org.eclipse.dawnsci.nexus.test/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilderTest.java b/org.eclipse.dawnsci.nexus.test/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilderTest.java index 7144d442..0bac1055 100644 --- a/org.eclipse.dawnsci.nexus.test/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilderTest.java +++ b/org.eclipse.dawnsci.nexus.test/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilderTest.java @@ -10,10 +10,12 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import java.util.Arrays; +import org.eclipse.dawnsci.nexus.NXcollection; import org.eclipse.dawnsci.nexus.NXdetector; import org.eclipse.dawnsci.nexus.NXentry; import org.eclipse.dawnsci.nexus.NXinstrument; @@ -31,8 +33,6 @@ import org.eclipse.dawnsci.nexus.builder.NexusObjectProvider; import org.eclipse.dawnsci.nexus.builder.appdef.NexusApplicationBuilder; import org.eclipse.dawnsci.nexus.builder.data.NexusDataBuilder; -import org.eclipse.dawnsci.nexus.builder.impl.DefaultNexusFileBuilder; -import org.eclipse.dawnsci.nexus.builder.impl.MapBasedMetadataProvider; import org.eclipse.dawnsci.nexus.validation.NexusValidationException; import org.junit.Before; import org.junit.Test; @@ -151,6 +151,27 @@ public void testAdd_namedGroup() throws NexusException { assertThat(instrument.getPositioner("x"), is(sameInstance(positionerProvider.getNexusObject()))); } + @Test + public void testAdd_positionerWithCollectionName() throws NexusException { + entryBuilder.addDefaultGroups(); + assertThat(nxEntry.getNumberOfGroupNodes(), is(3)); + NXinstrument instrument = nxEntry.getInstrument(); + assertThat(instrument.getNumberOfGroupNodes(), is(0)); + + AbstractNexusObjectProvider positioner = new TestPositioner("xPos"); + positioner.setCollectionName("scannables"); + entryBuilder.add(positioner); + + assertThat(nxEntry.getNumberOfGroupNodes(), is(3)); + assertThat(instrument.getNumberOfGroupNodes(), is(1)); + + NXcollection collection = instrument.getCollection("scannables"); + assertNotNull(collection); + NXpositioner xPositioner = (NXpositioner) collection.getGroupNode("xPos"); + assertNotNull(xPositioner); + assertThat(xPositioner, is(sameInstance(positioner.getNexusObject()))); + } + @Test public void testAdd_samplePositioner() throws NexusException { entryBuilder.addDefaultGroups(); diff --git a/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/AbstractNexusObjectProvider.java b/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/AbstractNexusObjectProvider.java index 8a79ecd9..aa915c9a 100644 --- a/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/AbstractNexusObjectProvider.java +++ b/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/AbstractNexusObjectProvider.java @@ -89,6 +89,8 @@ public abstract class AbstractNexusObjectProvider implements private String defaultAxisDataFieldName = null; + private String collectionName = null; + private NexusBaseClass category = null; private Boolean useDeviceNameInNXdata = null; @@ -461,6 +463,14 @@ public void setCategory(NexusBaseClass category) { this.category = category; } + public String getCollectionName() { + return collectionName; + } + + public void setCollectionName(String collectionName) { + this.collectionName = collectionName; + } + @Override public Integer getDefaultAxisDimension(String primaryDataFieldName, String dataFieldName) { PrimaryDataFieldModel dataFieldModel = getPrimaryDataFieldModel(primaryDataFieldName, false); diff --git a/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/NexusObjectProvider.java b/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/NexusObjectProvider.java index 51287994..0fed4785 100644 --- a/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/NexusObjectProvider.java +++ b/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/NexusObjectProvider.java @@ -14,6 +14,7 @@ import java.util.List; +import org.eclipse.dawnsci.nexus.NXcollection; import org.eclipse.dawnsci.nexus.NXdata; import org.eclipse.dawnsci.nexus.NXinstrument; import org.eclipse.dawnsci.nexus.NXobject; @@ -88,6 +89,16 @@ public interface NexusObjectProvider extends NexusEntryModif */ public NexusBaseClass getCategory(); + /** + * Returns the name of the collection for this {@link NexusObjectProvider}. When adding + * a nexus object to a {@link NexusEntryBuilder}, if this method does not return + * null, then the nexus object will be added to the {@link NXcollection} with this + * name within the group that it would have been added to otherwise. The collection will be + * created if it does not already exist. + * @return collection name or null + */ + public String getCollectionName(); + /** * Returns the name of the external HDF5 file that this device writes * its data to, or null if none diff --git a/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilder.java b/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilder.java index 0942b609..71ffa4c8 100644 --- a/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilder.java +++ b/org.eclipse.dawnsci.nexus/src/org/eclipse/dawnsci/nexus/builder/impl/DefaultNexusEntryBuilder.java @@ -18,7 +18,9 @@ import java.util.List; import org.eclipse.dawnsci.analysis.api.tree.DataNode; +import org.eclipse.dawnsci.analysis.api.tree.GroupNode; import org.eclipse.dawnsci.analysis.api.tree.NodeLink; +import org.eclipse.dawnsci.nexus.NXcollection; import org.eclipse.dawnsci.nexus.NXdata; import org.eclipse.dawnsci.nexus.NXentry; import org.eclipse.dawnsci.nexus.NXinstrument; @@ -66,10 +68,11 @@ public class DefaultNexusEntryBuilder implements NexusEntryBuilder { * Creates a new {@link DefaultNexusEntryBuilder}. This constructor should only be called * by {@link DefaultNexusFileBuilder}. * @param nexusNodeFactory node factory - * @param entryName TODO + * @param entryName name of entry * @param nxEntry entry to wrap */ - protected DefaultNexusEntryBuilder(final NexusNodeFactory nexusNodeFactory, String entryName, final NXentry nxEntry) { + protected DefaultNexusEntryBuilder(final NexusNodeFactory nexusNodeFactory, + String entryName, final NXentry nxEntry) { this.nexusNodeFactory = nexusNodeFactory; this.nxEntry = nxEntry; this.entryName = entryName; @@ -250,7 +253,6 @@ public DataNode getDataNode(String relativePath) throws NexusException { /** * Adds the default groups for the entry. Subclasses may override as appropriate. - * @return */ @Override public void addDefaultGroups() { @@ -310,10 +312,13 @@ protected void addGroupToNexusTree(NexusObjectProvider n final String name = nexusObjectProvider.getName(); final NexusBaseClass category = nexusObjectProvider.getCategory(); + // find the parent group NXobject parentGroup = null; if (category != null) { + // if a category is specified, the parent group is the first group for this category parentGroup = findGroupForCategory(category); } else { + // otherwise the parent group is the first group we can add this type of object to for (final NXobject group : defaultGroups) { if (group.canAddChild(nexusObject)) { parentGroup = group; @@ -324,10 +329,33 @@ protected void addGroupToNexusTree(NexusObjectProvider n throw new NexusException("Cannot find a parent group that accepts a " + nexusObject.getNexusBaseClass()); } } + + // if a collection name is specified, get the parent collection - creating it if necessary + String collectionName = nexusObjectProvider.getCollectionName(); + if (collectionName != null) { + parentGroup = getCollection(parentGroup, collectionName); + } parentGroup.addGroupNode(name, nexusObject); } } + + private NXcollection getCollection(NXobject group, String collectionName) { + NXcollection collection = null; + + GroupNode collectionGroup = group.getGroupNode(collectionName); + if (collectionGroup == null) { + collection = nexusNodeFactory.createNXcollection(); + group.addGroupNode(collectionName, collection); + } else if (collectionGroup instanceof NXcollection) { + collection = (NXcollection) collectionGroup; + } else { + throw new IllegalArgumentException("Cannot add collection " + collectionName + + ". A child group with that name already exists"); + } + + return collection; + } private NXobject findGroupForCategory(NexusBaseClass category) throws NexusException { if (category == NexusBaseClass.NX_ENTRY) {