KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > io > SerialUtilities


1 /* ========================================================================
2  * JCommon : a free general purpose class library for the Java(tm) platform
3  * ========================================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jcommon/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * --------------------
28  * SerialUtilities.java
29  * --------------------
30  * (C) Copyright 2000-2005, by Object Refinery Limited.
31  *
32  * Original Author: David Gilbert (for Object Refinery Limited);
33  * Contributor(s): Arik Levin;
34  *
35  * $Id: SerialUtilities.java,v 1.13 2005/11/03 09:55:27 mungady Exp $
36  *
37  * Changes
38  * -------
39  * 25-Mar-2003 : Version 1 (DG);
40  * 18-Sep-2003 : Added capability to serialize GradientPaint (DG);
41  * 26-Apr-2004 : Added read/writePoint2D() methods (DG);
42  * 22-Feb-2005 : Added support for Arc2D - see patch 1147035 by Arik Levin (DG);
43  * 29-Jul-2005 : Added support for AttributedString (DG);
44  *
45  */

46
47 package org.jfree.io;
48
49 import java.awt.BasicStroke JavaDoc;
50 import java.awt.Color JavaDoc;
51 import java.awt.GradientPaint JavaDoc;
52 import java.awt.Paint JavaDoc;
53 import java.awt.Shape JavaDoc;
54 import java.awt.Stroke JavaDoc;
55 import java.awt.geom.Arc2D JavaDoc;
56 import java.awt.geom.Ellipse2D JavaDoc;
57 import java.awt.geom.GeneralPath JavaDoc;
58 import java.awt.geom.Line2D JavaDoc;
59 import java.awt.geom.PathIterator JavaDoc;
60 import java.awt.geom.Point2D JavaDoc;
61 import java.awt.geom.Rectangle2D JavaDoc;
62 import java.io.IOException JavaDoc;
63 import java.io.ObjectInputStream JavaDoc;
64 import java.io.ObjectOutputStream JavaDoc;
65 import java.io.Serializable JavaDoc;
66 import java.text.AttributedCharacterIterator JavaDoc;
67 import java.text.AttributedString JavaDoc;
68 import java.text.CharacterIterator JavaDoc;
69 import java.util.HashMap JavaDoc;
70 import java.util.Map JavaDoc;
71
72 /**
73  * A class containing useful utility methods relating to serialization.
74  *
75  * @author David Gilbert
76  */

77 public class SerialUtilities {
78
79     /**
80      * Private constructor prevents object creation.
81      */

82     private SerialUtilities() {
83     }
84
85     /**
86      * Returns <code>true</code> if a class implements <code>Serializable</code>
87      * and <code>false</code> otherwise.
88      *
89      * @param c the class.
90      *
91      * @return A boolean.
92      */

93     public static boolean isSerializable(final Class JavaDoc c) {
94         /**
95         final Class[] interfaces = c.getInterfaces();
96         for (int i = 0; i < interfaces.length; i++) {
97             if (interfaces[i].equals(Serializable.class)) {
98                 return true;
99             }
100         }
101         Class cc = c.getSuperclass();
102         if (cc != null) {
103             return isSerializable(cc);
104         }
105          */

106         return (Serializable JavaDoc.class.isAssignableFrom(c));
107     }
108     
109     /**
110      * Reads a <code>Paint</code> object that has been serialised by the
111      * {@link SerialUtilities#writePaint(Paint, ObjectOutputStream)} method.
112      *
113      * @param stream the input stream (<code>null</code> not permitted).
114      *
115      * @return The paint object (possibly <code>null</code>).
116      *
117      * @throws IOException if there is an I/O problem.
118      * @throws ClassNotFoundException if there is a problem loading a class.
119      */

120     public static Paint JavaDoc readPaint(final ObjectInputStream JavaDoc stream)
121         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
122
123         if (stream == null) {
124             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
125         }
126         Paint JavaDoc result = null;
127         final boolean isNull = stream.readBoolean();
128         if (!isNull) {
129             final Class JavaDoc c = (Class JavaDoc) stream.readObject();
130             if (isSerializable(c)) {
131                 result = (Paint JavaDoc) stream.readObject();
132             }
133             else if (c.equals(GradientPaint JavaDoc.class)) {
134                 final float x1 = stream.readFloat();
135                 final float y1 = stream.readFloat();
136                 final Color JavaDoc c1 = (Color JavaDoc) stream.readObject();
137                 final float x2 = stream.readFloat();
138                 final float y2 = stream.readFloat();
139                 final Color JavaDoc c2 = (Color JavaDoc) stream.readObject();
140                 final boolean isCyclic = stream.readBoolean();
141                 result = new GradientPaint JavaDoc(x1, y1, c1, x2, y2, c2, isCyclic);
142             }
143         }
144         return result;
145
146     }
147
148     /**
149      * Serialises a <code>Paint</code> object.
150      *
151      * @param paint the paint object (<code>null</code> permitted).
152      * @param stream the output stream (<code>null</code> not permitted).
153      *
154      * @throws IOException if there is an I/O error.
155      */

156     public static void writePaint(final Paint JavaDoc paint,
157                                   final ObjectOutputStream JavaDoc stream)
158         throws IOException JavaDoc {
159
160         if (stream == null) {
161             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
162         }
163         if (paint != null) {
164             stream.writeBoolean(false);
165             stream.writeObject(paint.getClass());
166             if (paint instanceof Serializable JavaDoc) {
167                 stream.writeObject(paint);
168             }
169             else if (paint instanceof GradientPaint JavaDoc) {
170                 final GradientPaint JavaDoc gp = (GradientPaint JavaDoc) paint;
171                 stream.writeFloat((float) gp.getPoint1().getX());
172                 stream.writeFloat((float) gp.getPoint1().getY());
173                 stream.writeObject(gp.getColor1());
174                 stream.writeFloat((float) gp.getPoint2().getX());
175                 stream.writeFloat((float) gp.getPoint2().getY());
176                 stream.writeObject(gp.getColor2());
177                 stream.writeBoolean(gp.isCyclic());
178             }
179         }
180         else {
181             stream.writeBoolean(true);
182         }
183
184     }
185
186     /**
187      * Reads a <code>Stroke</code> object that has been serialised by the
188      * {@link SerialUtilities#writeStroke(Stroke, ObjectOutputStream)} method.
189      *
190      * @param stream the input stream (<code>null</code> not permitted).
191      *
192      * @return The stroke object (possibly <code>null</code>).
193      *
194      * @throws IOException if there is an I/O problem.
195      * @throws ClassNotFoundException if there is a problem loading a class.
196      */

197     public static Stroke JavaDoc readStroke(final ObjectInputStream JavaDoc stream)
198         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
199
200         if (stream == null) {
201             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
202         }
203         Stroke JavaDoc result = null;
204         final boolean isNull = stream.readBoolean();
205         if (!isNull) {
206             final Class JavaDoc c = (Class JavaDoc) stream.readObject();
207             if (c.equals(BasicStroke JavaDoc.class)) {
208                 final float width = stream.readFloat();
209                 final int cap = stream.readInt();
210                 final int join = stream.readInt();
211                 final float miterLimit = stream.readFloat();
212                 final float[] dash = (float[]) stream.readObject();
213                 final float dashPhase = stream.readFloat();
214                 result = new BasicStroke JavaDoc(
215                     width, cap, join, miterLimit, dash, dashPhase
216                 );
217             }
218             else {
219                 result = (Stroke JavaDoc) stream.readObject();
220             }
221         }
222         return result;
223
224     }
225
226     /**
227      * Serialises a <code>Stroke</code> object. This code handles the
228      * <code>BasicStroke</code> class which is the only <code>Stroke</code>
229      * implementation provided by the JDK (and isn't directly
230      * <code>Serializable</code>).
231      *
232      * @param stroke the stroke object (<code>null</code> permitted).
233      * @param stream the output stream (<code>null</code> not permitted).
234      *
235      * @throws IOException if there is an I/O error.
236      */

237     public static void writeStroke(final Stroke JavaDoc stroke,
238                                    final ObjectOutputStream JavaDoc stream)
239         throws IOException JavaDoc {
240
241         if (stream == null) {
242             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
243         }
244         if (stroke != null) {
245             stream.writeBoolean(false);
246             if (stroke instanceof BasicStroke JavaDoc) {
247                 final BasicStroke JavaDoc s = (BasicStroke JavaDoc) stroke;
248                 stream.writeObject(BasicStroke JavaDoc.class);
249                 stream.writeFloat(s.getLineWidth());
250                 stream.writeInt(s.getEndCap());
251                 stream.writeInt(s.getLineJoin());
252                 stream.writeFloat(s.getMiterLimit());
253                 stream.writeObject(s.getDashArray());
254                 stream.writeFloat(s.getDashPhase());
255             }
256             else {
257                 stream.writeObject(stroke.getClass());
258                 stream.writeObject(stroke);
259             }
260         }
261         else {
262             stream.writeBoolean(true);
263         }
264     }
265
266     /**
267      * Reads a <code>Shape</code> object that has been serialised by the
268      * {@link #writeShape(Shape, ObjectOutputStream)} method.
269      *
270      * @param stream the input stream (<code>null</code> not permitted).
271      *
272      * @return The shape object (possibly <code>null</code>).
273      *
274      * @throws IOException if there is an I/O problem.
275      * @throws ClassNotFoundException if there is a problem loading a class.
276      */

277     public static Shape JavaDoc readShape(final ObjectInputStream JavaDoc stream)
278         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
279
280         if (stream == null) {
281             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
282         }
283         Shape JavaDoc result = null;
284         final boolean isNull = stream.readBoolean();
285         if (!isNull) {
286             final Class JavaDoc c = (Class JavaDoc) stream.readObject();
287             if (c.equals(Line2D JavaDoc.class)) {
288                 final double x1 = stream.readDouble();
289                 final double y1 = stream.readDouble();
290                 final double x2 = stream.readDouble();
291                 final double y2 = stream.readDouble();
292                 result = new Line2D.Double JavaDoc(x1, y1, x2, y2);
293             }
294             else if (c.equals(Rectangle2D JavaDoc.class)) {
295                 final double x = stream.readDouble();
296                 final double y = stream.readDouble();
297                 final double w = stream.readDouble();
298                 final double h = stream.readDouble();
299                 result = new Rectangle2D.Double JavaDoc(x, y, w, h);
300             }
301             else if (c.equals(Ellipse2D JavaDoc.class)) {
302                 final double x = stream.readDouble();
303                 final double y = stream.readDouble();
304                 final double w = stream.readDouble();
305                 final double h = stream.readDouble();
306                 result = new Ellipse2D.Double JavaDoc(x, y, w, h);
307             }
308             else if (c.equals(Arc2D JavaDoc.class)) {
309                 final double x = stream.readDouble();
310                 final double y = stream.readDouble();
311                 final double w = stream.readDouble();
312                 final double h = stream.readDouble();
313                 final double as = stream.readDouble(); // Angle Start
314
final double ae = stream.readDouble(); // Angle Extent
315
final int at = stream.readInt(); // Arc type
316
result = new Arc2D.Double JavaDoc(x, y, w, h, as, ae, at);
317             }
318             else if (c.equals(GeneralPath JavaDoc.class)) {
319                 final GeneralPath JavaDoc gp = new GeneralPath JavaDoc();
320                 final float[] args = new float[6];
321                 boolean hasNext = stream.readBoolean();
322                 while (!hasNext) {
323                     final int type = stream.readInt();
324                     for (int i = 0; i < 6; i++) {
325                         args[i] = stream.readFloat();
326                     }
327                     switch (type) {
328                         case PathIterator.SEG_MOVETO :
329                             gp.moveTo(args[0], args[1]);
330                             break;
331                         case PathIterator.SEG_LINETO :
332                             gp.lineTo(args[0], args[1]);
333                             break;
334                         case PathIterator.SEG_CUBICTO :
335                             gp.curveTo(
336                                 args[0], args[1], args[2],
337                                 args[3], args[4], args[5]
338                             );
339                             break;
340                         case PathIterator.SEG_QUADTO :
341                             gp.quadTo(args[0], args[1], args[2], args[3]);
342                             break;
343                         case PathIterator.SEG_CLOSE :
344                             //result = gp;
345
break;
346                         default :
347                             throw new RuntimeException JavaDoc(
348                                 "JFreeChart - No path exists"
349                             );
350                     }
351                     gp.setWindingRule(stream.readInt());
352                     hasNext = stream.readBoolean();
353                 }
354                 result = gp;
355             }
356             else {
357                 result = (Shape JavaDoc) stream.readObject();
358             }
359         }
360         return result;
361
362     }
363
364     /**
365      * Serialises a <code>Shape</code> object.
366      *
367      * @param shape the shape object (<code>null</code> permitted).
368      * @param stream the output stream (<code>null</code> not permitted).
369      *
370      * @throws IOException if there is an I/O error.
371      */

372     public static void writeShape(final Shape JavaDoc shape,
373                                   final ObjectOutputStream JavaDoc stream)
374         throws IOException JavaDoc {
375
376         if (stream == null) {
377             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
378         }
379         if (shape != null) {
380             stream.writeBoolean(false);
381             if (shape instanceof Line2D JavaDoc) {
382                 final Line2D JavaDoc line = (Line2D JavaDoc) shape;
383                 stream.writeObject(Line2D JavaDoc.class);
384                 stream.writeDouble(line.getX1());
385                 stream.writeDouble(line.getY1());
386                 stream.writeDouble(line.getX2());
387                 stream.writeDouble(line.getY2());
388             }
389             else if (shape instanceof Rectangle2D JavaDoc) {
390                 final Rectangle2D JavaDoc rectangle = (Rectangle2D JavaDoc) shape;
391                 stream.writeObject(Rectangle2D JavaDoc.class);
392                 stream.writeDouble(rectangle.getX());
393                 stream.writeDouble(rectangle.getY());
394                 stream.writeDouble(rectangle.getWidth());
395                 stream.writeDouble(rectangle.getHeight());
396             }
397             else if (shape instanceof Ellipse2D JavaDoc) {
398                 final Ellipse2D JavaDoc ellipse = (Ellipse2D JavaDoc) shape;
399                 stream.writeObject(Ellipse2D JavaDoc.class);
400                 stream.writeDouble(ellipse.getX());
401                 stream.writeDouble(ellipse.getY());
402                 stream.writeDouble(ellipse.getWidth());
403                 stream.writeDouble(ellipse.getHeight());
404             }
405             else if (shape instanceof Arc2D JavaDoc) {
406                 final Arc2D JavaDoc arc = (Arc2D JavaDoc) shape;
407                 stream.writeObject(Arc2D JavaDoc.class);
408                 stream.writeDouble(arc.getX());
409                 stream.writeDouble(arc.getY());
410                 stream.writeDouble(arc.getWidth());
411                 stream.writeDouble(arc.getHeight());
412                 stream.writeDouble(arc.getAngleStart());
413                 stream.writeDouble(arc.getAngleExtent());
414                 stream.writeInt(arc.getArcType());
415             }
416             else if (shape instanceof GeneralPath JavaDoc) {
417                 stream.writeObject(GeneralPath JavaDoc.class);
418                 final PathIterator JavaDoc pi = shape.getPathIterator(null);
419                 final float[] args = new float[6];
420                 stream.writeBoolean(pi.isDone());
421                 while (!pi.isDone()) {
422                     final int type = pi.currentSegment(args);
423                     stream.writeInt(type);
424                     // TODO: could write this to only stream the values
425
// required for the segment type
426
for (int i = 0; i < 6; i++) {
427                         stream.writeFloat(args[i]);
428                     }
429                     stream.writeInt(pi.getWindingRule());
430                     pi.next();
431                     stream.writeBoolean(pi.isDone());
432                 }
433             }
434             else {
435                 stream.writeObject(shape.getClass());
436                 stream.writeObject(shape);
437             }
438         }
439         else {
440             stream.writeBoolean(true);
441         }
442     }
443
444     /**
445      * Reads a <code>Point2D</code> object that has been serialised by the
446      * {@link #writePoint2D(Point2D, ObjectOutputStream)} method.
447      *
448      * @param stream the input stream (<code>null</code> not permitted).
449      *
450      * @return The point object (possibly <code>null</code>).
451      *
452      * @throws IOException if there is an I/O problem.
453      */

454     public static Point2D JavaDoc readPoint2D(final ObjectInputStream JavaDoc stream)
455         throws IOException JavaDoc {
456
457         if (stream == null) {
458             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
459         }
460         Point2D JavaDoc result = null;
461         final boolean isNull = stream.readBoolean();
462         if (!isNull) {
463             final double x = stream.readDouble();
464             final double y = stream.readDouble();
465             result = new Point2D.Double JavaDoc(x, y);
466         }
467         return result;
468
469     }
470
471     /**
472      * Serialises a <code>Point2D</code> object.
473      *
474      * @param p the point object (<code>null</code> permitted).
475      * @param stream the output stream (<code>null</code> not permitted).
476      *
477      * @throws IOException if there is an I/O error.
478      */

479     public static void writePoint2D(final Point2D JavaDoc p,
480                                     final ObjectOutputStream JavaDoc stream)
481         throws IOException JavaDoc {
482
483         if (stream == null) {
484             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
485         }
486         if (p != null) {
487             stream.writeBoolean(false);
488             stream.writeDouble(p.getX());
489             stream.writeDouble(p.getY());
490         }
491         else {
492             stream.writeBoolean(true);
493         }
494     }
495     
496     /**
497      * Reads a <code>AttributedString</code> object that has been serialised by
498      * the {@link SerialUtilities#writeAttributedString(AttributedString,
499      * ObjectOutputStream)} method.
500      *
501      * @param stream the input stream (<code>null</code> not permitted).
502      *
503      * @return The attributed string object (possibly <code>null</code>).
504      *
505      * @throws IOException if there is an I/O problem.
506      * @throws ClassNotFoundException if there is a problem loading a class.
507      */

508     public static AttributedString JavaDoc readAttributedString(
509             ObjectInputStream JavaDoc stream)
510             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
511         
512         if (stream == null) {
513             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
514         }
515         AttributedString JavaDoc result = null;
516         final boolean isNull = stream.readBoolean();
517         if (!isNull) {
518             // read string and attributes then create result
519
String JavaDoc plainStr = (String JavaDoc) stream.readObject();
520             result = new AttributedString JavaDoc(plainStr);
521             char c = stream.readChar();
522             int start = 0;
523             while (c != CharacterIterator.DONE) {
524                 int limit = stream.readInt();
525                 Map JavaDoc atts = (Map JavaDoc) stream.readObject();
526                 result.addAttributes(atts, start, limit);
527                 start = limit;
528                 c = stream.readChar();
529             }
530         }
531         return result;
532     }
533     
534     /**
535      * Serialises an <code>AttributedString</code> object.
536      *
537      * @param as the attributed string object (<code>null</code> permitted).
538      * @param stream the output stream (<code>null</code> not permitted).
539      *
540      * @throws IOException if there is an I/O error.
541      */

542     public static void writeAttributedString(AttributedString JavaDoc as,
543             ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
544         
545         if (stream == null) {
546             throw new IllegalArgumentException JavaDoc("Null 'stream' argument.");
547         }
548         if (as != null) {
549             stream.writeBoolean(false);
550             AttributedCharacterIterator JavaDoc aci = as.getIterator();
551             // build a plain string from aci
552
// then write the string
553
StringBuffer JavaDoc plainStr = new StringBuffer JavaDoc();
554             char current = aci.first();
555             while (current != CharacterIterator.DONE) {
556                 plainStr = plainStr.append(current);
557                 current = aci.next();
558             }
559             stream.writeObject(plainStr.toString());
560             
561             // then write the attributes and limits for each run
562
current = aci.first();
563             int begin = aci.getBeginIndex();
564             while (current != CharacterIterator.DONE) {
565                 // write the current character - when the reader sees that this
566
// is not CharacterIterator.DONE, it will know to read the
567
// run limits and attributes
568
stream.writeChar(current);
569                 
570                 // now write the limit, adjusted as if beginIndex is zero
571
int limit = aci.getRunLimit();
572                 stream.writeInt(limit - begin);
573                 
574                 // now write the attribute set
575
Map JavaDoc atts = new HashMap JavaDoc(aci.getAttributes());
576                 stream.writeObject(atts);
577                 current = aci.setIndex(limit);
578             }
579             // write a character that signals to the reader that all runs
580
// are done...
581
stream.writeChar(CharacterIterator.DONE);
582         }
583         else {
584             // write a flag that indicates a null
585
stream.writeBoolean(true);
586         }
587
588     }
589
590 }
591
592
Popular Tags