summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/util/SerializerHelper.java
blob: 5b7b388dd6dc0d2f5d8d0246dff5e6f55e0d3fec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
@VaadinApache2LicenseForJavaFiles@
 */
package com.vaadin.util;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * Helper class for performing serialization. Most of the methods are here are
 * workarounds for problems in Google App Engine. Used internally by Vaadin and
 * should not be used by application developers. Subject to change at any time.
 * 
 * @since 6.0
 */
public class SerializerHelper {

    /**
     * Serializes the class reference so {@link #readClass(ObjectInputStream)}
     * can deserialize it. Supports null class references.
     * 
     * @param out
     *            The {@link ObjectOutputStream} to serialize to.
     * @param cls
     *            A class or null.
     * @throws IOException
     *             Rethrows any IOExceptions from the ObjectOutputStream
     */
    public static void writeClass(ObjectOutputStream out, Class<?> cls)
            throws IOException {
        if (cls == null) {
            out.writeObject(null);
        } else {
            out.writeObject(cls.getName());
        }

    }

    /**
     * Serializes the class references so
     * {@link #readClassArray(ObjectInputStream)} can deserialize it. Supports
     * null class arrays.
     * 
     * @param out
     *            The {@link ObjectOutputStream} to serialize to.
     * @param classes
     *            An array containing class references or null.
     * @throws IOException
     *             Rethrows any IOExceptions from the ObjectOutputStream
     */
    public static void writeClassArray(ObjectOutputStream out,
            Class<?>[] classes) throws IOException {
        if (classes == null) {
            out.writeObject(null);
        } else {
            String[] classNames = new String[classes.length];
            for (int i = 0; i < classes.length; i++) {
                classNames[i] = classes[i].getName();
            }
            out.writeObject(classNames);
        }
    }

    /**
     * Deserializes a class references serialized by
     * {@link #writeClassArray(ObjectOutputStream, Class[])}. Supports null
     * class arrays.
     * 
     * @param in
     *            {@link ObjectInputStream} to read from.
     * @return Class array with the class references or null.
     * @throws ClassNotFoundException
     *             If one of the classes could not be resolved.
     * @throws IOException
     *             Rethrows IOExceptions from the ObjectInputStream
     */
    public static Class<?>[] readClassArray(ObjectInputStream in)
            throws ClassNotFoundException, IOException {
        String[] classNames = (String[]) in.readObject();
        if (classNames == null) {
            return null;
        }
        Class<?>[] classes = new Class<?>[classNames.length];
        for (int i = 0; i < classNames.length; i++) {
            classes[i] = resolveClass(classNames[i]);
        }

        return classes;
    }

    /**
     * List of primitive classes. Google App Engine has problems
     * serializing/deserializing these (#3064).
     */
    private static Class<?>[] primitiveClasses = new Class<?>[] { byte.class,
            short.class, int.class, long.class, float.class, double.class,
            boolean.class, char.class };

    /**
     * Resolves the class given by {@code className}.
     * 
     * @param className
     *            The fully qualified class name.
     * @return A {@code Class} reference.
     * @throws ClassNotFoundException
     *             If the class could not be resolved.
     */
    public static Class<?> resolveClass(String className)
            throws ClassNotFoundException {
        for (Class<?> c : primitiveClasses) {
            if (className.equals(c.getName())) {
                return c;
            }
        }

        return Class.forName(className);
    }

    /**
     * Deserializes a class reference serialized by
     * {@link #writeClass(ObjectOutputStream, Class)}. Supports null class
     * references.
     * 
     * @param in
     *            {@code ObjectInputStream} to read from.
     * @return Class reference to the resolved class
     * @throws ClassNotFoundException
     *             If the class could not be resolved.
     * @throws IOException
     *             Rethrows IOExceptions from the ObjectInputStream
     */
    public static Class<?> readClass(ObjectInputStream in) throws IOException,
            ClassNotFoundException {
        String className = (String) in.readObject();
        if (className == null) {
            return null;
        } else {
            return resolveClass(className);

        }

    }

}