/* * Copyright 2006-2014 University of Dundee. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.server.itests.query; import java.sql.Timestamp; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import ome.conditions.ApiUsageException; import ome.model.IObject; import ome.model.annotations.TimestampAnnotation; import ome.model.containers.Dataset; import ome.model.containers.Project; import ome.model.core.Image; import ome.model.core.Pixels; import ome.model.meta.Experimenter; import ome.model.meta.ExperimenterGroup; import ome.parameters.Filter; import ome.parameters.Parameters; import ome.server.itests.AbstractManagedContextTest; import ome.services.query.PojosGetImagesQueryDefinition; import ome.testing.ObjectFactory; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @Test(groups = "integration") public class GetImagesQueryTest extends AbstractManagedContextTest { PojosGetImagesQueryDefinition q; List list; protected void creation_fails(Parameters parameters) { try { q = new PojosGetImagesQueryDefinition(parameters); fail("Should have failed!"); } catch (IllegalArgumentException e) { } catch (ApiUsageException aue) { } } @Test public void test_illegal_arguments() throws Exception { creation_fails(null); creation_fails(new Parameters().addIds(null) // Null .addClass(null)); creation_fails(new Parameters().addIds(Arrays.asList(1)) // Not long .addClass(Project.class)); /* * TODO currently handled by IContainer creation_fails( ContainerQP.ids( new * ArrayList() ), // Empty ContainerQP.options( null ), * ContainerQP.Class(QP.CLASS, Project.class ) ); * * PojoOptions po = new PojoOptions().allExps(); creation_fails( * ContainerQP.ids( null ), ContainerQP.options( po.realmap() ), // Has to have * experimenter ContainerQP.Class(QP.CLASS, Project.class ) ); */ } @org.testng.annotations.Test public void test_simple_usage() throws Exception { Long doesntExist = -1L; q = new PojosGetImagesQueryDefinition(new Parameters().addIds( Arrays.asList(doesntExist)).addClass(Project.class)); list = (List) iQuery.execute(q); Parameters po = new Parameters().exp(doesntExist); q = new PojosGetImagesQueryDefinition(new Parameters().addIds( Arrays.asList(doesntExist)).addClass(Project.class)); list = (List) iQuery.execute(q); } @Test(groups = { "ticket:159", "ticket:422" }) public void test_shouldReturnImages() throws Exception { Project prj = (Project) iQuery.findByQuery( // FIXME NullPointerException in Antlr. Report bug. // "select p from Project p " + // " where p.datasetLinks.child.imageLinks.child is not null // ",p); "select p from Project p " + " left outer join p.datasetLinks as pdl " + " left outer join pdl.child as d " + " left outer join d.imageLinks as dil " + " left outer join dil.child as i " + " where i is not null", new Parameters() .unique().page(0, 1)); q = new PojosGetImagesQueryDefinition(new Parameters().addIds( Arrays.asList(prj.getId())).addClass(Project.class)); list = (List) iQuery.execute(q); assertTrue(list.size() > 0); assertTrue(list.iterator().next().getClass().equals(Image.class)); } // ~ Setup // ========================================================================= MAP rootOnlyMap = new MAP(); Experimenter user; ExperimenterGroup group; MAP rootProjectMap = new MAP(); MAP userImageRootProjectMap = new MAP(); MAP userProjectMap = new MAP(); Parameters userPO; Parameters filterForUser; Parameters noFilter; @BeforeClass public void test_createObjects() throws Exception { // Forcing setup once now. // super adaptSetUp(); will be called by testng // ~ ALL ROOT OBJECTS // ===================================================================== loginRoot(); Project p1 = createProject(); Dataset d1 = createDataset(); Dataset d2 = createDataset(); Image i_d1 = createImage(); Image i_d2 = createImage(); p1.linkDataset(d1); p1.linkDataset(d2); d1.linkImage(i_d1); d2.linkImage(i_d2); rootOnlyMap.put(p1, i_d1); rootOnlyMap.put(d1, i_d1); rootOnlyMap.put(p1, i_d2); rootOnlyMap.put(d2, i_d2); Image i_c1 = createImage(); Image i_c2 = createImage(); // Saving the newly created links. iUpdate.saveArray(new IObject[] { p1, d1, d2, i_d1, i_d2, i_c1, i_c2 }); // ~ USER FILTER // ===================================================================== user = null; // (Experimenter) iQuery.findByQuery( // "select e from Experimenter e " + // "where e.id != 0", // new Parameters( new Filter().unique().page(0,1))); if (user == null) { group = new ExperimenterGroup(); group.setName(uuid()); group.setLdap(false); long gid = iAdmin.createGroup(group); user = new Experimenter(); user.setOmeName(uuid()); user.setFirstName("Get"); user.setLastName("Images"); user.setLdap(false); user = iAdmin.getExperimenter(iAdmin.createUser(user, group .getName())); } userPO = new Parameters().exp(user.getId()); filterForUser = userPO; // See ticket:67 noFilter = new Parameters(); // ~ MIXED ROOT/USER ITEMS // ===================================================================== loginRoot(group.getName()); Project p1_root = createProject(); Dataset d1_root = createDataset(); Dataset d2_root = createDataset(); Image i_d1_root = createImage(); Image i_d2_root = createImage(); p1_root.linkDataset(d1_root); p1_root.linkDataset(d2_root); d1_root.linkImage(i_d1_root); d2_root.linkImage(i_d2_root); rootProjectMap.put(p1_root, i_d1_root); rootProjectMap.put(d1_root, i_d1_root); rootProjectMap.put(p1_root, i_d2_root); rootProjectMap.put(d2_root, i_d2_root); loginUser(user.getOmeName()); Image i_d1_user = createImage(); Image i_d2_user = createImage(); p1_root.linkDataset(d1_root); p1_root.linkDataset(d2_root); d1_root.linkImage(i_d1_user); d2_root.linkImage(i_d2_user); userImageRootProjectMap.put(p1_root, i_d1_user); userImageRootProjectMap.put(d1_root, i_d1_user); userImageRootProjectMap.put(p1_root, i_d2_user); userImageRootProjectMap.put(d2_root, i_d2_user); Project p11_user = createProject(); Dataset d11_user = createDataset(); Dataset d22_user = createDataset(); Image i_d11_user = createImage(); Image i_d22_user = createImage(); p11_user.linkDataset(d11_user); p11_user.linkDataset(d22_user); d11_user.linkImage(i_d11_user); d22_user.linkImage(i_d22_user); userProjectMap.put(p11_user, i_d11_user); userProjectMap.put(d11_user, i_d11_user); userProjectMap.put(p11_user, i_d22_user); userProjectMap.put(d22_user, i_d22_user); // TODO not working. // setUser( user, // i_d1_user,i_d2_user, // p11_user,d11_user,d22_user,i_d11_user,i_d22_user); // omitting CGC for now since this is only testing "enableFilters" loginRoot(group.getName()); // Saving the newly created links. iUpdate.saveArray(new IObject[] { p1_root, d1_root, d2_root, i_d1_root, i_d2_root, i_d1_user, i_d2_user, p11_user, d11_user, d22_user, i_d11_user, i_d22_user }); // super class adaptTearDown(); will be called by testng } // ~ UNFILTERED // ========================================================================= @Test public void test_retrieve_levels() throws Exception { runWholeLevel(Project.class); runWholeLevel(Dataset.class); runAllOnLevel(Project.class); runAllOnLevel(Dataset.class); } private void runWholeLevel(Class klass) { runLevel(klass, rootOnlyMap.listKeyIds(klass), rootOnlyMap .listAllObjects(klass)); } private void runAllOnLevel(Class klass) { Set<Long> ids = rootOnlyMap.listKeyIds(klass); for (Long l : ids) { runLevel(klass, Collections.singleton(l), rootOnlyMap.get(klass, l)); } } private void runLevel(Class klass, Collection<Long> klassIds, Collection<IObject> results) { q = new PojosGetImagesQueryDefinition(new Parameters().addIds(klassIds) .addClass(klass)); list = (List) iQuery.execute(q); assertTrue( "Didn't find expected number of results, but " + list.size(), list.size() == results.size()); } // ~ FILTERING // ========================================================================= @Test public void test_owner_filter_user_obj() throws Exception { Parameters ids; Set set = new HashSet(); set.addAll(rootProjectMap.listKeyIds(Project.class)); set.addAll(userImageRootProjectMap.listKeyIds(Project.class)); set.addAll(userProjectMap.listKeyIds(Project.class)); ids = new Parameters().addIds(set); q = new PojosGetImagesQueryDefinition(new Parameters(ids).addAll( noFilter).addClass(Project.class)); list = (List) iQuery.execute(q); assertTrue(list.size() == userImageRootProjectMap.listAllObjects( Project.class).size() + rootProjectMap.listAllObjects(Project.class).size() + userProjectMap.listAllObjects(Project.class).size()); q = new PojosGetImagesQueryDefinition(new Parameters(ids).addAll( filterForUser).addClass(Project.class)); list = (List) iQuery.execute(q); int expected = userImageRootProjectMap.listAllObjects(Project.class) .size() + userProjectMap.listAllObjects(Project.class).size(); assertTrue(list.size() + " not " + expected, list.size() == expected); } @Test public void test_owner_filter_root_obj() throws Exception { Parameters ids; // Doesn't belong to user. // Using rootOnlyMap and not root*Map because root*Map has links to // user, // while rootOnlyMap doesn't. ids = new Parameters().addIds(rootOnlyMap.listKeyIds(Project.class)); q = new PojosGetImagesQueryDefinition(new Parameters(ids).addAll( noFilter).addClass(Project.class)); list = (List) iQuery.execute(q); assertTrue(list.size() == rootOnlyMap.listAllObjects(Project.class) .size()); q = new PojosGetImagesQueryDefinition(new Parameters(ids).addAll( filterForUser).addClass(Project.class)); list = (List) iQuery.execute(q); assertTrue(list.size() + " not 0", list.size() == 0); } @Test(groups = { "ticket:177", /* ? */"ticket:350" }) public void testGetImagesReturnsDefaultPixels() throws Exception { Pixels p = ObjectFactory.createPixelGraph(null); Image i = iUpdate.saveAndReturnObject(p.getImage()); i = iQuery.findByQuery( "select i from Image i left outer join fetch i.pixels p " + "where p.id = :id and index(p) = 0", new Parameters() .addId(p.getId())); assertNotNull(i.getPrimaryPixels()); Dataset d = new Dataset(); d.setName("ticket:177"); d.putAt(Dataset.IMAGELINKS, new HashSet()); i.putAt(Image.DATASETLINKS, new HashSet()); d.linkImage(i); d = iUpdate.saveAndReturnObject(d); q = new PojosGetImagesQueryDefinition(new Parameters(new Filter() .unique()).addClass(Dataset.class).addIds( Collections.singleton(d.getId()))); Image test = (Image) iQuery.execute(q); assertNotNull(test.getPrimaryPixels()); } @Test(groups = { "ticket:221" }) public void testGetImagesReturnsNoNulls() throws Exception { Dataset d = new Dataset(); d.setName("ticket:221"); Image i = new Image(); i.setName("ticket:221"); Pixels p = ObjectFactory.createPixelGraph(null); i.addPixels(p); d.linkImage(i); d = iUpdate.saveAndReturnObject(d); q = new PojosGetImagesQueryDefinition(new Parameters(new Filter() .unique()).addClass(Dataset.class).addIds( Collections.singleton(d.getId()))); Image test = (Image) iQuery.execute(q); assertNotNull(test); assertNotNull(test.getPrimaryPixels()); assertNotNull(test.getPrimaryPixels().getPixelsType()); } @Test(groups = { "ticket:296" }) public void testGetImagesTakesImageClass() throws Exception { Image i = new Image(); i.setName("ticket:296"); i = iUpdate.saveAndReturnObject(i); q = new PojosGetImagesQueryDefinition(new Parameters(new Filter() .unique()).addClass(Image.class).addIds( Collections.singleton(i.getId()))); Image test = (Image) iQuery.execute(q); assertNotNull(test); assertEquals(i.getId(), test.getId()); } @Test(groups = { "ticket:172" }) public void testGetImagesReturnsEventTimes() throws Exception { Image i = new Image(); i.setName("ticket:172"); i = iUpdate.saveAndReturnObject(i); q = new PojosGetImagesQueryDefinition(new Parameters(new Filter() .unique()).addClass(Image.class).addIds( Collections.singleton(i.getId()))); Image test = (Image) iQuery.execute(q); assertNotNull(test.getDetails().getCreationEvent().getTime()); assertNotNull(test.getDetails().getUpdateEvent().getTime()); } @Test(groups = { "CollectionsCounts" }) public void testGetImagesShouldReturnCountsOnAnnotations() { long self = iAdmin.getEventContext().getCurrentUserId(); Dataset d = new Dataset(); d.setName("CollectionCounts"); Image i = new Image(); i.setName("CollectionCounts"); TimestampAnnotation ta = new TimestampAnnotation(); ta.setNs("CollectionCounts"); ta.setTimeValue(new Timestamp(System.currentTimeMillis())); i.linkAnnotation(ta); i.linkDataset(d); i = iUpdate.saveAndReturnObject(i); q = new PojosGetImagesQueryDefinition(new Parameters(new Filter() .unique()).addClass(Image.class).addIds( Collections.singleton(i.getId()))); Image test = (Image) iQuery.execute(q); assertNotNull(test.getAnnotationLinksCountPerOwner()); assertNotNull(test.getAnnotationLinksCountPerOwner().get(self)); assertNotNull(test.getDatasetLinksCountPerOwner()); assertNotNull(test.getDatasetLinksCountPerOwner().get(self)); } // ~ Helpers // ========================================================================= private void setUser(Experimenter e, IObject... objs) { for (IObject object : objs) { object.getDetails().setOwner(e); } } // TODO refactor to ObjectFactory private Project createProject() { Project p1 = new Project(); p1.setName(this.getClass().getName()); return iUpdate.saveAndReturnObject(p1); } private Dataset createDataset() { Dataset d1 = new Dataset(); d1.setName(this.getClass().getName()); return iUpdate.saveAndReturnObject(d1); } private Image createImage() { Image i1 = new Image(); i1.setName(this.getClass().getName()); return iUpdate.saveAndReturnObject(i1); } private class MAP { // TODO possibly simplfy in that this contains only one class // a la generics, since that seems to be the use case. private final Map<Class, Map<Long, Set<IObject>>> m = new HashMap<Class, Map<Long, Set<IObject>>>(); public void put(IObject source, IObject target) { assert source != null; assert target != null; assert source.getId() != null; Map<Long, Set<IObject>> i = m.get(source.getClass()); if (i == null) { i = new HashMap<Long, Set<IObject>>(); m.put(source.getClass(), i); } Set<IObject> s = i.get(source.getId()); if (s == null) { s = new HashSet<IObject>(); i.put(source.getId(), s); } s.add(target); } public Set<IObject> get(IObject source) { assert source != null; assert source.getId() != null; Map<Long, Set<IObject>> i = m.get(source.getClass()); if (i != null) { Set<IObject> s = i.get(source.getId()); if (s == null) { return new HashSet<IObject>(); } return s; } return null; } public Set<IObject> get(Class sourceClass, Long id) { assert sourceClass != null; assert id != null; Map<Long, Set<IObject>> i = m.get(sourceClass); if (i != null) { Set<IObject> s = i.get(id); if (s == null) { return new HashSet<IObject>(); } return s; } return null; } public Set<Long> listKeyIds(Class sourceClass) { assert sourceClass != null; Map<Long, Set<IObject>> i = m.get(sourceClass); if (i != null) { return i.keySet(); } return new HashSet<Long>(); } public Set<IObject> listAllObjects(Class sourceClass) { assert sourceClass != null; Set<Long> s = listKeyIds(sourceClass); Set<IObject> result = new HashSet<IObject>(); for (Long l : s) { result.addAll(this.get(sourceClass, l)); } return result; } } }