/* @ITMillApache2LicenseForJavaFiles@ */ package com.vaadin.data; import java.io.Serializable; import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.terminal.ErrorMessage; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.SystemError; /** *

* Defines the interface to commit and discard changes to an object, supporting * read-through and write-through modes. *

* *

* Read-through mode means that the value read from the buffered object * is constantly up to date with the data source. Write-through mode * means that all changes to the object are immediately updated to the data * source. *

* *

* Since these modes are independent, their combinations may result in some * behaviour that may sound surprising. *

* *

* For example, if a Buffered 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. *

* * @author IT Mill Ltd. * @version * @VERSION@ * @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 commit 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; /** * Tests if the object is in write-through mode. If the object is in * write-through mode, all modifications to it will result in * commit being called after the modification. * * @return true if the object is in write-through mode, * false if it's not. */ public boolean isWriteThrough(); /** * Sets the object's write-through mode to the specified status. When * switching the write-through mode on, the commit operation * will be performed. * * @param writeThrough * Boolean value to indicate if the object should be in * write-through mode after the call. * @throws SourceException * If the operation fails because of an exception is thrown by * the data source. * @throws InvalidValueException * If the implicit commit operation fails because of a * validation error. * */ public void setWriteThrough(boolean writeThrough) throws SourceException, InvalidValueException; /** * Tests if the object is in read-through mode. If the object is in * read-through mode, retrieving its value will result in the value being * first updated from the data source to the object. *

* The only exception to this rule is that when the object is not in * write-through mode and it's buffer contains a modified value, the value * retrieved from the object will be the locally modified value in the * buffer which may differ from the value in the data source. *

* * @return true if the object is in read-through mode, * false if it's not. */ public boolean isReadThrough(); /** * Sets the object's read-through mode to the specified status. When * switching read-through mode on, the object's value is updated from the * data source. * * @param readThrough * Boolean value to indicate if the object should be in * read-through mode after the call. * * @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 setReadThrough(boolean readThrough) throws SourceException; /** * Tests if the value stored in the object has been modified since it was * last updated from the data source. * * @return true if the value in the object has been modified * since the last data source update, false 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 IT Mill Ltd. * @version * @VERSION@ * @since 3.0 */ @SuppressWarnings("serial") public class SourceException extends RuntimeException implements ErrorMessage, 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 cause for the exception. * @throws MoreThanOneCauseException * if there is more than one cause for the exception. This * is possible if the commit operation triggers more than * one error at the same time. */ @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; } /** * Gets the error level of this buffered source exception. The level of * the exception is maximum error level of all the contained causes. *

* The causes that do not specify error level default to * ERROR level. Also source exception without any causes * are of level ERROR. *

* * @see com.vaadin.terminal.ErrorMessage#getErrorLevel() */ public int getErrorLevel() { int level = Integer.MIN_VALUE; for (int i = 0; i < causes.length; i++) { final int causeLevel = (causes[i] instanceof ErrorMessage) ? ((ErrorMessage) causes[i]) .getErrorLevel() : ErrorMessage.ERROR; if (causeLevel > level) { level = causeLevel; } } return level == Integer.MIN_VALUE ? ErrorMessage.ERROR : level; } /* Documented in super interface */ public void paint(PaintTarget target) throws PaintException { target.startTag("error"); final int level = getErrorLevel(); if (level > 0 && level <= ErrorMessage.INFORMATION) { target.addAttribute("level", "info"); } else if (level <= ErrorMessage.WARNING) { target.addAttribute("level", "warning"); } else if (level <= ErrorMessage.ERROR) { target.addAttribute("level", "error"); } else if (level <= ErrorMessage.CRITICAL) { target.addAttribute("level", "critical"); } else { target.addAttribute("level", "system"); } // Paint all the exceptions for (int i = 0; i < causes.length; i++) { if (causes[i] instanceof ErrorMessage) { ((ErrorMessage) causes[i]).paint(target); } else { new SystemError(causes[i]).paint(target); } } target.endTag("error"); } /* Documented in super interface */ public void addListener(RepaintRequestListener listener) { } /* Documented in super interface */ public void removeListener(RepaintRequestListener listener) { } /* Documented in super interface */ public void requestRepaint() { } /* Documented in super interface */ public void requestRepaintRequests() { } public String getDebugId() { // TODO Auto-generated method stub return null; } public void setDebugId(String id) { throw new UnsupportedOperationException( "Setting testing id for this Paintable is not implemented"); } } }