1 /* 2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4263142 4172661 27 * @summary First run verifies that objects serialize and deserialize 28 * correctly against the current release. 29 * Second run verifies that objects from previous releases 30 * still deserialize correctly. The serial_1_6.out file was 31 * created using the "write" option under release 1.6. 32 * The test was modified after fixing 4172661 to add testing 33 * of Path2D serialization (and to recut the test file with 34 * the new serialVersionUID of GeneralPath). 35 * @run main SerialTest 36 * @run main SerialTest read serial_1_6.out 37 */ 38 39 import java.awt.Shape; 40 import java.awt.geom.AffineTransform; 41 import java.awt.geom.Arc2D; 42 import java.awt.geom.CubicCurve2D; 43 import java.awt.geom.Ellipse2D; 44 import java.awt.geom.GeneralPath; 45 import java.awt.geom.Line2D; 46 import java.awt.geom.Path2D; 47 import java.awt.geom.PathIterator; 48 import java.awt.geom.Point2D; 49 import java.awt.geom.QuadCurve2D; 50 import java.awt.geom.Rectangle2D; 51 import java.awt.geom.RoundRectangle2D; 52 import java.io.ByteArrayInputStream; 53 import java.io.ByteArrayOutputStream; 54 import java.io.File; 55 import java.io.FileInputStream; 56 import java.io.FileOutputStream; 57 import java.io.IOException; 58 import java.io.InputStream; 59 import java.io.ObjectInputStream; 60 import java.io.ObjectOutputStream; 61 import java.io.OutputStream; 62 63 public class SerialTest { 64 public static Object testobjects[] = { 65 // non-shapes... 66 new Point2D.Float(37, 42), 67 new Point2D.Double(85, 63), 68 new AffineTransform(10, 20, 30, 40, 50, 60), 69 70 // shapes... 71 new QuadCurve2D.Float(10f, 10f, 50f, 50f, 100f, 10f), 72 new QuadCurve2D.Double(20f, 20f, 50f, 50f, 100f, 20f), 73 new CubicCurve2D.Float(10f, 10f, 50f, 10f, 10f, 50f, 50f, 50f), 74 new CubicCurve2D.Double(0.0, 0.0, 50.0, 0.0, 0.0, 50.0, 50.0, 50.0), 75 new GeneralPath(), 76 new GeneralPath(PathIterator.WIND_NON_ZERO), 77 new GeneralPath(PathIterator.WIND_EVEN_ODD), 78 makeGeneralPath(PathIterator.WIND_NON_ZERO, 5f), 79 makeGeneralPath(PathIterator.WIND_EVEN_ODD, 23f), 80 new Line2D.Float(20f, 20f, 25f, 50f), 81 new Line2D.Double(20.0, 20.0, 35.0, 50.0), 82 new Rectangle2D.Float(100f, 100f, 50f, 25f), 83 new Rectangle2D.Double(200.0, 200.0, 75.0, 35.0), 84 new RoundRectangle2D.Float(120f, 120f, 50f, 35f, 5f, 7f), 85 new RoundRectangle2D.Double(220.0, 220.0, 85.0, 45.0, 3.0, 9.0), 86 new Ellipse2D.Float(110f, 110f, 50f, 55f), 87 new Ellipse2D.Double(210.0, 210.0, 75.0, 45.0), 88 new Arc2D.Float(10f, 10f, 50f, 40f, 45f, 72f, Arc2D.OPEN), 89 new Arc2D.Float(10f, 10f, 40f, 50f, 135f, 72f, Arc2D.PIE), 90 new Arc2D.Float(10f, 10f, 40f, 60f, 225f, 72f, Arc2D.CHORD), 91 new Arc2D.Double(10.0, 20.0, 50.0, 40.0, 45.0, 72.0, Arc2D.OPEN), 92 new Arc2D.Double(10.0, 20.0, 40.0, 50.0, 135.0, 72.0, Arc2D.PIE), 93 new Arc2D.Double(10.0, 20.0, 40.0, 60.0, 225.0, 72.0, Arc2D.CHORD), 94 95 // Paths 96 new Path2D.Float(), 97 new Path2D.Float(PathIterator.WIND_NON_ZERO), 98 new Path2D.Float(PathIterator.WIND_EVEN_ODD), 99 makePath2DFloat(PathIterator.WIND_NON_ZERO, 5f), 100 makePath2DFloat(PathIterator.WIND_EVEN_ODD, 23f), 101 new Path2D.Double(), 102 new Path2D.Double(PathIterator.WIND_NON_ZERO), 103 new Path2D.Double(PathIterator.WIND_EVEN_ODD), 104 makePath2DDouble(PathIterator.WIND_NON_ZERO, 5f), 105 makePath2DDouble(PathIterator.WIND_EVEN_ODD, 23f), 106 }; 107 makeGeneralPath(int winding, float off)108 public static Shape makeGeneralPath(int winding, float off) { 109 return fill(new GeneralPath(winding), off); 110 } 111 makePath2DFloat(int winding, float off)112 public static Shape makePath2DFloat(int winding, float off) { 113 return fill(new Path2D.Float(winding), off); 114 } 115 makePath2DDouble(int winding, float off)116 public static Shape makePath2DDouble(int winding, float off) { 117 return fill(new Path2D.Double(winding), off); 118 } 119 fill(Path2D p2d, float off)120 public static Path2D fill(Path2D p2d, float off) { 121 p2d.moveTo(off+10, off+10); 122 p2d.lineTo(off+100, off+50); 123 p2d.quadTo(off+50, off+100, off+200, off+100); 124 p2d.curveTo(off+400, off+20, off+20, off+400, off+100, off+100); 125 p2d.closePath(); 126 return p2d; 127 } 128 129 static int numerrors; 130 error(Object o1, Object o2, String reason)131 public static void error(Object o1, Object o2, String reason) { 132 System.err.println("Failed comparing: "+o1+" to "+o2); 133 System.err.println(reason); 134 numerrors++; 135 } 136 usage(int exitcode)137 public static void usage(int exitcode) { 138 System.err.println("usage: java SerialTest [read|write] <filename>"); 139 System.exit(exitcode); 140 } 141 main(String argv[])142 public static void main(String argv[]) { 143 if (argv.length > 0) { 144 if (argv.length < 2) { 145 usage(1); 146 } 147 148 String arg = argv[0].toLowerCase(); 149 if (arg.equals("write")) { 150 serializeTo(argv[1]); 151 } else if (arg.equals("read")) { 152 testFrom(argv[1]); 153 } else { 154 usage(1); 155 } 156 } else { 157 testSerial(); 158 } 159 } 160 makeFile(String filename)161 public static File makeFile(String filename) { 162 return new File(System.getProperty("test.src", "."), filename); 163 } 164 serializeTo(String filename)165 public static void serializeTo(String filename) { 166 FileOutputStream fos; 167 try { 168 fos = new FileOutputStream(makeFile(filename)); 169 } catch (IOException ioe) { 170 throw new InternalError("bad output filename: "+filename); 171 } 172 serializeTo(fos); 173 } 174 testFrom(String filename)175 public static void testFrom(String filename) { 176 FileInputStream fis; 177 try { 178 fis = new FileInputStream(makeFile(filename)); 179 } catch (IOException ioe) { 180 throw new InternalError("bad input filename: "+filename); 181 } 182 testFrom(fis); 183 } 184 testSerial()185 public static void testSerial() { 186 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 187 serializeTo(baos); 188 189 byte buf[] = baos.toByteArray(); 190 ByteArrayInputStream bais = new ByteArrayInputStream(buf); 191 192 testFrom(bais); 193 } 194 serializeTo(OutputStream os)195 public static void serializeTo(OutputStream os) { 196 try { 197 ObjectOutputStream oos = new ObjectOutputStream(os); 198 199 for (Object o1: testobjects) { 200 oos.writeObject(o1); 201 } 202 203 oos.close(); 204 } catch (IOException ioe) { 205 throw new RuntimeException(ioe); 206 } 207 } 208 testFrom(InputStream is)209 public static void testFrom(InputStream is) { 210 try { 211 ObjectInputStream ois = new ObjectInputStream(is); 212 213 for (Object o1: testobjects) { 214 Object o2 = ois.readObject(); 215 if (o1 instanceof Shape) { 216 compareShapes((Shape) o1, (Shape) o2); 217 } else { 218 if (!o1.equals(o2)) { 219 error(o1, o2, "objects not equal"); 220 } 221 } 222 } 223 224 try { 225 ois.readObject(); 226 throw new RuntimeException("extra data in stream"); 227 } catch (IOException ioe2) { 228 } 229 } catch (IOException ioe) { 230 throw new RuntimeException(ioe); 231 } catch (ClassNotFoundException cnfe) { 232 throw new RuntimeException(cnfe); 233 } 234 } 235 compareShapes(Shape s1, Shape s2)236 public static void compareShapes(Shape s1, Shape s2) { 237 PathIterator pi1 = s1.getPathIterator(null); 238 PathIterator pi2 = s2.getPathIterator(null); 239 240 if (pi1.getWindingRule() != pi2.getWindingRule()) { 241 error(s1, s2, "winding rules are different"); 242 } 243 244 double coords1[] = new double[6]; 245 double coords2[] = new double[6]; 246 247 while (!pi1.isDone()) { 248 if (pi2.isDone()) { 249 error(s1, s2, "Shape 2 ended prematurely"); 250 return; 251 } 252 253 int t1 = pi1.currentSegment(coords1); 254 int t2 = pi2.currentSegment(coords2); 255 256 if (t1 != t2) { 257 error(s1, s2, "different segment types"); 258 } 259 260 int ncoords; 261 switch (t1) { 262 case PathIterator.SEG_MOVETO: ncoords = 2; break; 263 case PathIterator.SEG_LINETO: ncoords = 2; break; 264 case PathIterator.SEG_QUADTO: ncoords = 4; break; 265 case PathIterator.SEG_CUBICTO: ncoords = 6; break; 266 case PathIterator.SEG_CLOSE: ncoords = 0; break; 267 268 default: 269 throw new RuntimeException("unknown segment type"); 270 } 271 272 for (int i = 0; i < ncoords; i++) { 273 if (coords1[i] != coords2[i]) { 274 error(s1, s2, "coordinates differ"); 275 } 276 } 277 pi1.next(); 278 pi2.next(); 279 } 280 281 if (!pi2.isDone()) { 282 error(s1, s2, "Shape 1 ended prematurely"); 283 } 284 } 285 } 286