aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/data/util/MethodPropertyDescriptor.java
blob: a2a76ec6cf1aa46e556e70b4b6da2eea3c1a43a6 (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
/*
@VaadinApache2LicenseForJavaFiles@
 */
package com.vaadin.data.util;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.vaadin.data.Property;
import com.vaadin.util.SerializerHelper;

/**
 * Property descriptor that is able to create simple {@link MethodProperty}
 * instances for a bean, using given accessors.
 * 
 * @param <BT>
 *            bean type
 * 
 * @since 6.6
 */
public class MethodPropertyDescriptor<BT> implements
        VaadinPropertyDescriptor<BT> {

    private final String name;
    private Class<?> propertyType;
    private transient Method readMethod;
    private transient Method writeMethod;

    /**
     * Creates a property descriptor that can create MethodProperty instances to
     * access the underlying bean property.
     * 
     * @param name
     *            of the property
     * @param propertyType
     *            type (class) of the property
     * @param readMethod
     *            getter {@link Method} for the property
     * @param writeMethod
     *            setter {@link Method} for the property or null if read-only
     *            property
     */
    public MethodPropertyDescriptor(String name, Class<?> propertyType,
            Method readMethod, Method writeMethod) {
        this.name = name;
        this.propertyType = propertyType;
        this.readMethod = readMethod;
        this.writeMethod = writeMethod;
    }

    /* Special serialization to handle method references */
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        SerializerHelper.writeClass(out, propertyType);

        if (writeMethod != null) {
            out.writeObject(writeMethod.getName());
            SerializerHelper.writeClass(out, writeMethod.getDeclaringClass());
            SerializerHelper.writeClassArray(out,
                    writeMethod.getParameterTypes());
        } else {
            out.writeObject(null);
            out.writeObject(null);
            out.writeObject(null);
        }

        if (readMethod != null) {
            out.writeObject(readMethod.getName());
            SerializerHelper.writeClass(out, readMethod.getDeclaringClass());
            SerializerHelper.writeClassArray(out,
                    readMethod.getParameterTypes());
        } else {
            out.writeObject(null);
            out.writeObject(null);
            out.writeObject(null);
        }
    }

    /* Special serialization to handle method references */
    private void readObject(java.io.ObjectInputStream in) throws IOException,
            ClassNotFoundException {
        in.defaultReadObject();
        try {
            @SuppressWarnings("unchecked")
            // business assumption; type parameters not checked at runtime
            Class<BT> class1 = (Class<BT>) SerializerHelper.readClass(in);
            propertyType = class1;

            String name = (String) in.readObject();
            Class<?> writeMethodClass = SerializerHelper.readClass(in);
            Class<?>[] paramTypes = SerializerHelper.readClassArray(in);
            if (name != null) {
                writeMethod = writeMethodClass.getMethod(name, paramTypes);
            } else {
                writeMethod = null;
            }

            name = (String) in.readObject();
            Class<?> readMethodClass = SerializerHelper.readClass(in);
            paramTypes = SerializerHelper.readClassArray(in);
            if (name != null) {
                readMethod = readMethodClass.getMethod(name, paramTypes);
            } else {
                readMethod = null;
            }
        } catch (SecurityException e) {
            getLogger().log(Level.SEVERE, "Internal deserialization error", e);
        } catch (NoSuchMethodException e) {
            getLogger().log(Level.SEVERE, "Internal deserialization error", e);
        }
    };

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Class<?> getPropertyType() {
        return propertyType;
    }

    @Override
    public Property<?> createProperty(Object bean) {
        return new MethodProperty<Object>(propertyType, bean, readMethod,
                writeMethod);
    }

    private static final Logger getLogger() {
        return Logger.getLogger(MethodPropertyDescriptor.class.getName());
    }
}