summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/data/Buffered.java
blob: bbfc04b73a25c22231f7c4775a96df817501ac0c (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
 * Copyright 2000-2013 Vaadin Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.vaadin.data;

import java.io.Serializable;

import com.vaadin.data.Validator.InvalidValueException;

/**
 * <p>
 * Defines the interface to commit and discard changes to an object, supporting
 * read-through and write-through modes.
 * </p>
 * 
 * <p>
 * <i>Read-through mode</i> means that the value read from the buffered object
 * is constantly up to date with the data source. <i>Write-through</i> mode
 * means that all changes to the object are immediately updated to the data
 * source.
 * </p>
 * 
 * <p>
 * Since these modes are independent, their combinations may result in some
 * behaviour that may sound surprising.
 * </p>
 * 
 * <p>
 * For example, if a <code>Buffered</code> object is in read-through mode but
 * not in write-through mode, the result is an object whose value is updated
 * directly from the data source only if it's not locally modified. If the value
 * is locally modified, retrieving the value from the object would result in a
 * value that is different than the one stored in the data source, even though
 * the object is in read-through mode.
 * </p>
 * 
 * @author Vaadin Ltd.
 * @since 3.0
 */
public interface Buffered extends Serializable {

    /**
     * Updates all changes since the previous commit to the data source. The
     * value stored in the object will always be updated into the data source
     * when <code>commit</code> is called.
     * 
     * @throws SourceException
     *             if the operation fails because of an exception is thrown by
     *             the data source. The cause is included in the exception.
     * @throws InvalidValueException
     *             if the operation fails because validation is enabled and the
     *             values do not validate
     */
    public void commit() throws SourceException, InvalidValueException;

    /**
     * Discards all changes since last commit. The object updates its value from
     * the data source.
     * 
     * @throws SourceException
     *             if the operation fails because of an exception is thrown by
     *             the data source. The cause is included in the exception.
     */
    public void discard() throws SourceException;

    /**
     * Sets the object's buffered mode to the specified status.
     * <p>
     * When the object is in buffered mode, an internal buffer will be used to
     * store changes until {@link #commit()} is called. Calling
     * {@link #discard()} will revert the internal buffer to the value of the
     * data source.
     * </p>
     * <p>
     * This is an easier way to use {@link #setReadThrough(boolean)} and
     * {@link #setWriteThrough(boolean)} and not as error prone. Changing
     * buffered mode will change both the read through and write through state
     * of the object.
     * </p>
     * <p>
     * Mixing calls to {@link #setBuffered(boolean)}/{@link #isBuffered()} and
     * {@link #setReadThrough(boolean)}/{@link #isReadThrough()} or
     * {@link #setWriteThrough(boolean)}/{@link #isWriteThrough()} is generally
     * a bad idea.
     * </p>
     * 
     * @param buffered
     *            true if buffered mode should be turned on, false otherwise
     * @since 7.0
     */
    public void setBuffered(boolean buffered);

    /**
     * Checks the buffered mode of this Object.
     * <p>
     * This method only returns true if both read and write buffering is used.
     * </p>
     * 
     * @return true if buffered mode is on, false otherwise
     * @since 7.0
     */
    public boolean isBuffered();

    /**
     * Tests if the value stored in the object has been modified since it was
     * last updated from the data source.
     * 
     * @return <code>true</code> if the value in the object has been modified
     *         since the last data source update, <code>false</code> if not.
     */
    public boolean isModified();

    /**
     * An exception that signals that one or more exceptions occurred while a
     * buffered object tried to access its data source or if there is a problem
     * in processing a data source.
     * 
     * @author Vaadin Ltd.
     * @since 3.0
     */
    @SuppressWarnings("serial")
    public class SourceException extends RuntimeException implements
            Serializable {

        /** Source class implementing the buffered interface */
        private final Buffered source;

        /** Original cause of the source exception */
        private Throwable[] causes = {};

        /**
         * Creates a source exception that does not include a cause.
         * 
         * @param source
         *            the source object implementing the Buffered interface.
         */
        public SourceException(Buffered source) {
            this.source = source;
        }

        /**
         * Creates a source exception from a cause exception.
         * 
         * @param source
         *            the source object implementing the Buffered interface.
         * @param cause
         *            the original cause for this exception.
         */
        public SourceException(Buffered source, Throwable cause) {
            this.source = source;
            causes = new Throwable[] { cause };
        }

        /**
         * Creates a source exception from multiple causes.
         * 
         * @param source
         *            the source object implementing the Buffered interface.
         * @param causes
         *            the original causes for this exception.
         */
        public SourceException(Buffered source, Throwable[] causes) {
            this.source = source;
            this.causes = causes;
        }

        /**
         * Gets the cause of the exception.
         * 
         * @return The (first) cause for the exception, null if no cause.
         */
        @Override
        public final Throwable getCause() {
            if (causes.length == 0) {
                return null;
            }
            return causes[0];
        }

        /**
         * Gets all the causes for this exception.
         * 
         * @return throwables that caused this exception
         */
        public final Throwable[] getCauses() {
            return causes;
        }

        /**
         * Gets a source of the exception.
         * 
         * @return the Buffered object which generated this exception.
         */
        public Buffered getSource() {
            return source;
        }

    }
}