diff --git a/components/blitz/src/omero/gateway/facility/ROIFacility.java b/components/blitz/src/omero/gateway/facility/ROIFacility.java index d7e96c18c9b..36ff2560492 100644 --- a/components/blitz/src/omero/gateway/facility/ROIFacility.java +++ b/components/blitz/src/omero/gateway/facility/ROIFacility.java @@ -702,8 +702,8 @@ public Collection saveROIs(SecurityContext ctx, long imageID, for (int i = 0 ; i < serverRoi.sizeOfShapes(); i++) { s = serverRoi.getShape(i); if (s != null) { - z = 0; - t = 0; + z = -1; + t = -1; if (s.getTheZ() != null) z = s.getTheZ().getValue(); if (s.getTheT() != null) t = s.getTheT().getValue(); serverCoordMap.put(new ROICoordinate(z, t), s); diff --git a/components/blitz/src/omero/gateway/model/LineData.java b/components/blitz/src/omero/gateway/model/LineData.java index 544454b163c..f2995ac58d5 100644 --- a/components/blitz/src/omero/gateway/model/LineData.java +++ b/components/blitz/src/omero/gateway/model/LineData.java @@ -100,6 +100,7 @@ public void setText(String text) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setTextValue(rtypes.rstring(text)); + setDirty(true); } /** @@ -128,6 +129,7 @@ public void setX1(double x1) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setX1(rtypes.rdouble(x1)); + setDirty(true); } /** @@ -156,6 +158,7 @@ public void setX2(double x2) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setX2(rtypes.rdouble(x2)); + setDirty(true); } /** @@ -184,6 +187,7 @@ public void setY1(double y1) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setY1(rtypes.rdouble(y1)); + setDirty(true); } /** @@ -212,6 +216,7 @@ public void setY2(double y2) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setY2(rtypes.rdouble(y2)); + setDirty(true); } } diff --git a/components/blitz/src/omero/gateway/model/MaskData.java b/components/blitz/src/omero/gateway/model/MaskData.java index d0a5159aac5..f4471dc9723 100644 --- a/components/blitz/src/omero/gateway/model/MaskData.java +++ b/components/blitz/src/omero/gateway/model/MaskData.java @@ -107,6 +107,7 @@ public void setText(String text) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setTextValue(rtypes.rstring(text)); + setDirty(true); } /** @@ -135,6 +136,7 @@ public void setX(double x) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setX(rtypes.rdouble(x)); + setDirty(true); } /** @@ -163,6 +165,7 @@ public void setY(double y) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setY(rtypes.rdouble(y)); + setDirty(true); } /** @@ -191,6 +194,7 @@ public void setWidth(double width) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setWidth(rtypes.rdouble(width)); + setDirty(true); } /** @@ -219,6 +223,7 @@ public void setHeight(double height) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setHeight(rtypes.rdouble(height)); + setDirty(true); } /** @@ -230,6 +235,7 @@ public void setMask(byte[] mask) { Mask shape = (Mask) asIObject(); shape.setBytes(mask); + setDirty(true); } /** @@ -255,6 +261,7 @@ public void setMask(BufferedImage image) } setBit(data, (int)(y*getWidth()+x), 1); } + setDirty(true); } /** @@ -343,6 +350,7 @@ public void setBit(byte[] data, int bit, int val) data[bytePosition] = (byte) ((byte)(data[bytePosition]& (~(byte)(0x1< points) String pointsValues = toPoints(points.toArray(new Point2D.Double[points.size()])); shape.setPoints(rtypes.rstring(pointsValues)); + setDirty(true); } } diff --git a/components/blitz/src/omero/gateway/model/PolylineData.java b/components/blitz/src/omero/gateway/model/PolylineData.java index 1f7a1454072..55d25e2cb51 100644 --- a/components/blitz/src/omero/gateway/model/PolylineData.java +++ b/components/blitz/src/omero/gateway/model/PolylineData.java @@ -100,6 +100,7 @@ public void setText(String text) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setTextValue(rtypes.rstring(text)); + setDirty(true); } /** @@ -129,5 +130,6 @@ public void setPoints(List points) String pointsValues = toPoints(points.toArray(new Point2D.Double[points.size()])); shape.setPoints(rtypes.rstring(pointsValues)); + setDirty(true); } } diff --git a/components/blitz/src/omero/gateway/model/ROICoordinate.java b/components/blitz/src/omero/gateway/model/ROICoordinate.java index f49108bb451..7810b2e8a05 100644 --- a/components/blitz/src/omero/gateway/model/ROICoordinate.java +++ b/components/blitz/src/omero/gateway/model/ROICoordinate.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2006-2009 University of Dundee. All rights reserved. + * Copyright (C) 2006-2018 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify @@ -58,8 +58,8 @@ public ROICoordinate() /** * Creates a new instance. * - * @param z The z-section. - * @param t The timepoint. + * @param z The z-section. (-1 == all z-sections) + * @param t The timepoint. (-1 == all timepoints) */ public ROICoordinate(int z, int t) { @@ -69,14 +69,14 @@ public ROICoordinate(int z, int t) /** * Returns the timepoint. - * + * (-1 == all timepoints) * @return See above. */ public int getTimePoint() { return t; } /** * Returns the z-section. - * + * (-1 == all z-sections) * @return See above. */ public int getZSection() { return z; } @@ -84,7 +84,6 @@ public ROICoordinate(int z, int t) /** * Implemented as specified by the {@link Comparator} I/F. * @see Comparator#compare(Object, Object) - * If any attribute == -1 it is not included in comparison. */ public int compare(Object o1, Object o2) { @@ -101,7 +100,6 @@ public int compare(Object o1, Object o2) /** * Overridden to control if the passed object equals the current one. - * If any attribute == -1 it is not included in comparison. * @see java.lang.Object#equals(Object) */ public boolean equals(Object obj) diff --git a/components/blitz/src/omero/gateway/model/ROIData.java b/components/blitz/src/omero/gateway/model/ROIData.java index 4fbf29b6e71..ad89cd7463c 100644 --- a/components/blitz/src/omero/gateway/model/ROIData.java +++ b/components/blitz/src/omero/gateway/model/ROIData.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2006-2016 University of Dundee. All rights reserved. + * Copyright (C) 2006-2018 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify @@ -207,17 +207,21 @@ public void removeShapeData(ShapeData shape) if (roi == null) throw new IllegalArgumentException("No Roi specified."); ROICoordinate coord = shape.getROICoordinate(); - List shapeList; - shapeList = roiShapes.get(coord); - shapeList.remove(shape); - roi.removeShape((Shape) shape.asIObject()); - setDirty(true); + List shapeList = roiShapes.get(coord); + if (shapeList != null) { + shapeList.remove(shape); + roi.removeShape((Shape) shape.asIObject()); + setDirty(true); + } } /** * Returns the number of planes occupied by the ROI. * * @return See above. + * @deprecated Will be removed in future. Does not work as + * expected if the ROI contains shapes which are associated + * with all planes (Z, C, T == -1) */ public int getPlaneCount() { return roiShapes.size(); } @@ -247,7 +251,19 @@ public int getShapeCount() */ public List getShapes(int z, int t) { - return roiShapes.get(new ROICoordinate(z, t)); + List res = roiShapes.get(new ROICoordinate(z, t)); + if (res == null) + res = new ArrayList(); + List allZT = roiShapes.get(new ROICoordinate(-1, -1)); + if (allZT != null) + res.addAll(allZT); + List allZ = roiShapes.get(new ROICoordinate(-1, t)); + if (allZ != null) + res.addAll(allZ); + List allT = roiShapes.get(new ROICoordinate(z, -1)); + if (allT != null) + res.addAll(allT); + return res; } /** @@ -260,38 +276,53 @@ public Iterator> getIterator() return roiShapes.values().iterator(); } - /** + /** * Return the first plane that the ROI starts on. * * @return See above. + * @deprecated Will be removed in future. Does not work as + * expected if the ROI contains shapes which are associated + * with all planes (Z, C, T == -1) */ - public ROICoordinate firstPlane() - { + public ROICoordinate firstPlane() { return roiShapes.firstKey(); } - /** + /** * Returns the last plane that the ROI ends on. * * @return See above. + * @deprecated Will be removed in future. Does not work as + * expected if the ROI contains shapes which are associated + * with all planes (Z, C, T == -1) */ - public ROICoordinate lastPlane() - { + public ROICoordinate lastPlane() { return roiShapes.lastKey(); } /** * Returns an iterator of the Shapes in the ROI in the range [start, end]. * - * @param start The starting plane where the Shapes should reside. - * @param end The final plane where the Shapes should reside. + * @param start + * The starting plane where the Shapes should reside. + * @param end + * The final plane where the Shapes should reside. * @return See above. + * @deprecated Will be removed in future. Does not work as + * expected if the ROI contains shapes which are associated + * with all planes (Z, C, T == -1) */ public Iterator> getShapesInRange(ROICoordinate start, - ROICoordinate end) - { - return roiShapes.subMap(start, end).values().iterator(); - } + ROICoordinate end) { + List> res = new ArrayList>(); + Collection> inRange = roiShapes.subMap(start, end).values(); + if (inRange != null) + res.addAll(inRange); + List allRanges = roiShapes.get(new ROICoordinate(-1, -1)); + if (allRanges != null) + res.add(allRanges); + return res.iterator(); + } /** * Returns true if the object a client-side object, diff --git a/components/blitz/src/omero/gateway/model/RectangleData.java b/components/blitz/src/omero/gateway/model/RectangleData.java index 04e5e846ca2..f0acd09800e 100644 --- a/components/blitz/src/omero/gateway/model/RectangleData.java +++ b/components/blitz/src/omero/gateway/model/RectangleData.java @@ -100,6 +100,7 @@ public void setText(String text) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setTextValue(rtypes.rstring(text)); + setDirty(true); } /** @@ -130,6 +131,7 @@ public void setX(double x) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setX(rtypes.rdouble(x)); + setDirty(true); } /** @@ -160,6 +162,7 @@ public void setY(double y) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setY(rtypes.rdouble(y)); + setDirty(true); } /** @@ -188,6 +191,7 @@ public void setWidth(double width) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setWidth(rtypes.rdouble(width)); + setDirty(true); } /** @@ -216,6 +220,7 @@ public void setHeight(double height) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setHeight(rtypes.rdouble(height)); + setDirty(true); } } diff --git a/components/blitz/src/omero/gateway/model/ShapeData.java b/components/blitz/src/omero/gateway/model/ShapeData.java index babe2da3a40..070d16d6ec2 100644 --- a/components/blitz/src/omero/gateway/model/ShapeData.java +++ b/components/blitz/src/omero/gateway/model/ShapeData.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2006-2015 University of Dundee. All rights reserved. + * Copyright (C) 2006-2018 University of Dundee. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -267,7 +267,8 @@ public void setClientObject(boolean clientObject) } /** - * Returns the z-section. + * Returns the z-section. -1 if the shape applies to all z-sections of + * the image. * * @return See above. */ @@ -284,20 +285,25 @@ public int getZ() /** * Sets the z-section. * - * @param z The value to set. + * @param z + * The value to set. Pass -1 to remove z value, i. e. shape + * applies to all z-sections of the image. */ public void setZ(int z) { Shape shape = (Shape) asIObject(); if (shape == null) throw new IllegalArgumentException("No shape specified."); - if (z < 0) z = 0; - shape.setTheZ(rtypes.rint(z)); + if (z < 0) + shape.setTheZ(null); + else + shape.setTheZ(rtypes.rint(z)); setDirty(true); } /** - * Returns the channel. + * Returns the channel. -1 if the shape applies to all channels of + * the image. * * @return See above. */ @@ -314,21 +320,26 @@ public int getC() /** * Sets the channel. * - * @param c The value to set. + * @param c + * The value to set. Pass -1 to remove c value, i. e. shape + * applies to all channels of the image. */ public void setC(int c) { Shape shape = (Shape) asIObject(); if (shape == null) throw new IllegalArgumentException("No shape specified."); - if (c < 0) c = 0; - shape.setTheC(rtypes.rint(c)); + if (c < 0) + shape.setTheC(null); + else + shape.setTheC(rtypes.rint(c)); setDirty(true); } /** - * Returns the time-point. + * Returns the time-point. -1 if the shape applies to all time-points of + * the image. * * @return See above. */ @@ -345,15 +356,19 @@ public int getT() /** * Sets the time-point. * - * @param t The value to set. + * @param t + * The value to set. Pass -1 to remove t value, i. e. shape + * applies to all time-points of the image. */ public void setT(int t) { Shape shape = (Shape) asIObject(); if (shape == null) throw new IllegalArgumentException("No shape specified."); - if (t < 0) t = 0; - shape.setTheT(rtypes.rint(t)); + if (t < 0) + shape.setTheT(null); + else + shape.setTheT(rtypes.rint(t)); setDirty(true); } @@ -386,7 +401,6 @@ public ROICoordinate getROICoordinate() throw new IllegalArgumentException("No shape specified."); int z = getZ(); int t = getT(); - if (z < 0 || t < 0) return null; return new ROICoordinate(z, t); } diff --git a/components/blitz/src/omero/gateway/model/TextData.java b/components/blitz/src/omero/gateway/model/TextData.java index 2faa3d1d460..c437e5c8910 100644 --- a/components/blitz/src/omero/gateway/model/TextData.java +++ b/components/blitz/src/omero/gateway/model/TextData.java @@ -99,6 +99,7 @@ public void setText(String text) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setTextValue(rtypes.rstring(text)); + setDirty(true); } /** @@ -127,6 +128,7 @@ public void setX(double x) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setX(rtypes.rdouble(x)); + setDirty(true); } /** @@ -155,6 +157,7 @@ public void setY(double y) if (shape == null) throw new IllegalArgumentException("No shape specified."); shape.setY(rtypes.rdouble(y)); + setDirty(true); } } \ No newline at end of file diff --git a/components/blitz/test/omero/gateway/model/ShapeTest.java b/components/blitz/test/omero/gateway/model/ShapeTest.java index b00685fc2a4..967531a0498 100644 --- a/components/blitz/test/omero/gateway/model/ShapeTest.java +++ b/components/blitz/test/omero/gateway/model/ShapeTest.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2017 University of Dundee & Open Microscopy Environment. + * Copyright (C) 2017-2018 University of Dundee & Open Microscopy Environment. * All rights reserved. * * @@ -23,13 +23,13 @@ import java.awt.geom.Point2D; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.testng.Assert; import org.testng.annotations.Test; - /** * Test the encoding of some shapes e.g. polyline * @author Jean-Marie Burel      @@ -88,4 +88,194 @@ public void testParsePointsWithComma() Assert.assertEquals(p.y, 4.0); } + private void testAndResetDirty(ShapeData s) { + Assert.assertTrue(s.isDirty()); + s.setDirty(false); + } + + @Test + public void testDirty() { + EllipseData s = new EllipseData(10, 10, 5, 5); + s.setDirty(false); + s.setX(1); + testAndResetDirty(s); + s.setY(1); + testAndResetDirty(s); + s.setRadiusX(1); + testAndResetDirty(s); + s.setRadiusY(1); + testAndResetDirty(s); + s.setText("bla"); + testAndResetDirty(s); + s.setC(2); + testAndResetDirty(s); + s.setT(2); + testAndResetDirty(s); + s.setT(2); + testAndResetDirty(s); + s.setC(-1); + testAndResetDirty(s); + s.setT(-1); + testAndResetDirty(s); + s.setT(-1); + testAndResetDirty(s); + + LineData l = new LineData(10, 10, 10, 10); + l.setDirty(false); + l.setX1(1); + testAndResetDirty(l); + l.setY1(1); + testAndResetDirty(l); + l.setX2(1); + testAndResetDirty(l); + l.setY2(1); + testAndResetDirty(l); + l.setText("bla"); + testAndResetDirty(l); + l.setC(2); + testAndResetDirty(l); + l.setT(2); + testAndResetDirty(l); + l.setT(2); + testAndResetDirty(l); + l.setC(-1); + testAndResetDirty(l); + l.setT(-1); + testAndResetDirty(l); + l.setT(-1); + testAndResetDirty(l); + + MaskData m = new MaskData(10, 10, 10, 10, new byte[10]); + m.setDirty(false); + m.setX(1); + testAndResetDirty(m); + m.setY(1); + testAndResetDirty(m); + m.setWidth(1); + testAndResetDirty(m); + m.setHeight(1); + testAndResetDirty(m); + m.setMask(new byte[10]); + testAndResetDirty(m); + m.setText("bla"); + testAndResetDirty(m); + m.setC(2); + testAndResetDirty(m); + m.setT(2); + testAndResetDirty(m); + m.setT(2); + testAndResetDirty(m); + m.setC(-1); + testAndResetDirty(m); + m.setT(-1); + testAndResetDirty(m); + m.setT(-1); + testAndResetDirty(m); + + PointData p = new PointData(10, 10); + p.setDirty(false); + p.setX(1); + testAndResetDirty(p); + p.setY(1); + testAndResetDirty(p); + p.setText("bla"); + testAndResetDirty(p); + p.setC(2); + testAndResetDirty(p); + p.setT(2); + testAndResetDirty(p); + p.setT(2); + testAndResetDirty(p); + p.setC(-1); + testAndResetDirty(p); + p.setT(-1); + testAndResetDirty(p); + p.setT(-1); + testAndResetDirty(p); + + List points = Arrays.asList(new Point2D.Double[]{new Point2D.Double(1,2), new Point2D.Double(2,3), new Point2D.Double(3,4), new Point2D.Double(4,5)}); + PolygonData pg = new PolygonData(points); + pg.setDirty(false); + pg.setPoints(points); + testAndResetDirty(pg); + pg.setText("bla"); + testAndResetDirty(pg); + pg.setC(2); + testAndResetDirty(pg); + pg.setT(2); + testAndResetDirty(pg); + pg.setT(2); + testAndResetDirty(pg); + pg.setC(-1); + testAndResetDirty(pg); + pg.setT(-1); + testAndResetDirty(pg); + pg.setT(-1); + testAndResetDirty(pg); + + PolylineData pl = new PolylineData(points); + pl.setDirty(false); + pl.setPoints(points); + testAndResetDirty(pl); + pl.setText("bla"); + testAndResetDirty(pl); + pl.setC(2); + testAndResetDirty(pl); + pl.setT(2); + testAndResetDirty(pl); + pl.setT(2); + testAndResetDirty(pl); + pl.setC(-1); + testAndResetDirty(pl); + pl.setT(-1); + testAndResetDirty(pl); + pl.setT(-1); + testAndResetDirty(pl); + + RectangleData r = new RectangleData(10, 10, 10, 10); + r.setDirty(false); + r.setX(1); + testAndResetDirty(r); + r.setY(1); + testAndResetDirty(r); + r.setWidth(1); + testAndResetDirty(r); + r.setHeight(1); + testAndResetDirty(r); + r.setText("bla"); + testAndResetDirty(r); + r.setC(2); + testAndResetDirty(r); + r.setT(2); + testAndResetDirty(r); + r.setT(2); + testAndResetDirty(r); + r.setC(-1); + testAndResetDirty(r); + r.setT(-1); + testAndResetDirty(r); + r.setT(-1); + testAndResetDirty(r); + + TextData t = new TextData("blup", 10, 10); + t.setDirty(false); + t.setX(1); + testAndResetDirty(t); + t.setY(1); + testAndResetDirty(t); + t.setText("bla"); + testAndResetDirty(t); + t.setC(2); + testAndResetDirty(t); + t.setT(2); + testAndResetDirty(t); + t.setT(2); + testAndResetDirty(t); + t.setC(-1); + testAndResetDirty(t); + t.setT(-1); + testAndResetDirty(t); + t.setT(-1); + testAndResetDirty(t); + } } diff --git a/components/blitz/test/omero/model/ROICoordinateTest.java b/components/blitz/test/omero/model/ROICoordinateTest.java new file mode 100644 index 00000000000..f24bb713b7c --- /dev/null +++ b/components/blitz/test/omero/model/ROICoordinateTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018 University of Dundee & Open Microscopy Environment. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package omero.model; + +import org.junit.Test; +import org.testng.Assert; + +import omero.gateway.model.ROICoordinate; + +public class ROICoordinateTest { + + public ROICoordinateTest() { + } + + @Test + public void testComparison() { + ROICoordinate c1 = new ROICoordinate(2, 10); + ROICoordinate c2 = new ROICoordinate(1, 11); + ROICoordinate c3 = new ROICoordinate(2, 11); + ROICoordinate c4 = new ROICoordinate(2, 11); + + Assert.assertTrue(c1.compare(c1, c2) == -1); + Assert.assertTrue(c1.compare(c2, c1) == 1); + + Assert.assertTrue(c1.compare(c2, c3) == -1); + Assert.assertTrue(c1.compare(c3, c2) == 1); + + Assert.assertTrue(c1.compare(c3, c4) == 0); + Assert.assertTrue(c1.compare(c4, c3) == 0); + + + ROICoordinate c5 = new ROICoordinate(-1, -1); + ROICoordinate c6 = new ROICoordinate(-1, -1); + + Assert.assertTrue(c1.compare(c5, c6) == 0); + Assert.assertTrue(c1.compare(c6, c5) == 0); + + Assert.assertTrue(c1.compare(c5, c1) == -1); + Assert.assertTrue(c1.compare(c1, c5) == 1); + } + + @Test + public void testHashEquals() { + ROICoordinate c1 = new ROICoordinate(4, 5); + ROICoordinate c2 = new ROICoordinate(4, 6); + ROICoordinate c3 = new ROICoordinate(3, 5); + ROICoordinate c4 = new ROICoordinate(3, 5); + + Assert.assertFalse(c1.equals(c2)); + Assert.assertFalse(c2.equals(c1)); + Assert.assertFalse(c1.hashCode() == c2.hashCode()); + + Assert.assertFalse(c1.equals(c3)); + Assert.assertFalse(c3.equals(c1)); + Assert.assertFalse(c3.hashCode() == c1.hashCode()); + + Assert.assertTrue(c3.equals(c4)); + Assert.assertTrue(c4.equals(c3)); + Assert.assertTrue(c3.hashCode() == c4.hashCode()); + + ROICoordinate c5 = new ROICoordinate(-1, -1); + ROICoordinate c6 = new ROICoordinate(-1, -1); + + Assert.assertTrue(c5.equals(c6)); + Assert.assertTrue(c6.equals(c5)); + Assert.assertTrue(c5.hashCode() == c6.hashCode()); + + Assert.assertFalse(c5.equals(c4)); + Assert.assertFalse(c4.equals(c5)); + Assert.assertFalse(c5.hashCode() == c4.hashCode()); + } + + +} diff --git a/components/blitz/test/omero/model/ROIDataTest.java b/components/blitz/test/omero/model/ROIDataTest.java new file mode 100644 index 00000000000..42dd8b1de04 --- /dev/null +++ b/components/blitz/test/omero/model/ROIDataTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2018 University of Dundee & Open Microscopy Environment. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +package omero.model; + +import omero.gateway.model.ROIData; +import omero.gateway.model.RectangleData; + +import org.junit.Test; +import org.testng.Assert; + +public class ROIDataTest { + + public ROIDataTest() { + } + + @Test + public void testGetShapes() { + ROIData roi = new ROIData(); + + RectangleData allZT = new RectangleData(1, 5, 10, 10); + allZT.setT(-1); + allZT.setZ(-1); + roi.addShapeData(allZT); + System.out.println("allZT: " + allZT); + + RectangleData allZ = new RectangleData(2, 5, 10, 10); + allZ.setT(2); + allZ.setZ(-1); + roi.addShapeData(allZ); + System.out.println("allZT: " + allZT); + + RectangleData allT = new RectangleData(3, 5, 10, 10); + allT.setT(-1); + allT.setZ(2); + roi.addShapeData(allT); + System.out.println("allZT: " + allZT); + + RectangleData r = new RectangleData(4, 5, 10, 10); + r.setT(3); + r.setZ(3); + roi.addShapeData(r); + + // all shapes + Assert.assertEquals(roi.getShapeCount(), 4); + + // just allZT + Assert.assertEquals(roi.getShapes(1, 1).size(), 1); + Assert.assertEquals(roi.getShapes(1, 1).iterator().next(), allZT); + + // allZT and allZ at t=2 + Assert.assertEquals(roi.getShapes(1, 2).size(), 2); + Assert.assertTrue(roi.getShapes(1, 2).contains(allZT)); + Assert.assertTrue(roi.getShapes(1, 2).contains(allZ)); + + // allZT and allT at z=2 + Assert.assertEquals(roi.getShapes(2, 1).size(), 2); + Assert.assertTrue(roi.getShapes(2, 1).contains(allZT)); + Assert.assertTrue(roi.getShapes(2, 1).contains(allT)); + + // r and allZT + Assert.assertEquals(roi.getShapes(3, 3).size(), 2); + Assert.assertTrue(roi.getShapes(3, 3).contains(r)); + Assert.assertTrue(roi.getShapes(3, 3).contains(allZT)); + } + +} diff --git a/components/tools/OmeroJava/test/integration/gateway/ROIFacilityTest.java b/components/tools/OmeroJava/test/integration/gateway/ROIFacilityTest.java index 501c23ab539..c4915cc069b 100644 --- a/components/tools/OmeroJava/test/integration/gateway/ROIFacilityTest.java +++ b/components/tools/OmeroJava/test/integration/gateway/ROIFacilityTest.java @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------------------ - * Copyright (C) 2015-2016 University of Dundee. All rights reserved. + * Copyright (C) 2015-2018 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify @@ -40,6 +40,7 @@ import omero.model.IObject; import omero.model.PixelsType; import omero.model.Roi; +import omero.model.Shape; import org.testng.Assert; import org.testng.annotations.BeforeClass; @@ -49,6 +50,7 @@ import omero.gateway.model.ImageData; import omero.gateway.model.ROIData; import omero.gateway.model.RectangleData; +import omero.gateway.model.ShapeData; /** * @@ -83,13 +85,32 @@ public void testSaveROIs() throws DSOutOfServiceException, rois = new ArrayList(); rois.add(createRectangleROI(0, 0, 10, 10)); rois.add(createRectangleROI(11, 11, 10, 10)); - rois = roifac.saveROIs(rootCtx, img.getId(), rois); + rois.add(createRectangleROI(12, 12, 10, 10, false)); + rois.add(createRectangleROI(13, 13, 10, 10, true)); + + Collection saved = roifac.saveROIs(rootCtx, img.getId(), rois); - Assert.assertEquals(rois.size(), 2); - for (ROIData roi : rois) { + Assert.assertEquals(saved.size(), rois.size()); + Assert.assertEquals(getShapes(saved).size(), getShapes(rois).size()); + for (ROIData roi : saved) { Assert.assertTrue(roi.getId() >= 0); } - } + + // check that ZCT correctly saved: + List shapes = getShapes(saved); + for (ShapeData shape : shapes) { + if (shape.getROICoordinate().getTimePoint() == -1) + Assert.assertNull(((Shape) shape.asIObject()).getTheT()); + else + Assert.assertNotNull(((Shape) shape.asIObject()).getTheT()); + if (shape.getROICoordinate().getZSection() == -1) + Assert.assertNull(((Shape) shape.asIObject()).getTheZ()); + else + Assert.assertNotNull(((Shape) shape.asIObject()).getTheZ()); + } + + rois = saved; + } @Test public void testSaveImagelessROIs() throws DSOutOfServiceException, @@ -102,19 +123,12 @@ public void testSaveImagelessROIs() throws DSOutOfServiceException, Assert.assertTrue(r.getId() >= 0); Assert.assertNull(r.getImage() ); } - - private ROIData createRectangleROI(int x, int y, int w, int h) { - ROIData roiData = new ROIData(); - RectangleData rectangle = new RectangleData(x, y, w, h); - roiData.addShapeData(rectangle); - return roiData; - } @Test(dependsOnMethods = { "testSaveROIs" }) public void testGetROICount() throws DSOutOfServiceException, DSAccessException { int n = roifac.getROICount(rootCtx, img.getId()); - Assert.assertEquals(2, n); + Assert.assertEquals(rois.size(), n); } @Test(dependsOnMethods = { "testSaveROIs" }) @@ -128,16 +142,7 @@ public void testLoadROIs() throws DSOutOfServiceException, Assert.assertEquals(myRois.size(), rois.size()); - Iterator it = myRois.iterator(); - while (it.hasNext()) { - ROIData r = it.next(); - for (ROIData r2 : rois) { - if (r2.getId() == r.getId()) - it.remove(); - } - } - - Assert.assertTrue(myRois.isEmpty()); + compare(myRois, rois); } @Test @@ -252,6 +257,29 @@ private void initData() throws Exception { folder = createRoiFolder(rootCtx, folderRois); } + private ROIData createRectangleROI(int x, int y, int w, int h) { + return createRectangleROI(x, y, w, h, null); + } + + private ROIData createRectangleROI(int x, int y, int w, int h, Boolean plane) { + ROIData roiData = new ROIData(); + RectangleData rectangle = new RectangleData(x, y, w, h); + if (plane != null) { + if (plane) { + rectangle.setC(1); + rectangle.setZ(1); + rectangle.setT(1); + } + else { + rectangle.setC(-1); + rectangle.setZ(-1); + rectangle.setT(-1); + } + } + roiData.addShapeData(rectangle); + return roiData; + } + private FolderData createRoiFolder(SecurityContext ctx, Collection rois) throws DSOutOfServiceException, DSAccessException { @@ -263,4 +291,38 @@ private FolderData createRoiFolder(SecurityContext ctx, return (FolderData) datamanagerFacility .saveAndReturnObject(ctx, folder); } + + private void compare(Collection list1, Collection list2) { + List shapes1 = getShapes(list1); + List shapes2 = getShapes(list2); + + Assert.assertEquals(shapes1.size(), shapes2.size()); + + Iterator it1 = shapes1.iterator(); + while(it1.hasNext()) { + ShapeData s1 = it1.next(); + + Iterator it2 = shapes2.iterator(); + while(it2.hasNext()) { + ShapeData s2 = it2.next(); + if(s1.getId() == s2.getId()) { + Assert.assertEquals(s1.getROICoordinate(), s2.getROICoordinate()); + it2.remove(); + break; + } + } + } + + Assert.assertTrue(shapes2.isEmpty()); + } + + private List getShapes(Collection rois) { + List res = new ArrayList(); + for(ROIData r : rois) { + Iterator> sit = r.getIterator(); + while(sit.hasNext()) + res.addAll(sit.next()); + } + return res; + } }