50344
|
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 |
|
|
108 |
public static Shape makeGeneralPath(int winding, float off) {
|
|
109 |
return fill(new GeneralPath(winding), off);
|
|
110 |
}
|
|
111 |
|
|
112 |
public static Shape makePath2DFloat(int winding, float off) {
|
|
113 |
return fill(new Path2D.Float(winding), off);
|
|
114 |
}
|
|
115 |
|
|
116 |
public static Shape makePath2DDouble(int winding, float off) {
|
|
117 |
return fill(new Path2D.Double(winding), off);
|
|
118 |
}
|
|
119 |
|
|
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 |
|
|
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 |
|
|
137 |
public static void usage(int exitcode) {
|
|
138 |
System.err.println("usage: java SerialTest [read|write] <filename>");
|
|
139 |
System.exit(exitcode);
|
|
140 |
}
|
|
141 |
|
|
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 |
|
|
161 |
public static File makeFile(String filename) {
|
|
162 |
return new File(System.getProperty("test.src", "."), filename);
|
|
163 |
}
|
|
164 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
}
|