diff options
author | Artur Signell <artur@vaadin.com> | 2012-08-13 18:34:33 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2012-08-13 19:18:33 +0300 |
commit | e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569 (patch) | |
tree | 9ab6f13f7188cab44bbd979b1cf620f15328a03f /src/com/vaadin/data | |
parent | 14dd4d0b28c76eb994b181a4570f3adec53342e6 (diff) | |
download | vaadin-framework-e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569.tar.gz vaadin-framework-e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569.zip |
Moved server files to a server src folder (#9299)
Diffstat (limited to 'src/com/vaadin/data')
115 files changed, 0 insertions, 23759 deletions
diff --git a/src/com/vaadin/data/Buffered.java b/src/com/vaadin/data/Buffered.java deleted file mode 100644 index 1387cb965b..0000000000 --- a/src/com/vaadin/data/Buffered.java +++ /dev/null @@ -1,280 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -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. - * @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 <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; - - /** - * Tests if the object is in write-through mode. If the object is in - * write-through mode, all modifications to it will result in - * <code>commit</code> being called after the modification. - * - * @return <code>true</code> if the object is in write-through mode, - * <code>false</code> if it's not. - * @deprecated Use {@link #setBuffered(boolean)} instead. Note that - * setReadThrough(true), setWriteThrough(true) equals - * setBuffered(false) - */ - @Deprecated - public boolean isWriteThrough(); - - /** - * Sets the object's write-through mode to the specified status. When - * switching the write-through mode on, the <code>commit</code> 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. - * - * @deprecated Use {@link #setBuffered(boolean)} instead. Note that - * setReadThrough(true), setWriteThrough(true) equals - * setBuffered(false) - */ - @Deprecated - 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. - * <p> - * 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. - * </p> - * - * @return <code>true</code> if the object is in read-through mode, - * <code>false</code> if it's not. - * @deprecated Use {@link #isBuffered(boolean)} instead. Note that - * setReadThrough(true), setWriteThrough(true) equals - * setBuffered(false) - */ - @Deprecated - 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. - * @deprecated Use {@link #setBuffered(boolean)} instead. Note that - * setReadThrough(true), setWriteThrough(true) equals - * setBuffered(false) - */ - @Deprecated - public void setReadThrough(boolean readThrough) 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. - * @version - * @VERSION@ - * @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; - } - - } -} diff --git a/src/com/vaadin/data/BufferedValidatable.java b/src/com/vaadin/data/BufferedValidatable.java deleted file mode 100644 index ce1d44fce6..0000000000 --- a/src/com/vaadin/data/BufferedValidatable.java +++ /dev/null @@ -1,35 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data; - -import java.io.Serializable; - -/** - * <p> - * This interface defines the combination of <code>Validatable</code> and - * <code>Buffered</code> interfaces. The combination of the interfaces defines - * if the invalid data is committed to datasource. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -public interface BufferedValidatable extends Buffered, Validatable, - Serializable { - - /** - * Tests if the invalid data is committed to datasource. The default is - * <code>false</code>. - */ - public boolean isInvalidCommitted(); - - /** - * Sets if the invalid data should be committed to datasource. The default - * is <code>false</code>. - */ - public void setInvalidCommitted(boolean isCommitted); -} diff --git a/src/com/vaadin/data/Collapsible.java b/src/com/vaadin/data/Collapsible.java deleted file mode 100644 index 06c96b7ea7..0000000000 --- a/src/com/vaadin/data/Collapsible.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data; - -import com.vaadin.data.Container.Hierarchical; -import com.vaadin.data.Container.Ordered; - -/** - * Container needed by large lazy loading hierarchies displayed e.g. in - * TreeTable. - * <p> - * Container of this type gets notified when a subtree is opened/closed in a - * component displaying its content. This allows container to lazy load subtrees - * and release memory when a sub-tree is no longer displayed. - * <p> - * Methods from {@link Container.Ordered} (and from {@linkContainer.Indexed} if - * implemented) are expected to work as in "preorder" of the currently visible - * hierarchy. This means for example that the return value of size method - * changes when subtree is collapsed/expanded. In other words items in collapsed - * sub trees should be "ignored" by container when the container is accessed - * with methods introduced in {@link Container.Ordered} or - * {@linkContainer.Indexed}. From the accessors point of view, items in - * collapsed subtrees don't exist. - * <p> - * - */ -public interface Collapsible extends Hierarchical, Ordered { - - /** - * <p> - * Collapsing the {@link Item} indicated by <code>itemId</code> hides all - * children, and their respective children, from the {@link Container}. - * </p> - * - * <p> - * If called on a leaf {@link Item}, this method does nothing. - * </p> - * - * @param itemId - * the identifier of the collapsed {@link Item} - * @param collapsed - * <code>true</code> if you want to collapse the children below - * this {@link Item}. <code>false</code> if you want to - * uncollapse the children. - */ - public void setCollapsed(Object itemId, boolean collapsed); - - /** - * <p> - * Checks whether the {@link Item}, identified by <code>itemId</code> is - * collapsed or not. - * </p> - * - * <p> - * If an {@link Item} is "collapsed" its children are not included in - * methods used to list Items in this container. - * </p> - * - * @param itemId - * The {@link Item}'s identifier that is to be checked. - * @return <code>true</code> iff the {@link Item} identified by - * <code>itemId</code> is currently collapsed, otherwise - * <code>false</code>. - */ - public boolean isCollapsed(Object itemId); - -} diff --git a/src/com/vaadin/data/Container.java b/src/com/vaadin/data/Container.java deleted file mode 100644 index f4c0ed9794..0000000000 --- a/src/com/vaadin/data/Container.java +++ /dev/null @@ -1,1105 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data; - -import java.io.Serializable; -import java.util.Collection; - -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * <p> - * A specialized set of identified Items. Basically the Container is a set of - * {@link Item}s, but it imposes certain constraints on its contents. These - * constraints state the following: - * </p> - * - * <ul> - * <li>All Items in the Container must have the same number of Properties. - * <li>All Items in the Container must have the same Property ID's (see - * {@link Item#getItemPropertyIds()}). - * <li>All Properties in the Items corresponding to the same Property ID must - * have the same data type. - * <li>All Items within a container are uniquely identified by their non-null - * IDs. - * </ul> - * - * <p> - * The Container can be visualized as a representation of a relational database - * table. Each Item in the Container represents a row in the table, and all - * cells in a column (identified by a Property ID) have the same data type. Note - * that as with the cells in a database table, no Property in a Container may be - * empty, though they may contain <code>null</code> values. - * </p> - * - * <p> - * Note that though uniquely identified, the Items in a Container are not - * necessarily {@link Container.Ordered ordered} or {@link Container.Indexed - * indexed}. - * </p> - * - * <p> - * Containers can derive Item ID's from the item properties or use other, - * container specific or user specified identifiers. - * </p> - * - * <p> - * If a container is {@link Filterable filtered} or {@link Sortable sorted}, - * most of the the methods of the container interface and its subinterfaces - * (container size, {@link #containsId(Object)}, iteration and indices etc.) - * relate to the filtered and sorted view, not to the full container contents. - * See individual method javadoc for exceptions to this (adding and removing - * items). - * </p> - * - * <p> - * <img src=doc-files/Container_full.gif> - * </p> - * - * <p> - * The Container interface is split to several subinterfaces so that a class can - * implement only the ones it needs. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 3.0 - */ -public interface Container extends Serializable { - - /** - * Gets the {@link Item} with the given Item ID from the Container. If the - * Container does not contain the requested Item, <code>null</code> is - * returned. - * - * Containers should not return Items that are filtered out. - * - * @param itemId - * ID of the {@link Item} to retrieve - * @return the {@link Item} with the given ID or <code>null</code> if the - * Item is not found in the Container - */ - public Item getItem(Object itemId); - - /** - * Gets the ID's of all Properties stored in the Container. The ID's cannot - * be modified through the returned collection. - * - * @return unmodifiable collection of Property IDs - */ - public Collection<?> getContainerPropertyIds(); - - /** - * Gets the ID's of all visible (after filtering and sorting) Items stored - * in the Container. The ID's cannot be modified through the returned - * collection. - * - * If the container is {@link Ordered}, the collection returned by this - * method should follow that order. If the container is {@link Sortable}, - * the items should be in the sorted order. - * - * Calling this method for large lazy containers can be an expensive - * operation and should be avoided when practical. - * - * @return unmodifiable collection of Item IDs - */ - public Collection<?> getItemIds(); - - /** - * Gets the Property identified by the given itemId and propertyId from the - * Container. If the Container does not contain the item or it is filtered - * out, or the Container does not have the Property, <code>null</code> is - * returned. - * - * @param itemId - * ID of the visible Item which contains the Property - * @param propertyId - * ID of the Property to retrieve - * @return Property with the given ID or <code>null</code> - */ - public Property<?> getContainerProperty(Object itemId, Object propertyId); - - /** - * Gets the data type of all Properties identified by the given Property ID. - * - * @param propertyId - * ID identifying the Properties - * @return data type of the Properties - */ - public Class<?> getType(Object propertyId); - - /** - * Gets the number of visible Items in the Container. - * - * Filtering can hide items so that they will not be visible through the - * container API. - * - * @return number of Items in the Container - */ - public int size(); - - /** - * Tests if the Container contains the specified Item. - * - * Filtering can hide items so that they will not be visible through the - * container API, and this method should respect visibility of items (i.e. - * only indicate visible items as being in the container) if feasible for - * the container. - * - * @param itemId - * ID the of Item to be tested - * @return boolean indicating if the Container holds the specified Item - */ - public boolean containsId(Object itemId); - - /** - * Creates a new Item with the given ID in the Container. - * - * <p> - * The new Item is returned, and it is ready to have its Properties - * modified. Returns <code>null</code> if the operation fails or the - * Container already contains a Item with the given ID. - * </p> - * - * <p> - * This functionality is optional. - * </p> - * - * @param itemId - * ID of the Item to be created - * @return Created new Item, or <code>null</code> in case of a failure - * @throws UnsupportedOperationException - * if adding an item with an explicit item ID is not supported - * by the container - */ - public Item addItem(Object itemId) throws UnsupportedOperationException; - - /** - * Creates a new Item into the Container, and assign it an automatic ID. - * - * <p> - * The new ID is returned, or <code>null</code> if the operation fails. - * After a successful call you can use the {@link #getItem(Object ItemId) - * <code>getItem</code>}method to fetch the Item. - * </p> - * - * <p> - * This functionality is optional. - * </p> - * - * @return ID of the newly created Item, or <code>null</code> in case of a - * failure - * @throws UnsupportedOperationException - * if adding an item without an explicit item ID is not - * supported by the container - */ - public Object addItem() throws UnsupportedOperationException; - - /** - * Removes the Item identified by <code>ItemId</code> from the Container. - * - * <p> - * Containers that support filtering should also allow removing an item that - * is currently filtered out. - * </p> - * - * <p> - * This functionality is optional. - * </p> - * - * @param itemId - * ID of the Item to remove - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the container does not support removing individual items - */ - public boolean removeItem(Object itemId) - throws UnsupportedOperationException; - - /** - * Adds a new Property to all Items in the Container. The Property ID, data - * type and default value of the new Property are given as parameters. - * - * This functionality is optional. - * - * @param propertyId - * ID of the Property - * @param type - * Data type of the new Property - * @param defaultValue - * The value all created Properties are initialized to - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the container does not support explicitly adding container - * properties - */ - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException; - - /** - * Removes a Property specified by the given Property ID from the Container. - * Note that the Property will be removed from all Items in the Container. - * - * This functionality is optional. - * - * @param propertyId - * ID of the Property to remove - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the container does not support removing container - * properties - */ - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException; - - /** - * Removes all Items from the Container. - * - * <p> - * Note that Property ID and type information is preserved. This - * functionality is optional. - * </p> - * - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the container does not support removing all items - */ - public boolean removeAllItems() throws UnsupportedOperationException; - - /** - * Interface for Container classes whose {@link Item}s can be traversed in - * order. - * - * <p> - * If the container is filtered or sorted, the traversal applies to the - * filtered and sorted view. - * </p> - * <p> - * The <code>addItemAfter()</code> methods should apply filters to the added - * item after inserting it, possibly hiding it immediately. If the container - * is being sorted, they may add items at the correct sorted position - * instead of the given position. See also {@link Filterable} and - * {@link Sortable} for more information. - * </p> - */ - public interface Ordered extends Container { - - /** - * Gets the ID of the Item following the Item that corresponds to - * <code>itemId</code>. If the given Item is the last or not found in - * the Container, <code>null</code> is returned. - * - * @param itemId - * ID of a visible Item in the Container - * @return ID of the next visible Item or <code>null</code> - */ - public Object nextItemId(Object itemId); - - /** - * Gets the ID of the Item preceding the Item that corresponds to - * <code>itemId</code>. If the given Item is the first or not found in - * the Container, <code>null</code> is returned. - * - * @param itemId - * ID of a visible Item in the Container - * @return ID of the previous visible Item or <code>null</code> - */ - public Object prevItemId(Object itemId); - - /** - * Gets the ID of the first Item in the Container. - * - * @return ID of the first visible Item in the Container - */ - public Object firstItemId(); - - /** - * Gets the ID of the last Item in the Container.. - * - * @return ID of the last visible Item in the Container - */ - public Object lastItemId(); - - /** - * Tests if the Item corresponding to the given Item ID is the first - * Item in the Container. - * - * @param itemId - * ID of an Item in the Container - * @return <code>true</code> if the Item is first visible item in the - * Container, <code>false</code> if not - */ - public boolean isFirstId(Object itemId); - - /** - * Tests if the Item corresponding to the given Item ID is the last Item - * in the Container. - * - * @return <code>true</code> if the Item is last visible item in the - * Container, <code>false</code> if not - */ - public boolean isLastId(Object itemId); - - /** - * Adds a new item after the given item. - * <p> - * Adding an item after null item adds the item as first item of the - * ordered container. - * </p> - * - * @see Ordered Ordered: adding items in filtered or sorted containers - * - * @param previousItemId - * Id of the visible item in ordered container after which to - * insert the new item. - * @return item id the the created new item or null if the operation - * fails. - * @throws UnsupportedOperationException - * if the operation is not supported by the container - */ - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException; - - /** - * Adds a new item after the given item. - * <p> - * Adding an item after null item adds the item as first item of the - * ordered container. - * </p> - * - * @see Ordered Ordered: adding items in filtered or sorted containers - * - * @param previousItemId - * Id of the visible item in ordered container after which to - * insert the new item. - * @param newItemId - * Id of the new item to be added. - * @return new item or null if the operation fails. - * @throws UnsupportedOperationException - * if the operation is not supported by the container - */ - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException; - - } - - /** - * Interface for Container classes whose {@link Item}s can be sorted. - * <p> - * When an {@link Ordered} or {@link Indexed} container is sorted, all - * relevant operations of these interfaces should only use the filtered and - * sorted contents and the filtered indices to the container. Indices or - * item identifiers in the public API refer to the visible view unless - * otherwise stated. However, the <code>addItem*()</code> methods may add - * items that will be filtered out after addition or moved to another - * position based on sorting. - * </p> - * <p> - * How sorting is performed when a {@link Hierarchical} container implements - * {@link Sortable} is implementation specific and should be documented in - * the implementing class. However, the recommended approach is sorting the - * roots and the sets of children of each item separately. - * </p> - * <p> - * Depending on the container type, sorting a container may permanently - * change the internal order of items in the container. - * </p> - */ - public interface Sortable extends Ordered { - - /** - * Sort method. - * - * Sorts the container items. - * - * Sorting a container can irreversibly change the order of its items or - * only change the order temporarily, depending on the container. - * - * @param propertyId - * Array of container property IDs, whose values are used to - * sort the items in container as primary, secondary, ... - * sorting criterion. All of the item IDs must be in the - * collection returned by - * {@link #getSortableContainerPropertyIds()} - * @param ascending - * Array of sorting order flags corresponding to each - * property ID used in sorting. If this array is shorter than - * propertyId array, ascending order is assumed for items - * where the order is not specified. Use <code>true</code> to - * sort in ascending order, <code>false</code> to use - * descending order. - */ - void sort(Object[] propertyId, boolean[] ascending); - - /** - * Gets the container property IDs which can be used to sort the items. - * - * @return the IDs of the properties that can be used for sorting the - * container - */ - Collection<?> getSortableContainerPropertyIds(); - - } - - /** - * Interface for Container classes whose {@link Item}s can be accessed by - * their position in the container. - * <p> - * If the container is filtered or sorted, all indices refer to the filtered - * and sorted view. However, the <code>addItemAt()</code> methods may add - * items that will be filtered out after addition or moved to another - * position based on sorting. - * </p> - */ - public interface Indexed extends Ordered { - - /** - * Gets the index of the Item corresponding to the itemId. The following - * is <code>true</code> for the returned index: 0 <= index < size(), or - * index = -1 if there is no visible item with that id in the container. - * - * @param itemId - * ID of an Item in the Container - * @return index of the Item, or -1 if (the filtered and sorted view of) - * the Container does not include the Item - */ - public int indexOfId(Object itemId); - - /** - * Gets the ID of an Item by an index number. - * - * @param index - * Index of the requested id in (the filtered and sorted view - * of) the Container - * @return ID of the Item in the given index - */ - public Object getIdByIndex(int index); - - /** - * Adds a new item at given index (in the filtered view). - * <p> - * The indices of the item currently in the given position and all the - * following items are incremented. - * </p> - * <p> - * This method should apply filters to the added item after inserting - * it, possibly hiding it immediately. If the container is being sorted, - * the item may be added at the correct sorted position instead of the - * given position. See {@link Indexed}, {@link Ordered}, - * {@link Filterable} and {@link Sortable} for more information. - * </p> - * - * @param index - * Index (in the filtered and sorted view) to add the new - * item. - * @return item id of the created item or null if the operation fails. - * @throws UnsupportedOperationException - * if the operation is not supported by the container - */ - public Object addItemAt(int index) throws UnsupportedOperationException; - - /** - * Adds a new item at given index (in the filtered view). - * <p> - * The indexes of the item currently in the given position and all the - * following items are incremented. - * </p> - * <p> - * This method should apply filters to the added item after inserting - * it, possibly hiding it immediately. If the container is being sorted, - * the item may be added at the correct sorted position instead of the - * given position. See {@link Indexed}, {@link Filterable} and - * {@link Sortable} for more information. - * </p> - * - * @param index - * Index (in the filtered and sorted view) at which to add - * the new item. - * @param newItemId - * Id of the new item to be added. - * @return new {@link Item} or null if the operation fails. - * @throws UnsupportedOperationException - * if the operation is not supported by the container - */ - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException; - - } - - /** - * <p> - * Interface for <code>Container</code> classes whose Items can be arranged - * hierarchically. This means that the Items in the container belong in a - * tree-like structure, with the following quirks: - * </p> - * - * <ul> - * <li>The Item structure may have more than one root elements - * <li>The Items in the hierarchy can be declared explicitly to be able or - * unable to have children. - * </ul> - */ - public interface Hierarchical extends Container { - - /** - * Gets the IDs of all Items that are children of the specified Item. - * The returned collection is unmodifiable. - * - * @param itemId - * ID of the Item whose children the caller is interested in - * @return An unmodifiable {@link java.util.Collection collection} - * containing the IDs of all other Items that are children in - * the container hierarchy - */ - public Collection<?> getChildren(Object itemId); - - /** - * Gets the ID of the parent Item of the specified Item. - * - * @param itemId - * ID of the Item whose parent the caller wishes to find out. - * @return the ID of the parent Item. Will be <code>null</code> if the - * specified Item is a root element. - */ - public Object getParent(Object itemId); - - /** - * Gets the IDs of all Items in the container that don't have a parent. - * Such items are called <code>root</code> Items. The returned - * collection is unmodifiable. - * - * @return An unmodifiable {@link java.util.Collection collection} - * containing IDs of all root elements of the container - */ - public Collection<?> rootItemIds(); - - /** - * <p> - * Sets the parent of an Item. The new parent item must exist and be - * able to have children. ( - * <code>{@link #areChildrenAllowed(Object)} == true</code> ). It is - * also possible to detach a node from the hierarchy (and thus make it - * root) by setting the parent <code>null</code>. - * </p> - * - * <p> - * This operation is optional. - * </p> - * - * @param itemId - * ID of the item to be set as the child of the Item - * identified with <code>newParentId</code> - * @param newParentId - * ID of the Item that's to be the new parent of the Item - * identified with <code>itemId</code> - * @return <code>true</code> if the operation succeeded, - * <code>false</code> if not - */ - public boolean setParent(Object itemId, Object newParentId) - throws UnsupportedOperationException; - - /** - * Tests if the Item with given ID can have children. - * - * @param itemId - * ID of the Item in the container whose child capability is - * to be tested - * @return <code>true</code> if the specified Item exists in the - * Container and it can have children, <code>false</code> if - * it's not found from the container or it can't have children. - */ - public boolean areChildrenAllowed(Object itemId); - - /** - * <p> - * Sets the given Item's capability to have children. If the Item - * identified with <code>itemId</code> already has children and - * <code>{@link #areChildrenAllowed(Object)}</code> is false this method - * fails and <code>false</code> is returned. - * </p> - * <p> - * The children must be first explicitly removed with - * {@link #setParent(Object itemId, Object newParentId)}or - * {@link com.vaadin.data.Container#removeItem(Object itemId)}. - * </p> - * - * <p> - * This operation is optional. If it is not implemented, the method - * always returns <code>false</code>. - * </p> - * - * @param itemId - * ID of the Item in the container whose child capability is - * to be set - * @param areChildrenAllowed - * boolean value specifying if the Item can have children or - * not - * @return <code>true</code> if the operation succeeded, - * <code>false</code> if not - */ - public boolean setChildrenAllowed(Object itemId, - boolean areChildrenAllowed) - throws UnsupportedOperationException; - - /** - * Tests if the Item specified with <code>itemId</code> is a root Item. - * The hierarchical container can have more than one root and must have - * at least one unless it is empty. The {@link #getParent(Object itemId)} - * method always returns <code>null</code> for root Items. - * - * @param itemId - * ID of the Item whose root status is to be tested - * @return <code>true</code> if the specified Item is a root, - * <code>false</code> if not - */ - public boolean isRoot(Object itemId); - - /** - * <p> - * Tests if the Item specified with <code>itemId</code> has child Items - * or if it is a leaf. The {@link #getChildren(Object itemId)} method - * always returns <code>null</code> for leaf Items. - * </p> - * - * <p> - * Note that being a leaf does not imply whether or not an Item is - * allowed to have children. - * </p> - * . - * - * @param itemId - * ID of the Item to be tested - * @return <code>true</code> if the specified Item has children, - * <code>false</code> if not (is a leaf) - */ - public boolean hasChildren(Object itemId); - - /** - * <p> - * Removes the Item identified by <code>ItemId</code> from the - * Container. - * </p> - * - * <p> - * Note that this does not remove any children the item might have. - * </p> - * - * @param itemId - * ID of the Item to remove - * @return <code>true</code> if the operation succeeded, - * <code>false</code> if not - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException; - } - - /** - * Interface that is implemented by containers which allow reducing their - * visible contents based on a set of filters. This interface has been - * renamed from {@link Filterable}, and implementing the new - * {@link Filterable} instead of or in addition to {@link SimpleFilterable} - * is recommended. This interface might be removed in future Vaadin - * versions. - * <p> - * When a set of filters are set, only items that match all the filters are - * included in the visible contents of the container. Still new items that - * do not match filters can be added to the container. Multiple filters can - * be added and the container remembers the state of the filters. When - * multiple filters are added, all filters must match for an item to be - * visible in the container. - * </p> - * <p> - * When an {@link Ordered} or {@link Indexed} container is filtered, all - * operations of these interfaces should only use the filtered contents and - * the filtered indices to the container. - * </p> - * <p> - * How filtering is performed when a {@link Hierarchical} container - * implements {@link SimpleFilterable} is implementation specific and should - * be documented in the implementing class. - * </p> - * <p> - * Adding items (if supported) to a filtered {@link Ordered} or - * {@link Indexed} container should insert them immediately after the - * indicated visible item. The unfiltered position of items added at index - * 0, at index {@link com.vaadin.data.Container#size()} or at an undefined - * position is up to the implementation. - * </p> - * <p> - * The functionality of SimpleFilterable can be implemented using the - * {@link Filterable} API and {@link SimpleStringFilter}. - * </p> - * - * @since 5.0 (renamed from Filterable to SimpleFilterable in 6.6) - */ - public interface SimpleFilterable extends Container, Serializable { - - /** - * Add a filter for given property. - * - * The API {@link Filterable#addContainerFilter(Filter)} is recommended - * instead of this method. A {@link SimpleStringFilter} can be used with - * the new API to implement the old string filtering functionality. - * - * The filter accepts items for which toString() of the value of the - * given property contains or starts with given filterString. Other - * items are not visible in the container when filtered. - * - * If a container has multiple filters, only items accepted by all - * filters are visible. - * - * @param propertyId - * Property for which the filter is applied to. - * @param filterString - * String that must match the value of the property - * @param ignoreCase - * Determine if the casing can be ignored when comparing - * strings. - * @param onlyMatchPrefix - * Only match prefixes; no other matches are included. - */ - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix); - - /** - * Remove all filters from all properties. - */ - public void removeAllContainerFilters(); - - /** - * Remove all filters from the given property. - * - * @param propertyId - * for which to remove filters - */ - public void removeContainerFilters(Object propertyId); - } - - /** - * Filter interface for container filtering. - * - * If a filter does not support in-memory filtering, - * {@link #passesFilter(Item)} should throw - * {@link UnsupportedOperationException}. - * - * Lazy containers must be able to map filters to their internal - * representation (e.g. SQL or JPA 2.0 Criteria). - * - * An {@link UnsupportedFilterException} can be thrown by the container if a - * particular filter is not supported by the container. - * - * An {@link Filter} should implement {@link #equals(Object)} and - * {@link #hashCode()} correctly to avoid duplicate filter registrations - * etc. - * - * @see Filterable - * - * @since 6.6 - */ - public interface Filter extends Serializable { - - /** - * Check if an item passes the filter (in-memory filtering). - * - * @param itemId - * identifier of the item being filtered; may be null when - * the item is being added to the container - * @param item - * the item being filtered - * @return true if the item is accepted by this filter - * @throws UnsupportedOperationException - * if the filter cannot be used for in-memory filtering - */ - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException; - - /** - * Check if a change in the value of a property can affect the filtering - * result. May always return true, at the cost of performance. - * - * If the filter cannot determine whether it may depend on the property - * or not, should return true. - * - * @param propertyId - * @return true if the filtering result may/does change based on changes - * to the property identified by propertyId - */ - public boolean appliesToProperty(Object propertyId); - - } - - /** - * Interface that is implemented by containers which allow reducing their - * visible contents based on a set of filters. - * <p> - * When a set of filters are set, only items that match all the filters are - * included in the visible contents of the container. Still new items that - * do not match filters can be added to the container. Multiple filters can - * be added and the container remembers the state of the filters. When - * multiple filters are added, all filters must match for an item to be - * visible in the container. - * </p> - * <p> - * When an {@link Ordered} or {@link Indexed} container is filtered, all - * operations of these interfaces should only use the filtered and sorted - * contents and the filtered indices to the container. Indices or item - * identifiers in the public API refer to the visible view unless otherwise - * stated. However, the <code>addItem*()</code> methods may add items that - * will be filtered out after addition or moved to another position based on - * sorting. - * </p> - * <p> - * How filtering is performed when a {@link Hierarchical} container - * implements {@link Filterable} is implementation specific and should be - * documented in the implementing class. - * </p> - * <p> - * Adding items (if supported) to a filtered {@link Ordered} or - * {@link Indexed} container should insert them immediately after the - * indicated visible item. However, the unfiltered position of items added - * at index 0, at index {@link com.vaadin.data.Container#size()} or at an - * undefined position is up to the implementation. - * </p> - * - * <p> - * This API replaces the old Filterable interface, renamed to - * {@link SimpleFilterable} in Vaadin 6.6. - * </p> - * - * @since 6.6 - */ - public interface Filterable extends Container, Serializable { - /** - * Adds a filter for the container. - * - * If a container has multiple filters, only items accepted by all - * filters are visible. - * - * @throws UnsupportedFilterException - * if the filter is not supported by the container - */ - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException; - - /** - * Removes a filter from the container. - * - * This requires that the equals() method considers the filters as - * equivalent (same instance or properly implemented equals() method). - */ - public void removeContainerFilter(Filter filter); - - /** - * Remove all active filters from the container. - */ - public void removeAllContainerFilters(); - - } - - /** - * Interface implemented by viewer classes capable of using a Container as a - * data source. - */ - public interface Viewer extends Serializable { - - /** - * Sets the Container that serves as the data source of the viewer. - * - * @param newDataSource - * The new data source Item - */ - public void setContainerDataSource(Container newDataSource); - - /** - * Gets the Container serving as the data source of the viewer. - * - * @return data source Container - */ - public Container getContainerDataSource(); - - } - - /** - * <p> - * Interface implemented by the editor classes supporting editing the - * Container. Implementing this interface means that the Container serving - * as the data source of the editor can be modified through it. - * </p> - * <p> - * Note that not implementing the <code>Container.Editor</code> interface - * does not restrict the class from editing the Container contents - * internally. - * </p> - */ - public interface Editor extends Container.Viewer, Serializable { - - } - - /* Contents change event */ - - /** - * An <code>Event</code> object specifying the Container whose Item set has - * changed (items added, removed or reordered). - * - * A simple property value change is not an item set change. - */ - public interface ItemSetChangeEvent extends Serializable { - - /** - * Gets the Property where the event occurred. - * - * @return source of the event - */ - public Container getContainer(); - } - - /** - * Container Item set change listener interface. - * - * An item set change refers to addition, removal or reordering of items in - * the container. A simple property value change is not an item set change. - */ - public interface ItemSetChangeListener extends Serializable { - - /** - * Lets the listener know a Containers visible (filtered and/or sorted, - * if applicable) Item set has changed. - * - * @param event - * change event text - */ - public void containerItemSetChange(Container.ItemSetChangeEvent event); - } - - /** - * The interface for adding and removing <code>ItemSetChangeEvent</code> - * listeners. By implementing this interface a class explicitly announces - * that it will generate a <code>ItemSetChangeEvent</code> when its contents - * are modified. - * - * An item set change refers to addition, removal or reordering of items in - * the container. A simple property value change is not an item set change. - * - * <p> - * Note: The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * <code>addListener</code> and <code>removeListener</code> methods. That - * way the caller of these methods has no real way of finding out if the - * class really will send the events, or if it just defines the methods to - * be able to implement an interface. - * </p> - */ - public interface ItemSetChangeNotifier extends Serializable { - - /** - * Adds an Item set change listener for the object. - * - * @param listener - * listener to be added - */ - public void addListener(Container.ItemSetChangeListener listener); - - /** - * Removes the Item set change listener from the object. - * - * @param listener - * listener to be removed - */ - public void removeListener(Container.ItemSetChangeListener listener); - } - - /* Property set change event */ - - /** - * An <code>Event</code> object specifying the Container whose Property set - * has changed. - * - * A property set change means the addition, removal or other structural - * changes to the properties of a container. Changes concerning the set of - * items in the container and their property values are not property set - * changes. - */ - public interface PropertySetChangeEvent extends Serializable { - - /** - * Retrieves the Container whose contents have been modified. - * - * @return Source Container of the event. - */ - public Container getContainer(); - } - - /** - * The listener interface for receiving <code>PropertySetChangeEvent</code> - * objects. - * - * A property set change means the addition, removal or other structural - * change of the properties (supported property IDs) of a container. Changes - * concerning the set of items in the container and their property values - * are not property set changes. - */ - public interface PropertySetChangeListener extends Serializable { - - /** - * Notifies this listener that the set of property IDs supported by the - * Container has changed. - * - * @param event - * Change event. - */ - public void containerPropertySetChange( - Container.PropertySetChangeEvent event); - } - - /** - * <p> - * The interface for adding and removing <code>PropertySetChangeEvent</code> - * listeners. By implementing this interface a class explicitly announces - * that it will generate a <code>PropertySetChangeEvent</code> when the set - * of property IDs supported by the container is modified. - * </p> - * - * <p> - * A property set change means the addition, removal or other structural - * changes to the properties of a container. Changes concerning the set of - * items in the container and their property values are not property set - * changes. - * </p> - * - * <p> - * Note that the general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * <code>addListener</code> and <code>removeListener</code> methods. That - * way the caller of these methods has no real way of finding out if the - * class really will send the events, or if it just defines the methods to - * be able to implement an interface. - * </p> - */ - public interface PropertySetChangeNotifier extends Serializable { - - /** - * Registers a new Property set change listener for this Container. - * - * @param listener - * The new Listener to be registered - */ - public void addListener(Container.PropertySetChangeListener listener); - - /** - * Removes a previously registered Property set change listener. - * - * @param listener - * Listener to be removed - */ - public void removeListener(Container.PropertySetChangeListener listener); - } -} diff --git a/src/com/vaadin/data/Item.java b/src/com/vaadin/data/Item.java deleted file mode 100644 index 98b95aecff..0000000000 --- a/src/com/vaadin/data/Item.java +++ /dev/null @@ -1,180 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data; - -import java.io.Serializable; -import java.util.Collection; - -/** - * <p> - * Provides a mechanism for handling a set of Properties, each associated to a - * locally unique non-null identifier. The interface is split into subinterfaces - * to enable a class to implement only the functionalities it needs. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 3.0 - */ -public interface Item extends Serializable { - - /** - * Gets the Property corresponding to the given Property ID stored in the - * Item. If the Item does not contain the Property, <code>null</code> is - * returned. - * - * @param id - * identifier of the Property to get - * @return the Property with the given ID or <code>null</code> - */ - public Property<?> getItemProperty(Object id); - - /** - * Gets the collection of IDs of all Properties stored in the Item. - * - * @return unmodifiable collection containing IDs of the Properties stored - * the Item - */ - public Collection<?> getItemPropertyIds(); - - /** - * Tries to add a new Property into the Item. - * - * <p> - * This functionality is optional. - * </p> - * - * @param id - * ID of the new Property - * @param property - * the Property to be added and associated with the id - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the operation is not supported. - */ - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException; - - /** - * Removes the Property identified by ID from the Item. - * - * <p> - * This functionality is optional. - * </p> - * - * @param id - * ID of the Property to be removed - * @return <code>true</code> if the operation succeeded - * @throws UnsupportedOperationException - * if the operation is not supported. <code>false</code> if not - */ - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException; - - /** - * Interface implemented by viewer classes capable of using an Item as a - * data source. - */ - public interface Viewer extends Serializable { - - /** - * Sets the Item that serves as the data source of the viewer. - * - * @param newDataSource - * The new data source Item - */ - public void setItemDataSource(Item newDataSource); - - /** - * Gets the Item serving as the data source of the viewer. - * - * @return data source Item - */ - public Item getItemDataSource(); - } - - /** - * Interface implemented by the <code>Editor</code> classes capable of - * editing the Item. Implementing this interface means that the Item serving - * as the data source of the editor can be modified through it. - * <p> - * Note : Not implementing the <code>Item.Editor</code> interface does not - * restrict the class from editing the contents of an internally. - * </p> - */ - public interface Editor extends Item.Viewer, Serializable { - - } - - /* Property set change event */ - - /** - * An <code>Event</code> object specifying the Item whose contents has been - * changed through the <code>Property</code> interface. - * <p> - * Note: The values stored in the Properties may change without triggering - * this event. - * </p> - */ - public interface PropertySetChangeEvent extends Serializable { - - /** - * Retrieves the Item whose contents has been modified. - * - * @return source Item of the event - */ - public Item getItem(); - } - - /** - * The listener interface for receiving <code>PropertySetChangeEvent</code> - * objects. - */ - public interface PropertySetChangeListener extends Serializable { - - /** - * Notifies this listener that the Item's property set has changed. - * - * @param event - * Property set change event object - */ - public void itemPropertySetChange(Item.PropertySetChangeEvent event); - } - - /** - * The interface for adding and removing <code>PropertySetChangeEvent</code> - * listeners. By implementing this interface a class explicitly announces - * that it will generate a <code>PropertySetChangeEvent</code> when its - * Property set is modified. - * <p> - * Note : The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * <code>addListener</code> and <code>removeListener</code> methods. That - * way the caller of these methods has no real way of finding out if the - * class really will send the events, or if it just defines the methods to - * be able to implement an interface. - * </p> - */ - public interface PropertySetChangeNotifier extends Serializable { - - /** - * Registers a new property set change listener for this Item. - * - * @param listener - * The new Listener to be registered. - */ - public void addListener(Item.PropertySetChangeListener listener); - - /** - * Removes a previously registered property set change listener. - * - * @param listener - * Listener to be removed. - */ - public void removeListener(Item.PropertySetChangeListener listener); - } -} diff --git a/src/com/vaadin/data/Property.java b/src/com/vaadin/data/Property.java deleted file mode 100644 index 9fab642381..0000000000 --- a/src/com/vaadin/data/Property.java +++ /dev/null @@ -1,402 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data; - -import java.io.Serializable; - -/** - * <p> - * The <code>Property</code> is a simple data object that contains one typed - * value. This interface contains methods to inspect and modify the stored value - * and its type, and the object's read-only state. - * </p> - * - * <p> - * The <code>Property</code> also defines the events - * <code>ReadOnlyStatusChangeEvent</code> and <code>ValueChangeEvent</code>, and - * the associated <code>listener</code> and <code>notifier</code> interfaces. - * </p> - * - * <p> - * The <code>Property.Viewer</code> interface should be used to attach the - * Property to an external data source. This way the value in the data source - * can be inspected using the <code>Property</code> interface. - * </p> - * - * <p> - * The <code>Property.editor</code> interface should be implemented if the value - * needs to be changed through the implementing class. - * </p> - * - * @param T - * type of values of the property - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 3.0 - */ -public interface Property<T> extends Serializable { - - /** - * Gets the value stored in the Property. The returned object is compatible - * with the class returned by getType(). - * - * @return the value stored in the Property - */ - public T getValue(); - - /** - * Sets the value of the Property. - * <p> - * Implementing this functionality is optional. If the functionality is - * missing, one should declare the Property to be in read-only mode and - * throw <code>Property.ReadOnlyException</code> in this function. - * </p> - * - * Note : Since Vaadin 7.0, setting the value of a non-String property as a - * String is no longer supported. - * - * @param newValue - * New value of the Property. This should be assignable to the - * type returned by getType - * - * @throws Property.ReadOnlyException - * if the object is in read-only mode - */ - public void setValue(Object newValue) throws Property.ReadOnlyException; - - /** - * Returns the type of the Property. The methods <code>getValue</code> and - * <code>setValue</code> must be compatible with this type: one must be able - * to safely cast the value returned from <code>getValue</code> to the given - * type and pass any variable assignable to this type as an argument to - * <code>setValue</code>. - * - * @return type of the Property - */ - public Class<? extends T> getType(); - - /** - * Tests if the Property is in read-only mode. In read-only mode calls to - * the method <code>setValue</code> will throw - * <code>ReadOnlyException</code> and will not modify the value of the - * Property. - * - * @return <code>true</code> if the Property is in read-only mode, - * <code>false</code> if it's not - */ - public boolean isReadOnly(); - - /** - * Sets the Property's read-only mode to the specified status. - * - * This functionality is optional, but all properties must implement the - * <code>isReadOnly</code> mode query correctly. - * - * @param newStatus - * new read-only status of the Property - */ - public void setReadOnly(boolean newStatus); - - /** - * A Property that is capable of handle a transaction that can end in commit - * or rollback. - * - * Note that this does not refer to e.g. database transactions but rather - * two-phase commit that allows resetting old field values on a form etc. if - * the commit of one of the properties fails after others have already been - * committed. If - * - * @param <T> - * The type of the property - * @author Vaadin Ltd - * @version @version@ - * @since 7.0 - */ - public interface Transactional<T> extends Property<T> { - - /** - * Starts a transaction. - * - * <p> - * If the value is set during a transaction the value must not replace - * the original value until {@link #commit()} is called. Still, - * {@link #getValue()} must return the current value set in the - * transaction. Calling {@link #rollback()} while in a transaction must - * rollback the value to what it was before the transaction started. - * </p> - * <p> - * {@link ValueChangeEvent}s must not be emitted for internal value - * changes during a transaction. If the value changes as a result of - * {@link #commit()}, a {@link ValueChangeEvent} should be emitted. - * </p> - */ - public void startTransaction(); - - /** - * Commits and ends the transaction that is in progress. - * <p> - * If the value is changed as a result of this operation, a - * {@link ValueChangeEvent} is emitted if such are supported. - * <p> - * This method has no effect if there is no transaction is in progress. - * <p> - * This method must never throw an exception. - */ - public void commit(); - - /** - * Aborts and rolls back the transaction that is in progress. - * <p> - * The value is reset to the value before the transaction started. No - * {@link ValueChangeEvent} is emitted as a result of this. - * <p> - * This method has no effect if there is no transaction is in progress. - * <p> - * This method must never throw an exception. - */ - public void rollback(); - } - - /** - * <code>Exception</code> object that signals that a requested Property - * modification failed because it's in read-only mode. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - @SuppressWarnings("serial") - public class ReadOnlyException extends RuntimeException { - - /** - * Constructs a new <code>ReadOnlyException</code> without a detail - * message. - */ - public ReadOnlyException() { - } - - /** - * Constructs a new <code>ReadOnlyException</code> with the specified - * detail message. - * - * @param msg - * the detail message - */ - public ReadOnlyException(String msg) { - super(msg); - } - } - - /** - * Interface implemented by the viewer classes capable of using a Property - * as a data source. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface Viewer extends Serializable { - - /** - * Sets the Property that serves as the data source of the viewer. - * - * @param newDataSource - * the new data source Property - */ - public void setPropertyDataSource(Property newDataSource); - - /** - * Gets the Property serving as the data source of the viewer. - * - * @return the Property serving as the viewers data source - */ - public Property getPropertyDataSource(); - } - - /** - * Interface implemented by the editor classes capable of editing the - * Property. - * <p> - * Implementing this interface means that the Property serving as the data - * source of the editor can be modified through the editor. It does not - * restrict the editor from editing the Property internally, though if the - * Property is in a read-only mode, attempts to modify it will result in the - * <code>ReadOnlyException</code> being thrown. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface Editor extends Property.Viewer, Serializable { - - } - - /* Value change event */ - - /** - * An <code>Event</code> object specifying the Property whose value has been - * changed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ValueChangeEvent extends Serializable { - - /** - * Retrieves the Property that has been modified. - * - * @return source Property of the event - */ - public Property getProperty(); - } - - /** - * The <code>listener</code> interface for receiving - * <code>ValueChangeEvent</code> objects. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ValueChangeListener extends Serializable { - - /** - * Notifies this listener that the Property's value has changed. - * - * @param event - * value change event object - */ - public void valueChange(Property.ValueChangeEvent event); - } - - /** - * The interface for adding and removing <code>ValueChangeEvent</code> - * listeners. If a Property wishes to allow other objects to receive - * <code>ValueChangeEvent</code> generated by it, it must implement this - * interface. - * <p> - * Note : The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * <code>addListener</code> and <code>removeListener</code> methods. That - * way the caller of these methods has no real way of finding out if the - * class really will send the events, or if it just defines the methods to - * be able to implement an interface. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ValueChangeNotifier extends Serializable { - - /** - * Registers a new value change listener for this Property. - * - * @param listener - * the new Listener to be registered - */ - public void addListener(Property.ValueChangeListener listener); - - /** - * Removes a previously registered value change listener. - * - * @param listener - * listener to be removed - */ - public void removeListener(Property.ValueChangeListener listener); - } - - /* ReadOnly Status change event */ - - /** - * An <code>Event</code> object specifying the Property whose read-only - * status has been changed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ReadOnlyStatusChangeEvent extends Serializable { - - /** - * Property whose read-only state has changed. - * - * @return source Property of the event. - */ - public Property getProperty(); - } - - /** - * The listener interface for receiving - * <code>ReadOnlyStatusChangeEvent</code> objects. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ReadOnlyStatusChangeListener extends Serializable { - - /** - * Notifies this listener that a Property's read-only status has - * changed. - * - * @param event - * Read-only status change event object - */ - public void readOnlyStatusChange( - Property.ReadOnlyStatusChangeEvent event); - } - - /** - * The interface for adding and removing - * <code>ReadOnlyStatusChangeEvent</code> listeners. If a Property wishes to - * allow other objects to receive <code>ReadOnlyStatusChangeEvent</code> - * generated by it, it must implement this interface. - * <p> - * Note : The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * <code>addListener</code> and <code>removeListener</code> methods. That - * way the caller of these methods has no real way of finding out if the - * class really will send the events, or if it just defines the methods to - * be able to implement an interface. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ReadOnlyStatusChangeNotifier extends Serializable { - - /** - * Registers a new read-only status change listener for this Property. - * - * @param listener - * the new Listener to be registered - */ - public void addListener(Property.ReadOnlyStatusChangeListener listener); - - /** - * Removes a previously registered read-only status change listener. - * - * @param listener - * listener to be removed - */ - public void removeListener( - Property.ReadOnlyStatusChangeListener listener); - } -} diff --git a/src/com/vaadin/data/Validatable.java b/src/com/vaadin/data/Validatable.java deleted file mode 100644 index 4a7a0fda10..0000000000 --- a/src/com/vaadin/data/Validatable.java +++ /dev/null @@ -1,110 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data; - -import java.io.Serializable; -import java.util.Collection; - -/** - * <p> - * Interface for validatable objects. Defines methods to verify if the object's - * value is valid or not, and to add, remove and list registered validators of - * the object. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - * @see com.vaadin.data.Validator - */ -public interface Validatable extends Serializable { - - /** - * <p> - * Adds a new validator for this object. The validator's - * {@link Validator#validate(Object)} method is activated every time the - * object's value needs to be verified, that is, when the {@link #isValid()} - * method is called. This usually happens when the object's value changes. - * </p> - * - * @param validator - * the new validator - */ - void addValidator(Validator validator); - - /** - * <p> - * Removes a previously registered validator from the object. The specified - * validator is removed from the object and its <code>validate</code> method - * is no longer called in {@link #isValid()}. - * </p> - * - * @param validator - * the validator to remove - */ - void removeValidator(Validator validator); - - /** - * <p> - * Lists all validators currently registered for the object. If no - * validators are registered, returns <code>null</code>. - * </p> - * - * @return collection of validators or <code>null</code> - */ - public Collection<Validator> getValidators(); - - /** - * <p> - * Tests the current value of the object against all registered validators. - * The registered validators are iterated and for each the - * {@link Validator#validate(Object)} method is called. If any validator - * throws the {@link Validator.InvalidValueException} this method returns - * <code>false</code>. - * </p> - * - * @return <code>true</code> if the registered validators concur that the - * value is valid, <code>false</code> otherwise - */ - public boolean isValid(); - - /** - * <p> - * Checks the validity of the validatable. If the validatable is valid this - * method should do nothing, and if it's not valid, it should throw - * <code>Validator.InvalidValueException</code> - * </p> - * - * @throws Validator.InvalidValueException - * if the value is not valid - */ - public void validate() throws Validator.InvalidValueException; - - /** - * <p> - * Checks the validabtable object accept invalid values.The default value is - * <code>true</code>. - * </p> - * - */ - public boolean isInvalidAllowed(); - - /** - * <p> - * Should the validabtable object accept invalid values. Supporting this - * configuration possibility is optional. By default invalid values are - * allowed. - * </p> - * - * @param invalidValueAllowed - * - * @throws UnsupportedOperationException - * if the setInvalidAllowed is not supported. - */ - public void setInvalidAllowed(boolean invalidValueAllowed) - throws UnsupportedOperationException; - -} diff --git a/src/com/vaadin/data/Validator.java b/src/com/vaadin/data/Validator.java deleted file mode 100644 index 768a02babe..0000000000 --- a/src/com/vaadin/data/Validator.java +++ /dev/null @@ -1,175 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data; - -import java.io.Serializable; - -import com.vaadin.terminal.gwt.server.AbstractApplicationServlet; - -/** - * Interface that implements a method for validating if an {@link Object} is - * valid or not. - * <p> - * Implementors of this class can be added to any - * {@link com.vaadin.data.Validatable Validatable} implementor to verify its - * value. - * </p> - * <p> - * {@link #validate(Object)} can be used to check if a value is valid. An - * {@link InvalidValueException} with an appropriate validation error message is - * thrown if the value is not valid. - * </p> - * <p> - * Validators must not have any side effects. - * </p> - * <p> - * Since Vaadin 7, the method isValid(Object) does not exist in the interface - - * {@link #validate(Object)} should be used instead, and the exception caught - * where applicable. Concrete classes implementing {@link Validator} can still - * internally implement and use isValid(Object) for convenience or to ease - * migration from earlier Vaadin versions. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -public interface Validator extends Serializable { - - /** - * Checks the given value against this validator. If the value is valid the - * method does nothing. If the value is invalid, an - * {@link InvalidValueException} is thrown. - * - * @param value - * the value to check - * @throws Validator.InvalidValueException - * if the value is invalid - */ - public void validate(Object value) throws Validator.InvalidValueException; - - /** - * Exception that is thrown by a {@link Validator} when a value is invalid. - * - * <p> - * The default implementation of InvalidValueException does not support HTML - * in error messages. To enable HTML support, override - * {@link #getHtmlMessage()} and use the subclass in validators. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - @SuppressWarnings("serial") - public class InvalidValueException extends RuntimeException { - - /** - * Array of one or more validation errors that are causing this - * validation error. - */ - private InvalidValueException[] causes = null; - - /** - * Constructs a new {@code InvalidValueException} with the specified - * message. - * - * @param message - * The detail message of the problem. - */ - public InvalidValueException(String message) { - this(message, new InvalidValueException[] {}); - } - - /** - * Constructs a new {@code InvalidValueException} with a set of causing - * validation exceptions. The causing validation exceptions are included - * when the exception is painted to the client. - * - * @param message - * The detail message of the problem. - * @param causes - * One or more {@code InvalidValueException}s that caused - * this exception. - */ - public InvalidValueException(String message, - InvalidValueException[] causes) { - super(message); - if (causes == null) { - throw new NullPointerException( - "Possible causes array must not be null"); - } - - this.causes = causes; - } - - /** - * Check if the error message should be hidden. - * - * An empty (null or "") message is invisible unless it contains nested - * exceptions that are visible. - * - * @return true if the error message should be hidden, false otherwise - */ - public boolean isInvisible() { - String msg = getMessage(); - if (msg != null && msg.length() > 0) { - return false; - } - if (causes != null) { - for (int i = 0; i < causes.length; i++) { - if (!causes[i].isInvisible()) { - return false; - } - } - } - return true; - } - - /** - * Returns the message of the error in HTML. - * - * Note that this API may change in future versions. - */ - public String getHtmlMessage() { - return AbstractApplicationServlet - .safeEscapeForHtml(getLocalizedMessage()); - } - - /** - * Returns the {@code InvalidValueExceptions} that caused this - * exception. - * - * @return An array containing the {@code InvalidValueExceptions} that - * caused this exception. Returns an empty array if this - * exception was not caused by other exceptions. - */ - public InvalidValueException[] getCauses() { - return causes; - } - - } - - /** - * A specific type of {@link InvalidValueException} that indicates that - * validation failed because the value was empty. What empty means is up to - * the thrower. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.3.0 - */ - @SuppressWarnings("serial") - public class EmptyValueException extends Validator.InvalidValueException { - - public EmptyValueException(String message) { - super(message); - } - - } -} diff --git a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java deleted file mode 100644 index b8efa5b1e4..0000000000 --- a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java +++ /dev/null @@ -1,157 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.fieldgroup; - -import java.lang.reflect.Method; - -import com.vaadin.data.Item; -import com.vaadin.data.util.BeanItem; -import com.vaadin.data.validator.BeanValidator; -import com.vaadin.ui.Field; - -public class BeanFieldGroup<T> extends FieldGroup { - - private Class<T> beanType; - - private static Boolean beanValidationImplementationAvailable = null; - - public BeanFieldGroup(Class<T> beanType) { - this.beanType = beanType; - } - - @Override - protected Class<?> getPropertyType(Object propertyId) { - if (getItemDataSource() != null) { - return super.getPropertyType(propertyId); - } else { - // Data source not set so we need to figure out the type manually - /* - * toString should never really be needed as propertyId should be of - * form "fieldName" or "fieldName.subField[.subField2]" but the - * method declaration comes from parent. - */ - java.lang.reflect.Field f; - try { - f = getField(beanType, propertyId.toString()); - return f.getType(); - } catch (SecurityException e) { - throw new BindException("Cannot determine type of propertyId '" - + propertyId + "'.", e); - } catch (NoSuchFieldException e) { - throw new BindException("Cannot determine type of propertyId '" - + propertyId + "'. The propertyId was not found in " - + beanType.getName(), e); - } - } - } - - private static java.lang.reflect.Field getField(Class<?> cls, - String propertyId) throws SecurityException, NoSuchFieldException { - if (propertyId.contains(".")) { - String[] parts = propertyId.split("\\.", 2); - // Get the type of the field in the "cls" class - java.lang.reflect.Field field1 = getField(cls, parts[0]); - // Find the rest from the sub type - return getField(field1.getType(), parts[1]); - } else { - try { - // Try to find the field directly in the given class - java.lang.reflect.Field field1 = cls - .getDeclaredField(propertyId); - return field1; - } catch (NoSuchFieldError e) { - // Try super classes until we reach Object - Class<?> superClass = cls.getSuperclass(); - if (superClass != Object.class) { - return getField(superClass, propertyId); - } else { - throw e; - } - } - } - } - - /** - * Helper method for setting the data source directly using a bean. This - * method wraps the bean in a {@link BeanItem} and calls - * {@link #setItemDataSource(Item)}. - * - * @param bean - * The bean to use as data source. - */ - public void setItemDataSource(T bean) { - setItemDataSource(new BeanItem(bean)); - } - - @Override - public void setItemDataSource(Item item) { - if (!(item instanceof BeanItem)) { - throw new RuntimeException(getClass().getSimpleName() - + " only supports BeanItems as item data source"); - } - super.setItemDataSource(item); - } - - @Override - public BeanItem<T> getItemDataSource() { - return (BeanItem<T>) super.getItemDataSource(); - } - - @Override - public void bind(Field field, Object propertyId) { - if (getItemDataSource() != null) { - // The data source is set so the property must be found in the item. - // If it is not we try to add it. - try { - getItemProperty(propertyId); - } catch (BindException e) { - // Not found, try to add a nested property; - // BeanItem property ids are always strings so this is safe - getItemDataSource().addNestedProperty((String) propertyId); - } - } - - super.bind(field, propertyId); - } - - @Override - protected void configureField(Field<?> field) { - super.configureField(field); - // Add Bean validators if there are annotations - if (isBeanValidationImplementationAvailable()) { - BeanValidator validator = new BeanValidator(beanType, - getPropertyId(field).toString()); - field.addValidator(validator); - if (field.getLocale() != null) { - validator.setLocale(field.getLocale()); - } - } - } - - /** - * Checks whether a bean validation implementation (e.g. Hibernate Validator - * or Apache Bean Validation) is available. - * - * TODO move this method to some more generic location - * - * @return true if a JSR-303 bean validation implementation is available - */ - protected static boolean isBeanValidationImplementationAvailable() { - if (beanValidationImplementationAvailable != null) { - return beanValidationImplementationAvailable; - } - try { - Class<?> validationClass = Class - .forName("javax.validation.Validation"); - Method buildFactoryMethod = validationClass - .getMethod("buildDefaultValidatorFactory"); - Object factory = buildFactoryMethod.invoke(null); - beanValidationImplementationAvailable = (factory != null); - } catch (Exception e) { - // no bean validation implementation available - beanValidationImplementationAvailable = false; - } - return beanValidationImplementationAvailable; - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/fieldgroup/Caption.java b/src/com/vaadin/data/fieldgroup/Caption.java deleted file mode 100644 index b990b720cd..0000000000 --- a/src/com/vaadin/data/fieldgroup/Caption.java +++ /dev/null @@ -1,15 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.fieldgroup; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface Caption { - String value(); -} diff --git a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java deleted file mode 100644 index be0db328f2..0000000000 --- a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java +++ /dev/null @@ -1,157 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.fieldgroup; - -import java.util.EnumSet; - -import com.vaadin.data.Item; -import com.vaadin.data.fieldgroup.FieldGroup.BindException; -import com.vaadin.ui.AbstractSelect; -import com.vaadin.ui.AbstractTextField; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Field; -import com.vaadin.ui.ListSelect; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.OptionGroup; -import com.vaadin.ui.RichTextArea; -import com.vaadin.ui.Table; -import com.vaadin.ui.TextField; - -public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory { - - public static final Object CAPTION_PROPERTY_ID = "Caption"; - - @Override - public <T extends Field> T createField(Class<?> type, Class<T> fieldType) { - if (Enum.class.isAssignableFrom(type)) { - return createEnumField(type, fieldType); - } else if (Boolean.class.isAssignableFrom(type) - || boolean.class.isAssignableFrom(type)) { - return createBooleanField(fieldType); - } - if (AbstractTextField.class.isAssignableFrom(fieldType)) { - return fieldType.cast(createAbstractTextField(fieldType - .asSubclass(AbstractTextField.class))); - } else if (fieldType == RichTextArea.class) { - return fieldType.cast(createRichTextArea()); - } - return createDefaultField(type, fieldType); - } - - protected RichTextArea createRichTextArea() { - RichTextArea rta = new RichTextArea(); - rta.setImmediate(true); - - return rta; - } - - private <T extends Field> T createEnumField(Class<?> type, - Class<T> fieldType) { - if (AbstractSelect.class.isAssignableFrom(fieldType)) { - AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType); - populateWithEnumData(s, (Class<? extends Enum>) type); - return (T) s; - } - - return null; - } - - protected AbstractSelect createCompatibleSelect( - Class<? extends AbstractSelect> fieldType) { - AbstractSelect select; - if (fieldType.isAssignableFrom(ListSelect.class)) { - select = new ListSelect(); - select.setMultiSelect(false); - } else if (fieldType.isAssignableFrom(NativeSelect.class)) { - select = new NativeSelect(); - } else if (fieldType.isAssignableFrom(OptionGroup.class)) { - select = new OptionGroup(); - select.setMultiSelect(false); - } else if (fieldType.isAssignableFrom(Table.class)) { - Table t = new Table(); - t.setSelectable(true); - select = t; - } else { - select = new ComboBox(null); - } - select.setImmediate(true); - select.setNullSelectionAllowed(false); - - return select; - } - - protected <T extends Field> T createBooleanField(Class<T> fieldType) { - if (fieldType.isAssignableFrom(CheckBox.class)) { - CheckBox cb = new CheckBox(null); - cb.setImmediate(true); - return (T) cb; - } else if (AbstractTextField.class.isAssignableFrom(fieldType)) { - return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType); - } - - return null; - } - - protected <T extends AbstractTextField> T createAbstractTextField( - Class<T> fieldType) { - if (fieldType == AbstractTextField.class) { - fieldType = (Class<T>) TextField.class; - } - try { - T field = fieldType.newInstance(); - field.setImmediate(true); - return field; - } catch (Exception e) { - throw new BindException("Could not create a field of type " - + fieldType, e); - } - } - - /** - * Fallback when no specific field has been created. Typically returns a - * TextField. - * - * @param <T> - * The type of field to create - * @param type - * The type of data that should be edited - * @param fieldType - * The type of field to create - * @return A field capable of editing the data or null if no field could be - * created - */ - protected <T extends Field> T createDefaultField(Class<?> type, - Class<T> fieldType) { - if (fieldType.isAssignableFrom(TextField.class)) { - return fieldType.cast(createAbstractTextField(TextField.class)); - } - return null; - } - - /** - * Populates the given select with all the enums in the given {@link Enum} - * class. Uses {@link Enum}.toString() for caption. - * - * @param select - * The select to populate - * @param enumClass - * The Enum class to use - */ - protected void populateWithEnumData(AbstractSelect select, - Class<? extends Enum> enumClass) { - select.removeAllItems(); - for (Object p : select.getContainerPropertyIds()) { - select.removeContainerProperty(p); - } - select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, ""); - select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID); - @SuppressWarnings("unchecked") - EnumSet<?> enumSet = EnumSet.allOf(enumClass); - for (Object r : enumSet) { - Item newItem = select.addItem(r); - newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString()); - } - } -} diff --git a/src/com/vaadin/data/fieldgroup/FieldGroup.java b/src/com/vaadin/data/fieldgroup/FieldGroup.java deleted file mode 100644 index 3df19f5bc9..0000000000 --- a/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ /dev/null @@ -1,978 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.fieldgroup; - -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.logging.Logger; - -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.Validator.InvalidValueException; -import com.vaadin.data.util.TransactionalPropertyWrapper; -import com.vaadin.tools.ReflectTools; -import com.vaadin.ui.DefaultFieldFactory; -import com.vaadin.ui.Field; -import com.vaadin.ui.Form; - -/** - * FieldGroup provides an easy way of binding fields to data and handling - * commits of these fields. - * <p> - * The functionality of FieldGroup is similar to {@link Form} but - * {@link FieldGroup} does not handle layouts in any way. The typical use case - * is to create a layout outside the FieldGroup and then use FieldGroup to bind - * the fields to a data source. - * </p> - * <p> - * {@link FieldGroup} is not a UI component so it cannot be added to a layout. - * Using the buildAndBind methods {@link FieldGroup} can create fields for you - * using a FieldGroupFieldFactory but you still have to add them to the correct - * position in your layout. - * </p> - * - * @author Vaadin Ltd - * @version @version@ - * @since 7.0 - */ -public class FieldGroup implements Serializable { - - private static final Logger logger = Logger.getLogger(FieldGroup.class - .getName()); - - private Item itemDataSource; - private boolean buffered = true; - - private boolean enabled = true; - private boolean readOnly = false; - - private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>(); - private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>(); - private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>(); - - /** - * The field factory used by builder methods. - */ - private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory(); - - /** - * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a - * data source for the field binder. - * - */ - public FieldGroup() { - - } - - /** - * Constructs a field binder that uses the given data source. - * - * @param itemDataSource - * The data source to bind the fields to - */ - public FieldGroup(Item itemDataSource) { - setItemDataSource(itemDataSource); - } - - /** - * Updates the item that is used by this FieldBinder. Rebinds all fields to - * the properties in the new item. - * - * @param itemDataSource - * The new item to use - */ - public void setItemDataSource(Item itemDataSource) { - this.itemDataSource = itemDataSource; - - for (Field<?> f : fieldToPropertyId.keySet()) { - bind(f, fieldToPropertyId.get(f)); - } - } - - /** - * Gets the item used by this FieldBinder. Note that you must call - * {@link #commit()} for the item to be updated unless buffered mode has - * been switched off. - * - * @see #setBuffered(boolean) - * @see #commit() - * - * @return The item used by this FieldBinder - */ - public Item getItemDataSource() { - return itemDataSource; - } - - /** - * Checks the buffered mode for the bound fields. - * <p> - * - * @see #setBuffered(boolean) for more details on buffered mode - * - * @see Field#isBuffered() - * @return true if buffered mode is on, false otherwise - * - */ - public boolean isBuffered() { - return buffered; - } - - /** - * Sets the buffered mode for the bound fields. - * <p> - * When buffered mode is on the item will not be updated until - * {@link #commit()} is called. If buffered mode is off the item will be - * updated once the fields are updated. - * </p> - * <p> - * The default is to use buffered mode. - * </p> - * - * @see Field#setBuffered(boolean) - * @param buffered - * true to turn on buffered mode, false otherwise - */ - public void setBuffered(boolean buffered) { - if (buffered == this.buffered) { - return; - } - - this.buffered = buffered; - for (Field<?> field : getFields()) { - field.setBuffered(buffered); - } - } - - /** - * Returns the enabled status for the fields. - * <p> - * Note that this will not accurately represent the enabled status of all - * fields if you change the enabled status of the fields through some other - * method than {@link #setEnabled(boolean)}. - * - * @return true if the fields are enabled, false otherwise - */ - public boolean isEnabled() { - return enabled; - } - - /** - * Updates the enabled state of all bound fields. - * - * @param fieldsEnabled - * true to enable all bound fields, false to disable them - */ - public void setEnabled(boolean fieldsEnabled) { - enabled = fieldsEnabled; - for (Field<?> field : getFields()) { - field.setEnabled(fieldsEnabled); - } - } - - /** - * Returns the read only status for the fields. - * <p> - * Note that this will not accurately represent the read only status of all - * fields if you change the read only status of the fields through some - * other method than {@link #setReadOnly(boolean)}. - * - * @return true if the fields are set to read only, false otherwise - */ - public boolean isReadOnly() { - return readOnly; - } - - /** - * Updates the read only state of all bound fields. - * - * @param fieldsReadOnly - * true to set all bound fields to read only, false to set them - * to read write - */ - public void setReadOnly(boolean fieldsReadOnly) { - readOnly = fieldsReadOnly; - } - - /** - * Returns a collection of all fields that have been bound. - * <p> - * The fields are not returned in any specific order. - * </p> - * - * @return A collection with all bound Fields - */ - public Collection<Field<?>> getFields() { - return fieldToPropertyId.keySet(); - } - - /** - * Binds the field with the given propertyId from the current item. If an - * item has not been set then the binding is postponed until the item is set - * using {@link #setItemDataSource(Item)}. - * <p> - * This method also adds validators when applicable. - * </p> - * - * @param field - * The field to bind - * @param propertyId - * The propertyId to bind to the field - * @throws BindException - * If the property id is already bound to another field by this - * field binder - */ - public void bind(Field<?> field, Object propertyId) throws BindException { - if (propertyIdToField.containsKey(propertyId) - && propertyIdToField.get(propertyId) != field) { - throw new BindException("Property id " + propertyId - + " is already bound to another field"); - } - fieldToPropertyId.put(field, propertyId); - propertyIdToField.put(propertyId, field); - if (itemDataSource == null) { - // Will be bound when data source is set - return; - } - - field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId))); - configureField(field); - } - - private <T> Property.Transactional<T> wrapInTransactionalProperty( - Property<T> itemProperty) { - return new TransactionalPropertyWrapper<T>(itemProperty); - } - - /** - * Gets the property with the given property id from the item. - * - * @param propertyId - * The id if the property to find - * @return The property with the given id from the item - * @throws BindException - * If the property was not found in the item or no item has been - * set - */ - protected Property<?> getItemProperty(Object propertyId) - throws BindException { - Item item = getItemDataSource(); - if (item == null) { - throw new BindException("Could not lookup property with id " - + propertyId + " as no item has been set"); - } - Property<?> p = item.getItemProperty(propertyId); - if (p == null) { - throw new BindException("A property with id " + propertyId - + " was not found in the item"); - } - return p; - } - - /** - * Detaches the field from its property id and removes it from this - * FieldBinder. - * <p> - * Note that the field is not detached from its property data source if it - * is no longer connected to the same property id it was bound to using this - * FieldBinder. - * - * @param field - * The field to detach - * @throws BindException - * If the field is not bound by this field binder or not bound - * to the correct property id - */ - public void unbind(Field<?> field) throws BindException { - Object propertyId = fieldToPropertyId.get(field); - if (propertyId == null) { - throw new BindException( - "The given field is not part of this FieldBinder"); - } - - Property fieldDataSource = field.getPropertyDataSource(); - if (fieldDataSource instanceof TransactionalPropertyWrapper) { - fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource) - .getWrappedProperty(); - } - if (fieldDataSource == getItemProperty(propertyId)) { - field.setPropertyDataSource(null); - } - fieldToPropertyId.remove(field); - propertyIdToField.remove(propertyId); - } - - /** - * Configures a field with the settings set for this FieldBinder. - * <p> - * By default this updates the buffered, read only and enabled state of the - * field. Also adds validators when applicable. - * - * @param field - * The field to update - */ - protected void configureField(Field<?> field) { - field.setBuffered(isBuffered()); - - field.setEnabled(isEnabled()); - field.setReadOnly(isReadOnly()); - } - - /** - * Gets the type of the property with the given property id. - * - * @param propertyId - * The propertyId. Must be find - * @return The type of the property - */ - protected Class<?> getPropertyType(Object propertyId) throws BindException { - if (getItemDataSource() == null) { - throw new BindException( - "Property type for '" - + propertyId - + "' could not be determined. No item data source has been set."); - } - Property<?> p = getItemDataSource().getItemProperty(propertyId); - if (p == null) { - throw new BindException( - "Property type for '" - + propertyId - + "' could not be determined. No property with that id was found."); - } - - return p.getType(); - } - - /** - * Returns a collection of all property ids that have been bound to fields. - * <p> - * Note that this will return property ids even before the item has been - * set. In that case it returns the property ids that will be bound once the - * item is set. - * </p> - * <p> - * No guarantee is given for the order of the property ids - * </p> - * - * @return A collection of bound property ids - */ - public Collection<Object> getBoundPropertyIds() { - return Collections.unmodifiableCollection(propertyIdToField.keySet()); - } - - /** - * Returns a collection of all property ids that exist in the item set using - * {@link #setItemDataSource(Item)} but have not been bound to fields. - * <p> - * Will always return an empty collection before an item has been set using - * {@link #setItemDataSource(Item)}. - * </p> - * <p> - * No guarantee is given for the order of the property ids - * </p> - * - * @return A collection of property ids that have not been bound to fields - */ - public Collection<Object> getUnboundPropertyIds() { - if (getItemDataSource() == null) { - return new ArrayList<Object>(); - } - List<Object> unboundPropertyIds = new ArrayList<Object>(); - unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds()); - unboundPropertyIds.removeAll(propertyIdToField.keySet()); - return unboundPropertyIds; - } - - /** - * Commits all changes done to the bound fields. - * <p> - * Calls all {@link CommitHandler}s before and after committing the field - * changes to the item data source. The whole commit is aborted and state is - * restored to what it was before commit was called if any - * {@link CommitHandler} throws a CommitException or there is a problem - * committing the fields - * - * @throws CommitException - * If the commit was aborted - */ - public void commit() throws CommitException { - if (!isBuffered()) { - // Not using buffered mode, nothing to do - return; - } - for (Field<?> f : fieldToPropertyId.keySet()) { - ((Property.Transactional<?>) f.getPropertyDataSource()) - .startTransaction(); - } - try { - firePreCommitEvent(); - // Commit the field values to the properties - for (Field<?> f : fieldToPropertyId.keySet()) { - f.commit(); - } - firePostCommitEvent(); - - // Commit the properties - for (Field<?> f : fieldToPropertyId.keySet()) { - ((Property.Transactional<?>) f.getPropertyDataSource()) - .commit(); - } - - } catch (Exception e) { - for (Field<?> f : fieldToPropertyId.keySet()) { - try { - ((Property.Transactional<?>) f.getPropertyDataSource()) - .rollback(); - } catch (Exception rollbackException) { - // FIXME: What to do ? - } - } - - throw new CommitException("Commit failed", e); - } - - } - - /** - * Sends a preCommit event to all registered commit handlers - * - * @throws CommitException - * If the commit should be aborted - */ - private void firePreCommitEvent() throws CommitException { - CommitHandler[] handlers = commitHandlers - .toArray(new CommitHandler[commitHandlers.size()]); - - for (CommitHandler handler : handlers) { - handler.preCommit(new CommitEvent(this)); - } - } - - /** - * Sends a postCommit event to all registered commit handlers - * - * @throws CommitException - * If the commit should be aborted - */ - private void firePostCommitEvent() throws CommitException { - CommitHandler[] handlers = commitHandlers - .toArray(new CommitHandler[commitHandlers.size()]); - - for (CommitHandler handler : handlers) { - handler.postCommit(new CommitEvent(this)); - } - } - - /** - * Discards all changes done to the bound fields. - * <p> - * Only has effect if buffered mode is used. - * - */ - public void discard() { - for (Field<?> f : fieldToPropertyId.keySet()) { - try { - f.discard(); - } catch (Exception e) { - // TODO: handle exception - // What can we do if discard fails other than try to discard all - // other fields? - } - } - } - - /** - * Returns the field that is bound to the given property id - * - * @param propertyId - * The property id to use to lookup the field - * @return The field that is bound to the property id or null if no field is - * bound to that property id - */ - public Field<?> getField(Object propertyId) { - return propertyIdToField.get(propertyId); - } - - /** - * Returns the property id that is bound to the given field - * - * @param field - * The field to use to lookup the property id - * @return The property id that is bound to the field or null if the field - * is not bound to any property id by this FieldBinder - */ - public Object getPropertyId(Field<?> field) { - return fieldToPropertyId.get(field); - } - - /** - * Adds a commit handler. - * <p> - * The commit handler is called before the field values are committed to the - * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item - * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a - * {@link CommitHandler} throws a CommitException the whole commit is - * aborted and the fields retain their old values. - * - * @param commitHandler - * The commit handler to add - */ - public void addCommitHandler(CommitHandler commitHandler) { - commitHandlers.add(commitHandler); - } - - /** - * Removes the given commit handler. - * - * @see #addCommitHandler(CommitHandler) - * - * @param commitHandler - * The commit handler to remove - */ - public void removeCommitHandler(CommitHandler commitHandler) { - commitHandlers.remove(commitHandler); - } - - /** - * Returns a list of all commit handlers for this {@link FieldGroup}. - * <p> - * Use {@link #addCommitHandler(CommitHandler)} and - * {@link #removeCommitHandler(CommitHandler)} to register or unregister a - * commit handler. - * - * @return A collection of commit handlers - */ - protected Collection<CommitHandler> getCommitHandlers() { - return Collections.unmodifiableCollection(commitHandlers); - } - - /** - * CommitHandlers are used by {@link FieldGroup#commit()} as part of the - * commit transactions. CommitHandlers can perform custom operations as part - * of the commit and cause the commit to be aborted by throwing a - * {@link CommitException}. - */ - public interface CommitHandler extends Serializable { - /** - * Called before changes are committed to the field and the item is - * updated. - * <p> - * Throw a {@link CommitException} to abort the commit. - * - * @param commitEvent - * An event containing information regarding the commit - * @throws CommitException - * if the commit should be aborted - */ - public void preCommit(CommitEvent commitEvent) throws CommitException; - - /** - * Called after changes are committed to the fields and the item is - * updated.. - * <p> - * Throw a {@link CommitException} to abort the commit. - * - * @param commitEvent - * An event containing information regarding the commit - * @throws CommitException - * if the commit should be aborted - */ - public void postCommit(CommitEvent commitEvent) throws CommitException; - } - - /** - * FIXME javadoc - * - */ - public static class CommitEvent implements Serializable { - private FieldGroup fieldBinder; - - private CommitEvent(FieldGroup fieldBinder) { - this.fieldBinder = fieldBinder; - } - - /** - * Returns the field binder that this commit relates to - * - * @return The FieldBinder that is being committed. - */ - public FieldGroup getFieldBinder() { - return fieldBinder; - } - - } - - /** - * Checks the validity of the bound fields. - * <p> - * Call the {@link Field#validate()} for the fields to get the individual - * error messages. - * - * @return true if all bound fields are valid, false otherwise. - */ - public boolean isValid() { - try { - for (Field<?> field : getFields()) { - field.validate(); - } - return true; - } catch (InvalidValueException e) { - return false; - } - } - - /** - * Checks if any bound field has been modified. - * - * @return true if at least on field has been modified, false otherwise - */ - public boolean isModified() { - for (Field<?> field : getFields()) { - if (field.isModified()) { - return true; - } - } - return false; - } - - /** - * Gets the field factory for the {@link FieldGroup}. The field factory is - * only used when {@link FieldGroup} creates a new field. - * - * @return The field factory in use - * - */ - public FieldGroupFieldFactory getFieldFactory() { - return fieldFactory; - } - - /** - * Sets the field factory for the {@link FieldGroup}. The field factory is - * only used when {@link FieldGroup} creates a new field. - * - * @param fieldFactory - * The field factory to use - */ - public void setFieldFactory(FieldGroupFieldFactory fieldFactory) { - this.fieldFactory = fieldFactory; - } - - /** - * Binds member fields found in the given object. - * <p> - * This method processes all (Java) member fields whose type extends - * {@link Field} and that can be mapped to a property id. Property id - * mapping is done based on the field name or on a @{@link PropertyId} - * annotation on the field. All non-null fields for which a property id can - * be determined are bound to the property id. - * </p> - * <p> - * For example: - * - * <pre> - * public class MyForm extends VerticalLayout { - * private TextField firstName = new TextField("First name"); - * @PropertyId("last") - * private TextField lastName = new TextField("Last name"); - * private TextField age = new TextField("Age"); ... } - * - * MyForm myForm = new MyForm(); - * ... - * fieldGroup.bindMemberFields(myForm); - * </pre> - * - * </p> - * This binds the firstName TextField to a "firstName" property in the item, - * lastName TextField to a "last" property and the age TextField to a "age" - * property. - * - * @param objectWithMemberFields - * The object that contains (Java) member fields to bind - * @throws BindException - * If there is a problem binding a field - */ - public void bindMemberFields(Object objectWithMemberFields) - throws BindException { - buildAndBindMemberFields(objectWithMemberFields, false); - } - - /** - * Binds member fields found in the given object and builds member fields - * that have not been initialized. - * <p> - * This method processes all (Java) member fields whose type extends - * {@link Field} and that can be mapped to a property id. Property id - * mapping is done based on the field name or on a @{@link PropertyId} - * annotation on the field. Fields that are not initialized (null) are built - * using the field factory. All non-null fields for which a property id can - * be determined are bound to the property id. - * </p> - * <p> - * For example: - * - * <pre> - * public class MyForm extends VerticalLayout { - * private TextField firstName = new TextField("First name"); - * @PropertyId("last") - * private TextField lastName = new TextField("Last name"); - * private TextField age; - * - * MyForm myForm = new MyForm(); - * ... - * fieldGroup.buildAndBindMemberFields(myForm); - * </pre> - * - * </p> - * <p> - * This binds the firstName TextField to a "firstName" property in the item, - * lastName TextField to a "last" property and builds an age TextField using - * the field factory and then binds it to the "age" property. - * </p> - * - * @param objectWithMemberFields - * The object that contains (Java) member fields to build and - * bind - * @throws BindException - * If there is a problem binding or building a field - */ - public void buildAndBindMemberFields(Object objectWithMemberFields) - throws BindException { - buildAndBindMemberFields(objectWithMemberFields, true); - } - - /** - * Binds member fields found in the given object and optionally builds - * member fields that have not been initialized. - * <p> - * This method processes all (Java) member fields whose type extends - * {@link Field} and that can be mapped to a property id. Property id - * mapping is done based on the field name or on a @{@link PropertyId} - * annotation on the field. Fields that are not initialized (null) are built - * using the field factory is buildFields is true. All non-null fields for - * which a property id can be determined are bound to the property id. - * </p> - * - * @param objectWithMemberFields - * The object that contains (Java) member fields to build and - * bind - * @throws BindException - * If there is a problem binding or building a field - */ - protected void buildAndBindMemberFields(Object objectWithMemberFields, - boolean buildFields) throws BindException { - Class<?> objectClass = objectWithMemberFields.getClass(); - - for (java.lang.reflect.Field memberField : objectClass - .getDeclaredFields()) { - - if (!Field.class.isAssignableFrom(memberField.getType())) { - // Process next field - continue; - } - - PropertyId propertyIdAnnotation = memberField - .getAnnotation(PropertyId.class); - - Class<? extends Field> fieldType = (Class<? extends Field>) memberField - .getType(); - - Object propertyId = null; - if (propertyIdAnnotation != null) { - // @PropertyId(propertyId) always overrides property id - propertyId = propertyIdAnnotation.value(); - } else { - propertyId = memberField.getName(); - } - - // Ensure that the property id exists - Class<?> propertyType; - - try { - propertyType = getPropertyType(propertyId); - } catch (BindException e) { - // Property id was not found, skip this field - continue; - } - - Field<?> field; - try { - // Get the field from the object - field = (Field<?>) ReflectTools.getJavaFieldValue( - objectWithMemberFields, memberField); - } catch (Exception e) { - // If we cannot determine the value, just skip the field and try - // the next one - continue; - } - - if (field == null && buildFields) { - Caption captionAnnotation = memberField - .getAnnotation(Caption.class); - String caption; - if (captionAnnotation != null) { - caption = captionAnnotation.value(); - } else { - caption = DefaultFieldFactory - .createCaptionByPropertyId(propertyId); - } - - // Create the component (Field) - field = build(caption, propertyType, fieldType); - - // Store it in the field - try { - ReflectTools.setJavaFieldValue(objectWithMemberFields, - memberField, field); - } catch (IllegalArgumentException e) { - throw new BindException("Could not assign value to field '" - + memberField.getName() + "'", e); - } catch (IllegalAccessException e) { - throw new BindException("Could not assign value to field '" - + memberField.getName() + "'", e); - } catch (InvocationTargetException e) { - throw new BindException("Could not assign value to field '" - + memberField.getName() + "'", e); - } - } - - if (field != null) { - // Bind it to the property id - bind(field, propertyId); - } - } - } - - public static class CommitException extends Exception { - - public CommitException() { - super(); - // TODO Auto-generated constructor stub - } - - public CommitException(String message, Throwable cause) { - super(message, cause); - // TODO Auto-generated constructor stub - } - - public CommitException(String message) { - super(message); - // TODO Auto-generated constructor stub - } - - public CommitException(Throwable cause) { - super(cause); - // TODO Auto-generated constructor stub - } - - } - - public static class BindException extends RuntimeException { - - public BindException(String message) { - super(message); - } - - public BindException(String message, Throwable t) { - super(message, t); - } - - } - - /** - * Builds a field and binds it to the given property id using the field - * binder. - * - * @param propertyId - * The property id to bind to. Must be present in the field - * finder. - * @throws BindException - * If there is a problem while building or binding - * @return The created and bound field - */ - public Field<?> buildAndBind(Object propertyId) throws BindException { - String caption = DefaultFieldFactory - .createCaptionByPropertyId(propertyId); - return buildAndBind(caption, propertyId); - } - - /** - * Builds a field using the given caption and binds it to the given property - * id using the field binder. - * - * @param caption - * The caption for the field - * @param propertyId - * The property id to bind to. Must be present in the field - * finder. - * @throws BindException - * If there is a problem while building or binding - * @return The created and bound field. Can be any type of {@link Field}. - */ - public Field<?> buildAndBind(String caption, Object propertyId) - throws BindException { - Class<?> type = getPropertyType(propertyId); - return buildAndBind(caption, propertyId, Field.class); - - } - - /** - * Builds a field using the given caption and binds it to the given property - * id using the field binder. Ensures the new field is of the given type. - * - * @param caption - * The caption for the field - * @param propertyId - * The property id to bind to. Must be present in the field - * finder. - * @throws BindException - * If the field could not be created - * @return The created and bound field. Can be any type of {@link Field}. - */ - - public <T extends Field> T buildAndBind(String caption, Object propertyId, - Class<T> fieldType) throws BindException { - Class<?> type = getPropertyType(propertyId); - - T field = build(caption, type, fieldType); - bind(field, propertyId); - - return field; - } - - /** - * Creates a field based on the given data type. - * <p> - * The data type is the type that we want to edit using the field. The field - * type is the type of field we want to create, can be {@link Field} if any - * Field is good. - * </p> - * - * @param caption - * The caption for the new field - * @param dataType - * The data model type that we want to edit using the field - * @param fieldType - * The type of field that we want to create - * @return A Field capable of editing the given type - * @throws BindException - * If the field could not be created - */ - protected <T extends Field> T build(String caption, Class<?> dataType, - Class<T> fieldType) throws BindException { - T field = getFieldFactory().createField(dataType, fieldType); - if (field == null) { - throw new BindException("Unable to build a field of type " - + fieldType.getName() + " for editing " - + dataType.getName()); - } - - field.setCaption(caption); - return field; - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java deleted file mode 100644 index 80c012cbdc..0000000000 --- a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java +++ /dev/null @@ -1,31 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.fieldgroup; - -import java.io.Serializable; - -import com.vaadin.ui.Field; - -/** - * Factory interface for creating new Field-instances based on the data type - * that should be edited. - * - * @author Vaadin Ltd. - * @version @version@ - * @since 7.0 - */ -public interface FieldGroupFieldFactory extends Serializable { - /** - * Creates a field based on the data type that we want to edit - * - * @param dataType - * The type that we want to edit using the field - * @param fieldType - * The type of field we want to create. If set to {@link Field} - * then any type of field is accepted - * @return A field that can be assigned to the given fieldType and that is - * capable of editing the given type of data - */ - <T extends Field> T createField(Class<?> dataType, Class<T> fieldType); -} diff --git a/src/com/vaadin/data/fieldgroup/PropertyId.java b/src/com/vaadin/data/fieldgroup/PropertyId.java deleted file mode 100644 index 268047401d..0000000000 --- a/src/com/vaadin/data/fieldgroup/PropertyId.java +++ /dev/null @@ -1,15 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.fieldgroup; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ ElementType.FIELD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface PropertyId { - String value(); -} diff --git a/src/com/vaadin/data/package.html b/src/com/vaadin/data/package.html deleted file mode 100644 index a14ea1ac88..0000000000 --- a/src/com/vaadin/data/package.html +++ /dev/null @@ -1,49 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -</head> - -<body bgcolor="white"> - -<p>Contains interfaces for the data layer, mainly for binding typed -data and data collections to components, and for validating data.</p> - -<h2>Data binding</h2> - -<p>The package contains a three-tiered structure for typed data -objects and collections of them:</p> - -<ul> - <li>A {@link com.vaadin.data.Property Property} represents a - single, typed data value. - - <li>An {@link com.vaadin.data.Item Item} embodies a set of <i>Properties</i>. - A locally unique (inside the {@link com.vaadin.data.Item Item}) - Property identifier corresponds to each Property inside the Item.</li> - <li>A {@link com.vaadin.data.Container Container} contains a set - of Items, each corresponding to a locally unique Item identifier. Note - that Container imposes a few restrictions on the data stored in it, see - {@link com.vaadin.data.Container Container} for further information.</li> -</ul> - -<p>For more information on the data model, see the <a - href="http://vaadin.com/book/-/page/datamodel.html">Data model -chapter</a> in Book of Vaadin.</p> - -<h2>Buffering</h2> - -<p>A {@link com.vaadin.data.Buffered Buffered} implementor is able -to track and buffer changes and commit or discard them later.</p> - -<h2>Validation</h2> - -<p>{@link com.vaadin.data.Validator Validator} implementations are -used to validate data, typically the value of a {@link -com.vaadin.ui.Field Field}. One or more {@link com.vaadin.data.Validator -Validators} can be added to a {@link com.vaadin.data.Validatable -Validatable} implementor and then used to validate the value of the -Validatable. </p> - -<!-- Put @see and @since tags down here. --> -</body> -</html> diff --git a/src/com/vaadin/data/util/AbstractBeanContainer.java b/src/com/vaadin/data/util/AbstractBeanContainer.java deleted file mode 100644 index 2f428d2cb6..0000000000 --- a/src/com/vaadin/data/util/AbstractBeanContainer.java +++ /dev/null @@ -1,856 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.io.Serializable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.Filterable; -import com.vaadin.data.Container.PropertySetChangeNotifier; -import com.vaadin.data.Container.SimpleFilterable; -import com.vaadin.data.Container.Sortable; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.data.Property.ValueChangeNotifier; -import com.vaadin.data.util.MethodProperty.MethodException; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * An abstract base class for in-memory containers for JavaBeans. - * - * <p> - * The properties of the container are determined automatically by introspecting - * the used JavaBean class and explicitly adding or removing properties is not - * supported. Only beans of the same type can be added to the container. - * </p> - * - * <p> - * Subclasses should implement any public methods adding items to the container, - * typically calling the protected methods {@link #addItem(Object, Object)}, - * {@link #addItemAfter(Object, Object, Object)} and - * {@link #addItemAt(int, Object, Object)}. - * </p> - * - * @param <IDTYPE> - * The type of the item identifier - * @param <BEANTYPE> - * The type of the Bean - * - * @since 6.5 - */ -public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends - AbstractInMemoryContainer<IDTYPE, String, BeanItem<BEANTYPE>> implements - Filterable, SimpleFilterable, Sortable, ValueChangeListener, - PropertySetChangeNotifier { - - /** - * Resolver that maps beans to their (item) identifiers, removing the need - * to explicitly specify item identifiers when there is no need to customize - * this. - * - * Note that beans can also be added with an explicit id even if a resolver - * has been set. - * - * @param <IDTYPE> - * @param <BEANTYPE> - * - * @since 6.5 - */ - public static interface BeanIdResolver<IDTYPE, BEANTYPE> extends - Serializable { - /** - * Return the item identifier for a bean. - * - * @param bean - * @return - */ - public IDTYPE getIdForBean(BEANTYPE bean); - } - - /** - * A item identifier resolver that returns the value of a bean property. - * - * The bean must have a getter for the property, and the getter must return - * an object of type IDTYPE. - */ - protected class PropertyBasedBeanIdResolver implements - BeanIdResolver<IDTYPE, BEANTYPE> { - - private final Object propertyId; - - public PropertyBasedBeanIdResolver(Object propertyId) { - if (propertyId == null) { - throw new IllegalArgumentException( - "Property identifier must not be null"); - } - this.propertyId = propertyId; - } - - @Override - @SuppressWarnings("unchecked") - public IDTYPE getIdForBean(BEANTYPE bean) - throws IllegalArgumentException { - VaadinPropertyDescriptor<BEANTYPE> pd = model.get(propertyId); - if (null == pd) { - throw new IllegalStateException("Property " + propertyId - + " not found"); - } - try { - Property<IDTYPE> property = (Property<IDTYPE>) pd - .createProperty(bean); - return property.getValue(); - } catch (MethodException e) { - throw new IllegalArgumentException(e); - } - } - - } - - /** - * The resolver that finds the item ID for a bean, or null not to use - * automatic resolving. - * - * Methods that add a bean without specifying an ID must not be called if no - * resolver has been set. - */ - private BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver = null; - - /** - * Maps all item ids in the container (including filtered) to their - * corresponding BeanItem. - */ - private final Map<IDTYPE, BeanItem<BEANTYPE>> itemIdToItem = new HashMap<IDTYPE, BeanItem<BEANTYPE>>(); - - /** - * The type of the beans in the container. - */ - private final Class<? super BEANTYPE> type; - - /** - * A description of the properties found in beans of type {@link #type}. - * Determines the property ids that are present in the container. - */ - private LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model; - - /** - * Constructs a {@code AbstractBeanContainer} for beans of the given type. - * - * @param type - * the type of the beans that will be added to the container. - * @throws IllegalArgumentException - * If {@code type} is null - */ - protected AbstractBeanContainer(Class<? super BEANTYPE> type) { - if (type == null) { - throw new IllegalArgumentException( - "The bean type passed to AbstractBeanContainer must not be null"); - } - this.type = type; - model = BeanItem.getPropertyDescriptors((Class<BEANTYPE>) type); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getType(java.lang.Object) - */ - @Override - public Class<?> getType(Object propertyId) { - return model.get(propertyId).getPropertyType(); - } - - /** - * Create a BeanItem for a bean using pre-parsed bean metadata (based on - * {@link #getBeanType()}). - * - * @param bean - * @return created {@link BeanItem} or null if bean is null - */ - protected BeanItem<BEANTYPE> createBeanItem(BEANTYPE bean) { - return bean == null ? null : new BeanItem<BEANTYPE>(bean, model); - } - - /** - * Returns the type of beans this Container can contain. - * - * This comes from the bean type constructor parameter, and bean metadata - * (including container properties) is based on this. - * - * @return - */ - public Class<? super BEANTYPE> getBeanType() { - return type; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - @Override - public Collection<String> getContainerPropertyIds() { - return model.keySet(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() { - int origSize = size(); - - internalRemoveAllItems(); - - // detach listeners from all Items - for (Item item : itemIdToItem.values()) { - removeAllValueChangeListeners(item); - } - itemIdToItem.clear(); - - // fire event only if the visible view changed, regardless of whether - // filtered out items were removed or not - if (origSize != 0) { - fireItemSetChange(); - } - - return true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItem(java.lang.Object) - */ - @Override - public BeanItem<BEANTYPE> getItem(Object itemId) { - // TODO return only if visible? - return getUnfilteredItem(itemId); - } - - @Override - protected BeanItem<BEANTYPE> getUnfilteredItem(Object itemId) { - return itemIdToItem.get(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItemIds() - */ - @Override - @SuppressWarnings("unchecked") - public List<IDTYPE> getItemIds() { - return (List<IDTYPE>) super.getItemIds(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, - * java.lang.Object) - */ - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - Item item = getItem(itemId); - if (item == null) { - return null; - } - return item.getItemProperty(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) { - // TODO should also remove items that are filtered out - int origSize = size(); - Item item = getItem(itemId); - int position = indexOfId(itemId); - - if (internalRemoveItem(itemId)) { - // detach listeners from Item - removeAllValueChangeListeners(item); - - // remove item - itemIdToItem.remove(itemId); - - // fire event only if the visible view changed, regardless of - // whether filtered out items were removed or not - if (size() != origSize) { - fireItemRemoved(position, itemId); - } - - return true; - } else { - return false; - } - } - - /** - * Re-filter the container when one of the monitored properties changes. - */ - @Override - public void valueChange(ValueChangeEvent event) { - // if a property that is used in a filter is changed, refresh filtering - filterAll(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.Filterable#addContainerFilter(java.lang.Object, - * java.lang.String, boolean, boolean) - */ - @Override - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - try { - addFilter(new SimpleStringFilter(propertyId, filterString, - ignoreCase, onlyMatchPrefix)); - } catch (UnsupportedFilterException e) { - // the filter instance created here is always valid for in-memory - // containers - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Filterable#removeAllContainerFilters() - */ - @Override - public void removeAllContainerFilters() { - if (!getFilters().isEmpty()) { - for (Item item : itemIdToItem.values()) { - removeAllValueChangeListeners(item); - } - removeAllFilters(); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.Filterable#removeContainerFilters(java.lang - * .Object) - */ - @Override - public void removeContainerFilters(Object propertyId) { - Collection<Filter> removedFilters = super.removeFilters(propertyId); - if (!removedFilters.isEmpty()) { - // stop listening to change events for the property - for (Item item : itemIdToItem.values()) { - removeValueChangeListener(item, propertyId); - } - } - } - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - addFilter(filter); - } - - @Override - public void removeContainerFilter(Filter filter) { - removeFilter(filter); - } - - /** - * Make this container listen to the given property provided it notifies - * when its value changes. - * - * @param item - * The {@link Item} that contains the property - * @param propertyId - * The id of the property - */ - private void addValueChangeListener(Item item, Object propertyId) { - Property<?> property = item.getItemProperty(propertyId); - if (property instanceof ValueChangeNotifier) { - // avoid multiple notifications for the same property if - // multiple filters are in use - ValueChangeNotifier notifier = (ValueChangeNotifier) property; - notifier.removeListener(this); - notifier.addListener(this); - } - } - - /** - * Remove this container as a listener for the given property. - * - * @param item - * The {@link Item} that contains the property - * @param propertyId - * The id of the property - */ - private void removeValueChangeListener(Item item, Object propertyId) { - Property<?> property = item.getItemProperty(propertyId); - if (property instanceof ValueChangeNotifier) { - ((ValueChangeNotifier) property).removeListener(this); - } - } - - /** - * Remove this contains as a listener for all the properties in the given - * {@link Item}. - * - * @param item - * The {@link Item} that contains the properties - */ - private void removeAllValueChangeListeners(Item item) { - for (Object propertyId : item.getItemPropertyIds()) { - removeValueChangeListener(item, propertyId); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() - */ - @Override - public Collection<?> getSortableContainerPropertyIds() { - return getSortablePropertyIds(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - sortContainer(propertyId, ascending); - } - - @Override - public ItemSorter getItemSorter() { - return super.getItemSorter(); - } - - @Override - public void setItemSorter(ItemSorter itemSorter) { - super.setItemSorter(itemSorter); - } - - @Override - protected void registerNewItem(int position, IDTYPE itemId, - BeanItem<BEANTYPE> item) { - itemIdToItem.put(itemId, item); - - // add listeners to be able to update filtering on property - // changes - for (Filter filter : getFilters()) { - for (String propertyId : getContainerPropertyIds()) { - if (filter.appliesToProperty(propertyId)) { - // addValueChangeListener avoids adding duplicates - addValueChangeListener(item, propertyId); - } - } - } - } - - /** - * Check that a bean can be added to the container (is of the correct type - * for the container). - * - * @param bean - * @return - */ - private boolean validateBean(BEANTYPE bean) { - return bean != null && getBeanType().isAssignableFrom(bean.getClass()); - } - - /** - * Adds the bean to the Container. - * - * Note: the behavior of this method changed in Vaadin 6.6 - now items are - * added at the very end of the unfiltered container and not after the last - * visible item if filtering is used. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - protected BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) { - if (!validateBean(bean)) { - return null; - } - return internalAddItemAtEnd(itemId, createBeanItem(bean), true); - } - - /** - * Adds the bean after the given bean. - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) - */ - protected BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId, - IDTYPE newItemId, BEANTYPE bean) { - if (!validateBean(bean)) { - return null; - } - return internalAddItemAfter(previousItemId, newItemId, - createBeanItem(bean), true); - } - - /** - * Adds a new bean at the given index. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param index - * Index at which the bean should be added. - * @param newItemId - * The item id for the bean to add to the container. - * @param bean - * The bean to add to the container. - * - * @return Returns the new BeanItem or null if the operation fails. - */ - protected BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId, - BEANTYPE bean) { - if (!validateBean(bean)) { - return null; - } - return internalAddItemAt(index, newItemId, createBeanItem(bean), true); - } - - /** - * Adds a bean to the container using the bean item id resolver to find its - * identifier. - * - * A bean id resolver must be set before calling this method. - * - * @see #addItem(Object, Object) - * - * @param bean - * the bean to add - * @return BeanItem<BEANTYPE> item added or null - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if an identifier cannot be resolved for the bean - */ - protected BeanItem<BEANTYPE> addBean(BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - if (bean == null) { - return null; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - return addItem(itemId, bean); - } - - /** - * Adds a bean to the container after a specified item identifier, using the - * bean item id resolver to find its identifier. - * - * A bean id resolver must be set before calling this method. - * - * @see #addItemAfter(Object, Object, Object) - * - * @param previousItemId - * the identifier of the bean after which this bean should be - * added, null to add to the beginning - * @param bean - * the bean to add - * @return BeanItem<BEANTYPE> item added or null - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if an identifier cannot be resolved for the bean - */ - protected BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId, - BEANTYPE bean) throws IllegalStateException, - IllegalArgumentException { - if (bean == null) { - return null; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - return addItemAfter(previousItemId, itemId, bean); - } - - /** - * Adds a bean at a specified (filtered view) position in the container - * using the bean item id resolver to find its identifier. - * - * A bean id resolver must be set before calling this method. - * - * @see #addItemAfter(Object, Object, Object) - * - * @param index - * the index (in the filtered view) at which to add the item - * @param bean - * the bean to add - * @return BeanItem<BEANTYPE> item added or null - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if an identifier cannot be resolved for the bean - */ - protected BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - if (bean == null) { - return null; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - return addItemAt(index, itemId, bean); - } - - /** - * Adds all the beans from a {@link Collection} in one operation using the - * bean item identifier resolver. More efficient than adding them one by - * one. - * - * A bean id resolver must be set before calling this method. - * - * Note: the behavior of this method changed in Vaadin 6.6 - now items are - * added at the very end of the unfiltered container and not after the last - * visible item if filtering is used. - * - * @param collection - * The collection of beans to add. Must not be null. - * @throws IllegalStateException - * if no bean identifier resolver has been set - * @throws IllegalArgumentException - * if the resolver returns a null itemId for one of the beans in - * the collection - */ - protected void addAll(Collection<? extends BEANTYPE> collection) - throws IllegalStateException, IllegalArgumentException { - boolean modified = false; - for (BEANTYPE bean : collection) { - // TODO skipping invalid beans - should not allow them in javadoc? - if (bean == null - || !getBeanType().isAssignableFrom(bean.getClass())) { - continue; - } - IDTYPE itemId = resolveBeanId(bean); - if (itemId == null) { - throw new IllegalArgumentException( - "Resolved identifier for a bean must not be null"); - } - - if (internalAddItemAtEnd(itemId, createBeanItem(bean), false) != null) { - modified = true; - } - } - - if (modified) { - // Filter the contents when all items have been added - if (isFiltered()) { - filterAll(); - } else { - fireItemSetChange(); - } - } - } - - /** - * Use the bean resolver to get the identifier for a bean. - * - * @param bean - * @return resolved bean identifier, null if could not be resolved - * @throws IllegalStateException - * if no bean resolver is set - */ - protected IDTYPE resolveBeanId(BEANTYPE bean) { - if (beanIdResolver == null) { - throw new IllegalStateException( - "Bean item identifier resolver is required."); - } - return beanIdResolver.getIdForBean(bean); - } - - /** - * Sets the resolver that finds the item id for a bean, or null not to use - * automatic resolving. - * - * Methods that add a bean without specifying an id must not be called if no - * resolver has been set. - * - * Note that methods taking an explicit id can be used whether a resolver - * has been defined or not. - * - * @param beanIdResolver - * to use or null to disable automatic id resolution - */ - protected void setBeanIdResolver( - BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) { - this.beanIdResolver = beanIdResolver; - } - - /** - * Returns the resolver that finds the item ID for a bean. - * - * @return resolver used or null if automatic item id resolving is disabled - */ - public BeanIdResolver<IDTYPE, BEANTYPE> getBeanIdResolver() { - return beanIdResolver; - } - - /** - * Create an item identifier resolver using a named bean property. - * - * @param propertyId - * property identifier, which must map to a getter in BEANTYPE - * @return created resolver - */ - protected BeanIdResolver<IDTYPE, BEANTYPE> createBeanPropertyResolver( - Object propertyId) { - return new PropertyBasedBeanIdResolver(propertyId); - } - - @Override - public void addListener(Container.PropertySetChangeListener listener) { - super.addListener(listener); - } - - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - super.removeListener(listener); - } - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Use addNestedContainerProperty(String) to add container properties to a " - + getClass().getSimpleName()); - } - - /** - * Adds a property for the container and all its items. - * - * Primarily for internal use, may change in future versions. - * - * @param propertyId - * @param propertyDescriptor - * @return true if the property was added - */ - protected final boolean addContainerProperty(String propertyId, - VaadinPropertyDescriptor<BEANTYPE> propertyDescriptor) { - if (null == propertyId || null == propertyDescriptor) { - return false; - } - - // Fails if the Property is already present - if (model.containsKey(propertyId)) { - return false; - } - - model.put(propertyId, propertyDescriptor); - for (BeanItem<BEANTYPE> item : itemIdToItem.values()) { - item.addItemProperty(propertyId, - propertyDescriptor.createProperty(item.getBean())); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - - /** - * Adds a nested container property for the container, e.g. - * "manager.address.street". - * - * All intermediate getters must exist and must return non-null values when - * the property value is accessed. - * - * @see NestedMethodProperty - * - * @param propertyId - * @return true if the property was added - */ - public boolean addNestedContainerProperty(String propertyId) { - return addContainerProperty(propertyId, new NestedPropertyDescriptor( - propertyId, type)); - } - - /** - * Adds a nested container properties for all sub-properties of a named - * property to the container. The named property itself is removed from the - * model as its subproperties are added. - * - * All intermediate getters must exist and must return non-null values when - * the property value is accessed. - * - * @see NestedMethodProperty - * @see #addNestedContainerProperty(String) - * - * @param propertyId - */ - @SuppressWarnings("unchecked") - public void addNestedContainerBean(String propertyId) { - Class<?> propertyType = getType(propertyId); - LinkedHashMap<String, VaadinPropertyDescriptor<Object>> pds = BeanItem - .getPropertyDescriptors((Class<Object>) propertyType); - for (String subPropertyId : pds.keySet()) { - String qualifiedPropertyId = propertyId + "." + subPropertyId; - NestedPropertyDescriptor<BEANTYPE> pd = new NestedPropertyDescriptor<BEANTYPE>( - qualifiedPropertyId, (Class<BEANTYPE>) type); - model.put(qualifiedPropertyId, pd); - model.remove(propertyId); - for (BeanItem<BEANTYPE> item : itemIdToItem.values()) { - item.addItemProperty(propertyId, - pd.createProperty(item.getBean())); - item.removeItemProperty(propertyId); - } - } - - // Sends a change event - fireContainerPropertySetChange(); - } - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - // Fails if the Property is not present - if (!model.containsKey(propertyId)) { - return false; - } - - // Removes the Property to Property list and types - model.remove(propertyId); - - // If remove the Property from all Items - for (final Iterator<IDTYPE> i = getAllItemIds().iterator(); i.hasNext();) { - getUnfilteredItem(i.next()).removeItemProperty(propertyId); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - -} diff --git a/src/com/vaadin/data/util/AbstractContainer.java b/src/com/vaadin/data/util/AbstractContainer.java deleted file mode 100644 index 7d96c2d757..0000000000 --- a/src/com/vaadin/data/util/AbstractContainer.java +++ /dev/null @@ -1,251 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.LinkedList; - -import com.vaadin.data.Container; - -/** - * Abstract container class that manages event listeners and sending events to - * them ({@link PropertySetChangeNotifier}, {@link ItemSetChangeNotifier}). - * - * Note that this class provides the internal implementations for both types of - * events and notifiers as protected methods, but does not implement the - * {@link PropertySetChangeNotifier} and {@link ItemSetChangeNotifier} - * interfaces directly. This way, subclasses can choose not to implement them. - * Subclasses implementing those interfaces should also override the - * corresponding {@link #addListener()} and {@link #removeListener()} methods to - * make them public. - * - * @since 6.6 - */ -public abstract class AbstractContainer implements Container { - - /** - * List of all Property set change event listeners. - */ - private Collection<Container.PropertySetChangeListener> propertySetChangeListeners = null; - - /** - * List of all container Item set change event listeners. - */ - private Collection<Container.ItemSetChangeListener> itemSetChangeListeners = null; - - /** - * An <code>event</code> object specifying the container whose Property set - * has changed. - * - * This class does not provide information about which properties were - * concerned by the change, but subclasses can provide additional - * information about the changes. - */ - protected static class BasePropertySetChangeEvent extends EventObject - implements Container.PropertySetChangeEvent, Serializable { - - protected BasePropertySetChangeEvent(Container source) { - super(source); - } - - @Override - public Container getContainer() { - return (Container) getSource(); - } - } - - /** - * An <code>event</code> object specifying the container whose Item set has - * changed. - * - * This class does not provide information about the exact changes - * performed, but subclasses can add provide additional information about - * the changes. - */ - protected static class BaseItemSetChangeEvent extends EventObject implements - Container.ItemSetChangeEvent, Serializable { - - protected BaseItemSetChangeEvent(Container source) { - super(source); - } - - @Override - public Container getContainer() { - return (Container) getSource(); - } - } - - // PropertySetChangeNotifier - - /** - * Implementation of the corresponding method in - * {@link PropertySetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see PropertySetChangeNotifier#addListener(com.vaadin.data.Container.PropertySetChangeListener) - */ - protected void addListener(Container.PropertySetChangeListener listener) { - if (getPropertySetChangeListeners() == null) { - setPropertySetChangeListeners(new LinkedList<Container.PropertySetChangeListener>()); - } - getPropertySetChangeListeners().add(listener); - } - - /** - * Implementation of the corresponding method in - * {@link PropertySetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see PropertySetChangeNotifier#removeListener(com.vaadin.data.Container. - * PropertySetChangeListener) - */ - protected void removeListener(Container.PropertySetChangeListener listener) { - if (getPropertySetChangeListeners() != null) { - getPropertySetChangeListeners().remove(listener); - } - } - - // ItemSetChangeNotifier - - /** - * Implementation of the corresponding method in - * {@link ItemSetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see ItemSetChangeNotifier#addListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - protected void addListener(Container.ItemSetChangeListener listener) { - if (getItemSetChangeListeners() == null) { - setItemSetChangeListeners(new LinkedList<Container.ItemSetChangeListener>()); - } - getItemSetChangeListeners().add(listener); - } - - /** - * Implementation of the corresponding method in - * {@link ItemSetChangeNotifier}, override with the corresponding public - * method and implement the interface to use this. - * - * @see ItemSetChangeNotifier#removeListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - protected void removeListener(Container.ItemSetChangeListener listener) { - if (getItemSetChangeListeners() != null) { - getItemSetChangeListeners().remove(listener); - } - } - - /** - * Sends a simple Property set change event to all interested listeners. - */ - protected void fireContainerPropertySetChange() { - fireContainerPropertySetChange(new BasePropertySetChangeEvent(this)); - } - - /** - * Sends a Property set change event to all interested listeners. - * - * Use {@link #fireContainerPropertySetChange()} instead of this method - * unless additional information about the exact changes is available and - * should be included in the event. - * - * @param event - * the property change event to send, optionally with additional - * information - */ - protected void fireContainerPropertySetChange( - Container.PropertySetChangeEvent event) { - if (getPropertySetChangeListeners() != null) { - final Object[] l = getPropertySetChangeListeners().toArray(); - for (int i = 0; i < l.length; i++) { - ((Container.PropertySetChangeListener) l[i]) - .containerPropertySetChange(event); - } - } - } - - /** - * Sends a simple Item set change event to all interested listeners, - * indicating that anything in the contents may have changed (items added, - * removed etc.). - */ - protected void fireItemSetChange() { - fireItemSetChange(new BaseItemSetChangeEvent(this)); - } - - /** - * Sends an Item set change event to all registered interested listeners. - * - * @param event - * the item set change event to send, optionally with additional - * information - */ - protected void fireItemSetChange(ItemSetChangeEvent event) { - if (getItemSetChangeListeners() != null) { - final Object[] l = getItemSetChangeListeners().toArray(); - for (int i = 0; i < l.length; i++) { - ((Container.ItemSetChangeListener) l[i]) - .containerItemSetChange(event); - } - } - } - - /** - * Sets the property set change listener collection. For internal use only. - * - * @param propertySetChangeListeners - */ - protected void setPropertySetChangeListeners( - Collection<Container.PropertySetChangeListener> propertySetChangeListeners) { - this.propertySetChangeListeners = propertySetChangeListeners; - } - - /** - * Returns the property set change listener collection. For internal use - * only. - */ - protected Collection<Container.PropertySetChangeListener> getPropertySetChangeListeners() { - return propertySetChangeListeners; - } - - /** - * Sets the item set change listener collection. For internal use only. - * - * @param itemSetChangeListeners - */ - protected void setItemSetChangeListeners( - Collection<Container.ItemSetChangeListener> itemSetChangeListeners) { - this.itemSetChangeListeners = itemSetChangeListeners; - } - - /** - * Returns the item set change listener collection. For internal use only. - */ - protected Collection<Container.ItemSetChangeListener> getItemSetChangeListeners() { - return itemSetChangeListeners; - } - - public Collection<?> getListeners(Class<?> eventType) { - if (Container.PropertySetChangeEvent.class.isAssignableFrom(eventType)) { - if (propertySetChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertySetChangeListeners); - } - } else if (Container.ItemSetChangeEvent.class - .isAssignableFrom(eventType)) { - if (itemSetChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(itemSetChangeListeners); - } - } - - return Collections.EMPTY_LIST; - } -} diff --git a/src/com/vaadin/data/util/AbstractInMemoryContainer.java b/src/com/vaadin/data/util/AbstractInMemoryContainer.java deleted file mode 100644 index b7832756f2..0000000000 --- a/src/com/vaadin/data/util/AbstractInMemoryContainer.java +++ /dev/null @@ -1,941 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.ItemSetChangeNotifier; -import com.vaadin.data.Item; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * Abstract {@link Container} class that handles common functionality for - * in-memory containers. Concrete in-memory container classes can either inherit - * this class, inherit {@link AbstractContainer}, or implement the - * {@link Container} interface directly. - * - * Adding and removing items (if desired) must be implemented in subclasses by - * overriding the appropriate add*Item() and remove*Item() and removeAllItems() - * methods, calling the corresponding - * {@link #internalAddItemAfter(Object, Object, Item)}, - * {@link #internalAddItemAt(int, Object, Item)}, - * {@link #internalAddItemAtEnd(Object, Item, boolean)}, - * {@link #internalRemoveItem(Object)} and {@link #internalRemoveAllItems()} - * methods. - * - * By default, adding and removing container properties is not supported, and - * subclasses need to implement {@link #getContainerPropertyIds()}. Optionally, - * subclasses can override {@link #addContainerProperty(Object, Class, Object)} - * and {@link #removeContainerProperty(Object)} to implement them. - * - * Features: - * <ul> - * <li> {@link Container.Ordered} - * <li> {@link Container.Indexed} - * <li> {@link Filterable} and {@link SimpleFilterable} (internal implementation, - * does not implement the interface directly) - * <li> {@link Sortable} (internal implementation, does not implement the - * interface directly) - * </ul> - * - * To implement {@link Sortable}, subclasses need to implement - * {@link #getSortablePropertyIds()} and call the superclass method - * {@link #sortContainer(Object[], boolean[])} in the method - * <code>sort(Object[], boolean[])</code>. - * - * To implement {@link Filterable}, subclasses need to implement the methods - * {@link Filterable#addContainerFilter(com.vaadin.data.Container.Filter)} - * (calling {@link #addFilter(Filter)}), - * {@link Filterable#removeAllContainerFilters()} (calling - * {@link #removeAllFilters()}) and - * {@link Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)} - * (calling {@link #removeFilter(com.vaadin.data.Container.Filter)}). - * - * To implement {@link SimpleFilterable}, subclasses also need to implement the - * methods - * {@link SimpleFilterable#addContainerFilter(Object, String, boolean, boolean)} - * and {@link SimpleFilterable#removeContainerFilters(Object)} calling - * {@link #addFilter(com.vaadin.data.Container.Filter)} and - * {@link #removeFilters(Object)} respectively. - * - * @param <ITEMIDTYPE> - * the class of item identifiers in the container, use Object if can - * be any class - * @param <PROPERTYIDCLASS> - * the class of property identifiers for the items in the container, - * use Object if can be any class - * @param <ITEMCLASS> - * the (base) class of the Item instances in the container, use - * {@link Item} if unknown - * - * @since 6.6 - */ -public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITEMCLASS extends Item> - extends AbstractContainer implements ItemSetChangeNotifier, - Container.Indexed { - - /** - * An ordered {@link List} of all item identifiers in the container, - * including those that have been filtered out. - * - * Must not be null. - */ - private List<ITEMIDTYPE> allItemIds; - - /** - * An ordered {@link List} of item identifiers in the container after - * filtering, excluding those that have been filtered out. - * - * This is what the external API of the {@link Container} interface and its - * subinterfaces shows (e.g. {@link #size()}, {@link #nextItemId(Object)}). - * - * If null, the full item id list is used instead. - */ - private List<ITEMIDTYPE> filteredItemIds; - - /** - * Filters that are applied to the container to limit the items visible in - * it - */ - private Set<Filter> filters = new HashSet<Filter>(); - - /** - * The item sorter which is used for sorting the container. - */ - private ItemSorter itemSorter = new DefaultItemSorter(); - - // Constructors - - /** - * Constructor for an abstract in-memory container. - */ - protected AbstractInMemoryContainer() { - setAllItemIds(new ListSet<ITEMIDTYPE>()); - } - - // Container interface methods with more specific return class - - // default implementation, can be overridden - @Override - public ITEMCLASS getItem(Object itemId) { - if (containsId(itemId)) { - return getUnfilteredItem(itemId); - } else { - return null; - } - } - - /** - * Get an item even if filtered out. - * - * For internal use only. - * - * @param itemId - * @return - */ - protected abstract ITEMCLASS getUnfilteredItem(Object itemId); - - // cannot override getContainerPropertyIds() and getItemIds(): if subclass - // uses Object as ITEMIDCLASS or PROPERTYIDCLASS, Collection<Object> cannot - // be cast to Collection<MyInterface> - - // public abstract Collection<PROPERTYIDCLASS> getContainerPropertyIds(); - // public abstract Collection<ITEMIDCLASS> getItemIds(); - - // Container interface method implementations - - @Override - public int size() { - return getVisibleItemIds().size(); - } - - @Override - public boolean containsId(Object itemId) { - // only look at visible items after filtering - if (itemId == null) { - return false; - } else { - return getVisibleItemIds().contains(itemId); - } - } - - @Override - public List<?> getItemIds() { - return Collections.unmodifiableList(getVisibleItemIds()); - } - - // Container.Ordered - - @Override - public ITEMIDTYPE nextItemId(Object itemId) { - int index = indexOfId(itemId); - if (index >= 0 && index < size() - 1) { - return getIdByIndex(index + 1); - } else { - // out of bounds - return null; - } - } - - @Override - public ITEMIDTYPE prevItemId(Object itemId) { - int index = indexOfId(itemId); - if (index > 0) { - return getIdByIndex(index - 1); - } else { - // out of bounds - return null; - } - } - - @Override - public ITEMIDTYPE firstItemId() { - if (size() > 0) { - return getIdByIndex(0); - } else { - return null; - } - } - - @Override - public ITEMIDTYPE lastItemId() { - if (size() > 0) { - return getIdByIndex(size() - 1); - } else { - return null; - } - } - - @Override - public boolean isFirstId(Object itemId) { - if (itemId == null) { - return false; - } - return itemId.equals(firstItemId()); - } - - @Override - public boolean isLastId(Object itemId) { - if (itemId == null) { - return false; - } - return itemId.equals(lastItemId()); - } - - // Container.Indexed - - @Override - public ITEMIDTYPE getIdByIndex(int index) { - return getVisibleItemIds().get(index); - } - - @Override - public int indexOfId(Object itemId) { - return getVisibleItemIds().indexOf(itemId); - } - - // methods that are unsupported by default, override to support - - @Override - public Object addItemAt(int index) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public Object addItem() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Removing items not supported. Override the removeItem() method if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Removing items not supported. Override the removeAllItems() method if required as specified in AbstractInMemoryContainer javadoc."); - } - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Adding container properties not supported. Override the addContainerProperty() method if required."); - } - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Removing container properties not supported. Override the addContainerProperty() method if required."); - } - - // ItemSetChangeNotifier - - @Override - public void addListener(Container.ItemSetChangeListener listener) { - super.addListener(listener); - } - - @Override - public void removeListener(Container.ItemSetChangeListener listener) { - super.removeListener(listener); - } - - // internal methods - - // Filtering support - - /** - * Filter the view to recreate the visible item list from the unfiltered - * items, and send a notification if the set of visible items changed in any - * way. - */ - protected void filterAll() { - if (doFilterContainer(!getFilters().isEmpty())) { - fireItemSetChange(); - } - } - - /** - * Filters the data in the container and updates internal data structures. - * This method should reset any internal data structures and then repopulate - * them so {@link #getItemIds()} and other methods only return the filtered - * items. - * - * @param hasFilters - * true if filters has been set for the container, false - * otherwise - * @return true if the item set has changed as a result of the filtering - */ - protected boolean doFilterContainer(boolean hasFilters) { - if (!hasFilters) { - boolean changed = getAllItemIds().size() != getVisibleItemIds() - .size(); - setFilteredItemIds(null); - return changed; - } - - // Reset filtered list - List<ITEMIDTYPE> originalFilteredItemIds = getFilteredItemIds(); - boolean wasUnfiltered = false; - if (originalFilteredItemIds == null) { - originalFilteredItemIds = Collections.emptyList(); - wasUnfiltered = true; - } - setFilteredItemIds(new ListSet<ITEMIDTYPE>()); - - // Filter - boolean equal = true; - Iterator<ITEMIDTYPE> origIt = originalFilteredItemIds.iterator(); - for (final Iterator<ITEMIDTYPE> i = getAllItemIds().iterator(); i - .hasNext();) { - final ITEMIDTYPE id = i.next(); - if (passesFilters(id)) { - // filtered list comes from the full list, can use == - equal = equal && origIt.hasNext() && origIt.next() == id; - getFilteredItemIds().add(id); - } - } - - return (wasUnfiltered && !getAllItemIds().isEmpty()) || !equal - || origIt.hasNext(); - } - - /** - * Checks if the given itemId passes the filters set for the container. The - * caller should make sure the itemId exists in the container. For - * non-existing itemIds the behavior is undefined. - * - * @param itemId - * An itemId that exists in the container. - * @return true if the itemId passes all filters or no filters are set, - * false otherwise. - */ - protected boolean passesFilters(Object itemId) { - ITEMCLASS item = getUnfilteredItem(itemId); - if (getFilters().isEmpty()) { - return true; - } - final Iterator<Filter> i = getFilters().iterator(); - while (i.hasNext()) { - final Filter f = i.next(); - if (!f.passesFilter(itemId, item)) { - return false; - } - } - return true; - } - - /** - * Adds a container filter and re-filter the view. - * - * The filter must implement Filter and its sub-filters (if any) must also - * be in-memory filterable. - * - * This can be used to implement - * {@link Filterable#addContainerFilter(com.vaadin.data.Container.Filter)} - * and optionally also - * {@link SimpleFilterable#addContainerFilter(Object, String, boolean, boolean)} - * (with {@link SimpleStringFilter}). - * - * Note that in some cases, incompatible filters cannot be detected when - * added and an {@link UnsupportedFilterException} may occur when performing - * filtering. - * - * @throws UnsupportedFilterException - * if the filter is detected as not supported by the container - */ - protected void addFilter(Filter filter) throws UnsupportedFilterException { - getFilters().add(filter); - filterAll(); - } - - /** - * Remove a specific container filter and re-filter the view (if necessary). - * - * This can be used to implement - * {@link Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)} - * . - */ - protected void removeFilter(Filter filter) { - for (Iterator<Filter> iterator = getFilters().iterator(); iterator - .hasNext();) { - Filter f = iterator.next(); - if (f.equals(filter)) { - iterator.remove(); - filterAll(); - return; - } - } - } - - /** - * Remove all container filters for all properties and re-filter the view. - * - * This can be used to implement - * {@link Filterable#removeAllContainerFilters()}. - */ - protected void removeAllFilters() { - if (getFilters().isEmpty()) { - return; - } - getFilters().clear(); - filterAll(); - } - - /** - * Checks if there is a filter that applies to a given property. - * - * @param propertyId - * @return true if there is an active filter for the property - */ - protected boolean isPropertyFiltered(Object propertyId) { - if (getFilters().isEmpty() || propertyId == null) { - return false; - } - final Iterator<Filter> i = getFilters().iterator(); - while (i.hasNext()) { - final Filter f = i.next(); - if (f.appliesToProperty(propertyId)) { - return true; - } - } - return false; - } - - /** - * Remove all container filters for a given property identifier and - * re-filter the view. This also removes filters applying to multiple - * properties including the one identified by propertyId. - * - * This can be used to implement - * {@link Filterable#removeContainerFilters(Object)}. - * - * @param propertyId - * @return Collection<Filter> removed filters - */ - protected Collection<Filter> removeFilters(Object propertyId) { - if (getFilters().isEmpty() || propertyId == null) { - return Collections.emptyList(); - } - List<Filter> removedFilters = new LinkedList<Filter>(); - for (Iterator<Filter> iterator = getFilters().iterator(); iterator - .hasNext();) { - Filter f = iterator.next(); - if (f.appliesToProperty(propertyId)) { - removedFilters.add(f); - iterator.remove(); - } - } - if (!removedFilters.isEmpty()) { - filterAll(); - return removedFilters; - } - return Collections.emptyList(); - } - - // sorting - - /** - * Returns the ItemSorter used for comparing items in a sort. See - * {@link #setItemSorter(ItemSorter)} for more information. - * - * @return The ItemSorter used for comparing two items in a sort. - */ - protected ItemSorter getItemSorter() { - return itemSorter; - } - - /** - * Sets the ItemSorter used for comparing items in a sort. The - * {@link ItemSorter#compare(Object, Object)} method is called with item ids - * to perform the sorting. A default ItemSorter is used if this is not - * explicitly set. - * - * @param itemSorter - * The ItemSorter used for comparing two items in a sort (not - * null). - */ - protected void setItemSorter(ItemSorter itemSorter) { - this.itemSorter = itemSorter; - } - - /** - * Sort base implementation to be used to implement {@link Sortable}. - * - * Subclasses should call this from a public - * {@link #sort(Object[], boolean[])} method when implementing Sortable. - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - protected void sortContainer(Object[] propertyId, boolean[] ascending) { - if (!(this instanceof Sortable)) { - throw new UnsupportedOperationException( - "Cannot sort a Container that does not implement Sortable"); - } - - // Set up the item sorter for the sort operation - getItemSorter().setSortProperties((Sortable) this, propertyId, - ascending); - - // Perform the actual sort - doSort(); - - // Post sort updates - if (isFiltered()) { - filterAll(); - } else { - fireItemSetChange(); - } - - } - - /** - * Perform the sorting of the data structures in the container. This is - * invoked when the <code>itemSorter</code> has been prepared for the sort - * operation. Typically this method calls - * <code>Collections.sort(aCollection, getItemSorter())</code> on all arrays - * (containing item ids) that need to be sorted. - * - */ - protected void doSort() { - Collections.sort(getAllItemIds(), getItemSorter()); - } - - /** - * Returns the sortable property identifiers for the container. Can be used - * to implement {@link Sortable#getSortableContainerPropertyIds()}. - */ - protected Collection<?> getSortablePropertyIds() { - LinkedList<Object> sortables = new LinkedList<Object>(); - for (Object propertyId : getContainerPropertyIds()) { - Class<?> propertyType = getType(propertyId); - if (Comparable.class.isAssignableFrom(propertyType) - || propertyType.isPrimitive()) { - sortables.add(propertyId); - } - } - return sortables; - } - - // removing items - - /** - * Removes all items from the internal data structures of this class. This - * can be used to implement {@link #removeAllItems()} in subclasses. - * - * No notification is sent, the caller has to fire a suitable item set - * change notification. - */ - protected void internalRemoveAllItems() { - // Removes all Items - getAllItemIds().clear(); - if (isFiltered()) { - getFilteredItemIds().clear(); - } - } - - /** - * Removes a single item from the internal data structures of this class. - * This can be used to implement {@link #removeItem(Object)} in subclasses. - * - * No notification is sent, the caller has to fire a suitable item set - * change notification. - * - * @param itemId - * the identifier of the item to remove - * @return true if an item was successfully removed, false if failed to - * remove or no such item - */ - protected boolean internalRemoveItem(Object itemId) { - if (itemId == null) { - return false; - } - - boolean result = getAllItemIds().remove(itemId); - if (result && isFiltered()) { - getFilteredItemIds().remove(itemId); - } - - return result; - } - - // adding items - - /** - * Adds the bean to all internal data structures at the given position. - * Fails if an item with itemId is already in the container. Returns a the - * item if it was added successfully, null otherwise. - * - * <p> - * Caller should initiate filtering after calling this method. - * </p> - * - * For internal use only - subclasses should use - * {@link #internalAddItemAtEnd(Object, Item, boolean)}, - * {@link #internalAddItemAt(int, Object, Item, boolean)} and - * {@link #internalAddItemAfter(Object, Object, Item, boolean)} instead. - * - * @param position - * The position at which the item should be inserted in the - * unfiltered collection of items - * @param itemId - * The item identifier for the item to insert - * @param item - * The item to insert - * - * @return ITEMCLASS if the item was added successfully, null otherwise - */ - private ITEMCLASS internalAddAt(int position, ITEMIDTYPE itemId, - ITEMCLASS item) { - if (position < 0 || position > getAllItemIds().size() || itemId == null - || item == null) { - return null; - } - // Make sure that the item has not been added previously - if (getAllItemIds().contains(itemId)) { - return null; - } - - // "filteredList" will be updated in filterAll() which should be invoked - // by the caller after calling this method. - getAllItemIds().add(position, itemId); - registerNewItem(position, itemId, item); - - return item; - } - - /** - * Add an item at the end of the container, and perform filtering if - * necessary. An event is fired if the filtered view changes. - * - * @param newItemId - * @param item - * new item to add - * @param filter - * true to perform filtering and send event after adding the - * item, false to skip these operations for batch inserts - if - * false, caller needs to make sure these operations are - * performed at the end of the batch - * @return item added or null if no item was added - */ - protected ITEMCLASS internalAddItemAtEnd(ITEMIDTYPE newItemId, - ITEMCLASS item, boolean filter) { - ITEMCLASS newItem = internalAddAt(getAllItemIds().size(), newItemId, - item); - if (newItem != null && filter) { - // TODO filter only this item, use fireItemAdded() - filterAll(); - if (!isFiltered()) { - // TODO hack: does not detect change in filterAll() in this case - fireItemAdded(indexOfId(newItemId), newItemId, item); - } - } - return newItem; - } - - /** - * Add an item after a given (visible) item, and perform filtering. An event - * is fired if the filtered view changes. - * - * The new item is added at the beginning if previousItemId is null. - * - * @param previousItemId - * item id of a visible item after which to add the new item, or - * null to add at the beginning - * @param newItemId - * @param item - * new item to add - * @param filter - * true to perform filtering and send event after adding the - * item, false to skip these operations for batch inserts - if - * false, caller needs to make sure these operations are - * performed at the end of the batch - * @return item added or null if no item was added - */ - protected ITEMCLASS internalAddItemAfter(ITEMIDTYPE previousItemId, - ITEMIDTYPE newItemId, ITEMCLASS item, boolean filter) { - // only add if the previous item is visible - ITEMCLASS newItem = null; - if (previousItemId == null) { - newItem = internalAddAt(0, newItemId, item); - } else if (containsId(previousItemId)) { - newItem = internalAddAt( - getAllItemIds().indexOf(previousItemId) + 1, newItemId, - item); - } - if (newItem != null && filter) { - // TODO filter only this item, use fireItemAdded() - filterAll(); - if (!isFiltered()) { - // TODO hack: does not detect change in filterAll() in this case - fireItemAdded(indexOfId(newItemId), newItemId, item); - } - } - return newItem; - } - - /** - * Add an item at a given (visible after filtering) item index, and perform - * filtering. An event is fired if the filtered view changes. - * - * @param index - * position where to add the item (visible/view index) - * @param newItemId - * @param item - * new item to add - * @param filter - * true to perform filtering and send event after adding the - * item, false to skip these operations for batch inserts - if - * false, caller needs to make sure these operations are - * performed at the end of the batch - * @return item added or null if no item was added - */ - protected ITEMCLASS internalAddItemAt(int index, ITEMIDTYPE newItemId, - ITEMCLASS item, boolean filter) { - if (index < 0 || index > size()) { - return null; - } else if (index == 0) { - // add before any item, visible or not - return internalAddItemAfter(null, newItemId, item, filter); - } else { - // if index==size(), adds immediately after last visible item - return internalAddItemAfter(getIdByIndex(index - 1), newItemId, - item, filter); - } - } - - /** - * Registers a new item as having been added to the container. This can - * involve storing the item or any relevant information about it in internal - * container-specific collections if necessary, as well as registering - * listeners etc. - * - * The full identifier list in {@link AbstractInMemoryContainer} has already - * been updated to reflect the new item when this method is called. - * - * @param position - * @param itemId - * @param item - */ - protected void registerNewItem(int position, ITEMIDTYPE itemId, - ITEMCLASS item) { - } - - // item set change notifications - - /** - * Notify item set change listeners that an item has been added to the - * container. - * - * Unless subclasses specify otherwise, the default notification indicates a - * full refresh. - * - * @param postion - * position of the added item in the view (if visible) - * @param itemId - * id of the added item - * @param item - * the added item - */ - protected void fireItemAdded(int position, ITEMIDTYPE itemId, ITEMCLASS item) { - fireItemSetChange(); - } - - /** - * Notify item set change listeners that an item has been removed from the - * container. - * - * Unless subclasses specify otherwise, the default notification indicates a - * full refresh. - * - * @param postion - * position of the removed item in the view prior to removal (if - * was visible) - * @param itemId - * id of the removed item, of type {@link Object} to satisfy - * {@link Container#removeItem(Object)} API - */ - protected void fireItemRemoved(int position, Object itemId) { - fireItemSetChange(); - } - - // visible and filtered item identifier lists - - /** - * Returns the internal list of visible item identifiers after filtering. - * - * For internal use only. - */ - protected List<ITEMIDTYPE> getVisibleItemIds() { - if (isFiltered()) { - return getFilteredItemIds(); - } else { - return getAllItemIds(); - } - } - - /** - * Returns true is the container has active filters. - * - * @return true if the container is currently filtered - */ - protected boolean isFiltered() { - return filteredItemIds != null; - } - - /** - * Internal helper method to set the internal list of filtered item - * identifiers. Should not be used outside this class except for - * implementing clone(), may disappear from future versions. - * - * @param filteredItemIds - */ - @Deprecated - protected void setFilteredItemIds(List<ITEMIDTYPE> filteredItemIds) { - this.filteredItemIds = filteredItemIds; - } - - /** - * Internal helper method to get the internal list of filtered item - * identifiers. Should not be used outside this class except for - * implementing clone(), may disappear from future versions - use - * {@link #getVisibleItemIds()} in other contexts. - * - * @return List<ITEMIDTYPE> - */ - protected List<ITEMIDTYPE> getFilteredItemIds() { - return filteredItemIds; - } - - /** - * Internal helper method to set the internal list of all item identifiers. - * Should not be used outside this class except for implementing clone(), - * may disappear from future versions. - * - * @param allItemIds - */ - @Deprecated - protected void setAllItemIds(List<ITEMIDTYPE> allItemIds) { - this.allItemIds = allItemIds; - } - - /** - * Internal helper method to get the internal list of all item identifiers. - * Avoid using this method outside this class, may disappear in future - * versions. - * - * @return List<ITEMIDTYPE> - */ - protected List<ITEMIDTYPE> getAllItemIds() { - return allItemIds; - } - - /** - * Set the internal collection of filters without performing filtering. - * - * This method is mostly for internal use, use - * {@link #addFilter(com.vaadin.data.Container.Filter)} and - * <code>remove*Filter*</code> (which also re-filter the container) instead - * when possible. - * - * @param filters - */ - protected void setFilters(Set<Filter> filters) { - this.filters = filters; - } - - /** - * Returns the internal collection of filters. The returned collection - * should not be modified by callers outside this class. - * - * @return Set<Filter> - */ - protected Set<Filter> getFilters() { - return filters; - } - -} diff --git a/src/com/vaadin/data/util/AbstractProperty.java b/src/com/vaadin/data/util/AbstractProperty.java deleted file mode 100644 index 373a8dfd58..0000000000 --- a/src/com/vaadin/data/util/AbstractProperty.java +++ /dev/null @@ -1,226 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; - -import com.vaadin.data.Property; - -/** - * Abstract base class for {@link Property} implementations. - * - * Handles listener management for {@link ValueChangeListener}s and - * {@link ReadOnlyStatusChangeListener}s. - * - * @since 6.6 - */ -public abstract class AbstractProperty<T> implements Property<T>, - Property.ValueChangeNotifier, Property.ReadOnlyStatusChangeNotifier { - - /** - * List of listeners who are interested in the read-only status changes of - * the Property - */ - private LinkedList<ReadOnlyStatusChangeListener> readOnlyStatusChangeListeners = null; - - /** - * List of listeners who are interested in the value changes of the Property - */ - private LinkedList<ValueChangeListener> valueChangeListeners = null; - - /** - * Is the Property read-only? - */ - private boolean readOnly; - - /** - * {@inheritDoc} - * - * Override for additional restrictions on what is considered a read-only - * property. - */ - @Override - public boolean isReadOnly() { - return readOnly; - } - - @Override - public void setReadOnly(boolean newStatus) { - boolean oldStatus = isReadOnly(); - readOnly = newStatus; - if (oldStatus != isReadOnly()) { - fireReadOnlyStatusChange(); - } - } - - /** - * Returns the value of the <code>Property</code> in human readable textual - * format. - * - * @return String representation of the value stored in the Property - * @deprecated use {@link #getValue()} instead and possibly toString on that - */ - @Deprecated - @Override - public String toString() { - throw new UnsupportedOperationException( - "Use Property.getValue() instead of " + getClass() - + ".toString()"); - } - - /* Events */ - - /** - * An <code>Event</code> object specifying the Property whose read-only - * status has been changed. - */ - protected static class ReadOnlyStatusChangeEvent extends - java.util.EventObject implements Property.ReadOnlyStatusChangeEvent { - - /** - * Constructs a new read-only status change event for this object. - * - * @param source - * source object of the event. - */ - protected ReadOnlyStatusChangeEvent(Property source) { - super(source); - } - - /** - * Gets the Property whose read-only state has changed. - * - * @return source Property of the event. - */ - @Override - public Property getProperty() { - return (Property) getSource(); - } - - } - - /** - * Registers a new read-only status change listener for this Property. - * - * @param listener - * the new Listener to be registered. - */ - @Override - public void addListener(Property.ReadOnlyStatusChangeListener listener) { - if (readOnlyStatusChangeListeners == null) { - readOnlyStatusChangeListeners = new LinkedList<ReadOnlyStatusChangeListener>(); - } - readOnlyStatusChangeListeners.add(listener); - } - - /** - * Removes a previously registered read-only status change listener. - * - * @param listener - * the listener to be removed. - */ - @Override - public void removeListener(Property.ReadOnlyStatusChangeListener listener) { - if (readOnlyStatusChangeListeners != null) { - readOnlyStatusChangeListeners.remove(listener); - } - } - - /** - * Sends a read only status change event to all registered listeners. - */ - protected void fireReadOnlyStatusChange() { - if (readOnlyStatusChangeListeners != null) { - final Object[] l = readOnlyStatusChangeListeners.toArray(); - final Property.ReadOnlyStatusChangeEvent event = new ReadOnlyStatusChangeEvent( - this); - for (int i = 0; i < l.length; i++) { - ((Property.ReadOnlyStatusChangeListener) l[i]) - .readOnlyStatusChange(event); - } - } - } - - /** - * An <code>Event</code> object specifying the Property whose value has been - * changed. - */ - private static class ValueChangeEvent extends java.util.EventObject - implements Property.ValueChangeEvent { - - /** - * Constructs a new value change event for this object. - * - * @param source - * source object of the event. - */ - protected ValueChangeEvent(Property source) { - super(source); - } - - /** - * Gets the Property whose value has changed. - * - * @return source Property of the event. - */ - @Override - public Property getProperty() { - return (Property) getSource(); - } - - } - - @Override - public void addListener(ValueChangeListener listener) { - if (valueChangeListeners == null) { - valueChangeListeners = new LinkedList<ValueChangeListener>(); - } - valueChangeListeners.add(listener); - - } - - @Override - public void removeListener(ValueChangeListener listener) { - if (valueChangeListeners != null) { - valueChangeListeners.remove(listener); - } - - } - - /** - * Sends a value change event to all registered listeners. - */ - protected void fireValueChange() { - if (valueChangeListeners != null) { - final Object[] l = valueChangeListeners.toArray(); - final Property.ValueChangeEvent event = new ValueChangeEvent(this); - for (int i = 0; i < l.length; i++) { - ((Property.ValueChangeListener) l[i]).valueChange(event); - } - } - } - - public Collection<?> getListeners(Class<?> eventType) { - if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) { - if (valueChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections.unmodifiableCollection(valueChangeListeners); - } - } else if (Property.ReadOnlyStatusChangeEvent.class - .isAssignableFrom(eventType)) { - if (readOnlyStatusChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(readOnlyStatusChangeListeners); - } - } - - return Collections.EMPTY_LIST; - } - -} diff --git a/src/com/vaadin/data/util/BeanContainer.java b/src/com/vaadin/data/util/BeanContainer.java deleted file mode 100644 index bc1ee3c39e..0000000000 --- a/src/com/vaadin/data/util/BeanContainer.java +++ /dev/null @@ -1,168 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.util.Collection; - -/** - * An in-memory container for JavaBeans. - * - * <p> - * The properties of the container are determined automatically by introspecting - * the used JavaBean class. Only beans of the same type can be added to the - * container. - * </p> - * - * <p> - * In BeanContainer (unlike {@link BeanItemContainer}), the item IDs do not have - * to be the beans themselves. The container can be used either with explicit - * item IDs or the item IDs can be generated when adding beans. - * </p> - * - * <p> - * To use explicit item IDs, use the methods {@link #addItem(Object, Object)}, - * {@link #addItemAfter(Object, Object, Object)} and - * {@link #addItemAt(int, Object, Object)}. - * </p> - * - * <p> - * If a bean id resolver is set using - * {@link #setBeanIdResolver(com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver)} - * or {@link #setBeanIdProperty(Object)}, the methods {@link #addBean(Object)}, - * {@link #addBeanAfter(Object, Object)}, {@link #addBeanAt(int, Object)} and - * {@link #addAll(java.util.Collection)} can be used to add items to the - * container. If one of these methods is called, the resolver is used to - * generate an identifier for the item (must not return null). - * </p> - * - * <p> - * Note that explicit item identifiers can also be used when a resolver has been - * set by calling the addItem*() methods - the resolver is only used when adding - * beans using the addBean*() or {@link #addAll(Collection)} methods. - * </p> - * - * <p> - * It is not possible to add additional properties to the container and nested - * bean properties are not supported. - * </p> - * - * @param <IDTYPE> - * The type of the item identifier - * @param <BEANTYPE> - * The type of the Bean - * - * @see AbstractBeanContainer - * @see BeanItemContainer - * - * @since 6.5 - */ -public class BeanContainer<IDTYPE, BEANTYPE> extends - AbstractBeanContainer<IDTYPE, BEANTYPE> { - - public BeanContainer(Class<? super BEANTYPE> type) { - super(type); - } - - /** - * Adds the bean to the Container. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - public BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) { - if (itemId != null && bean != null) { - return super.addItem(itemId, bean); - } else { - return null; - } - } - - /** - * Adds the bean after the given item id. - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) - */ - @Override - public BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId, - IDTYPE newItemId, BEANTYPE bean) { - if (newItemId != null && bean != null) { - return super.addItemAfter(previousItemId, newItemId, bean); - } else { - return null; - } - } - - /** - * Adds a new bean at the given index. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param index - * Index at which the bean should be added. - * @param newItemId - * The item id for the bean to add to the container. - * @param bean - * The bean to add to the container. - * - * @return Returns the new BeanItem or null if the operation fails. - */ - @Override - public BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId, - BEANTYPE bean) { - if (newItemId != null && bean != null) { - return super.addItemAt(index, newItemId, bean); - } else { - return null; - } - } - - // automatic item id resolution - - /** - * Sets the bean id resolver to use a property of the beans as the - * identifier. - * - * @param propertyId - * the identifier of the property to use to find item identifiers - */ - public void setBeanIdProperty(Object propertyId) { - setBeanIdResolver(createBeanPropertyResolver(propertyId)); - } - - @Override - // overridden to make public - public void setBeanIdResolver( - BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) { - super.setBeanIdResolver(beanIdResolver); - } - - @Override - // overridden to make public - public BeanItem<BEANTYPE> addBean(BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBean(bean); - } - - @Override - // overridden to make public - public BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBeanAfter(previousItemId, bean); - } - - @Override - // overridden to make public - public BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBeanAt(index, bean); - } - - @Override - // overridden to make public - public void addAll(Collection<? extends BEANTYPE> collection) - throws IllegalStateException { - super.addAll(collection); - } - -} diff --git a/src/com/vaadin/data/util/BeanItem.java b/src/com/vaadin/data/util/BeanItem.java deleted file mode 100644 index 94439471f5..0000000000 --- a/src/com/vaadin/data/util/BeanItem.java +++ /dev/null @@ -1,269 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * A wrapper class for adding the Item interface to any Java Bean. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class BeanItem<BT> extends PropertysetItem { - - /** - * The bean which this Item is based on. - */ - private final BT bean; - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all properties - * of a Java Bean to it. The properties are identified by their respective - * bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * - */ - public BeanItem(BT bean) { - this(bean, getPropertyDescriptors((Class<BT>) bean.getClass())); - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> using a pre-computed set - * of properties. The properties are identified by their respective bean - * names. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyDescriptors - * pre-computed property descriptors - */ - BeanItem(BT bean, - Map<String, VaadinPropertyDescriptor<BT>> propertyDescriptors) { - - this.bean = bean; - - for (VaadinPropertyDescriptor<BT> pd : propertyDescriptors.values()) { - addItemProperty(pd.getName(), pd.createProperty(bean)); - } - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all listed - * properties of a Java Bean to it - in specified order. The properties are - * identified by their respective bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyIds - * id of the property. - */ - public BeanItem(BT bean, Collection<?> propertyIds) { - - this.bean = bean; - - // Create bean information - LinkedHashMap<String, VaadinPropertyDescriptor<BT>> pds = getPropertyDescriptors((Class<BT>) bean - .getClass()); - - // Add all the bean properties as MethodProperties to this Item - for (Object id : propertyIds) { - VaadinPropertyDescriptor<BT> pd = pds.get(id); - if (pd != null) { - addItemProperty(pd.getName(), pd.createProperty(bean)); - } - } - - } - - /** - * <p> - * Creates a new instance of <code>BeanItem</code> and adds all listed - * properties of a Java Bean to it - in specified order. The properties are - * identified by their respective bean names. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyIds - * ids of the properties. - */ - public BeanItem(BT bean, String[] propertyIds) { - this(bean, Arrays.asList(propertyIds)); - } - - /** - * <p> - * Perform introspection on a Java Bean class to find its properties. - * </p> - * - * <p> - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone <code>is</code> and - * <code>are</code> methods are not supported. - * </p> - * - * @param beanClass - * the Java Bean class to get properties for. - * @return an ordered map from property names to property descriptors - */ - static <BT> LinkedHashMap<String, VaadinPropertyDescriptor<BT>> getPropertyDescriptors( - final Class<BT> beanClass) { - final LinkedHashMap<String, VaadinPropertyDescriptor<BT>> pdMap = new LinkedHashMap<String, VaadinPropertyDescriptor<BT>>(); - - // Try to introspect, if it fails, we just have an empty Item - try { - List<PropertyDescriptor> propertyDescriptors = getBeanPropertyDescriptor(beanClass); - - // Add all the bean properties as MethodProperties to this Item - // later entries on the list overwrite earlier ones - for (PropertyDescriptor pd : propertyDescriptors) { - final Method getMethod = pd.getReadMethod(); - if ((getMethod != null) - && getMethod.getDeclaringClass() != Object.class) { - VaadinPropertyDescriptor<BT> vaadinPropertyDescriptor = new MethodPropertyDescriptor<BT>( - pd.getName(), pd.getPropertyType(), - pd.getReadMethod(), pd.getWriteMethod()); - pdMap.put(pd.getName(), vaadinPropertyDescriptor); - } - } - } catch (final java.beans.IntrospectionException ignored) { - } - - return pdMap; - } - - /** - * Returns the property descriptors of a class or an interface. - * - * For an interface, superinterfaces are also iterated as Introspector does - * not take them into account (Oracle Java bug 4275879), but in that case, - * both the setter and the getter for a property must be in the same - * interface and should not be overridden in subinterfaces for the discovery - * to work correctly. - * - * For interfaces, the iteration is depth first and the properties of - * superinterfaces are returned before those of their subinterfaces. - * - * @param beanClass - * @return - * @throws IntrospectionException - */ - private static List<PropertyDescriptor> getBeanPropertyDescriptor( - final Class<?> beanClass) throws IntrospectionException { - // Oracle bug 4275879: Introspector does not consider superinterfaces of - // an interface - if (beanClass.isInterface()) { - List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>(); - - for (Class<?> cls : beanClass.getInterfaces()) { - propertyDescriptors.addAll(getBeanPropertyDescriptor(cls)); - } - - BeanInfo info = Introspector.getBeanInfo(beanClass); - propertyDescriptors.addAll(Arrays.asList(info - .getPropertyDescriptors())); - - return propertyDescriptors; - } else { - BeanInfo info = Introspector.getBeanInfo(beanClass); - return Arrays.asList(info.getPropertyDescriptors()); - } - } - - /** - * Expands nested bean properties by replacing a top-level property with - * some or all of its sub-properties. The expansion is not recursive. - * - * @param propertyId - * property id for the property whose sub-properties are to be - * expanded, - * @param subPropertyIds - * sub-properties to expand, all sub-properties are expanded if - * not specified - */ - public void expandProperty(String propertyId, String... subPropertyIds) { - Set<String> subPropertySet = new HashSet<String>( - Arrays.asList(subPropertyIds)); - - if (0 == subPropertyIds.length) { - // Enumerate all sub-properties - Class<?> propertyType = getItemProperty(propertyId).getType(); - Map<String, ?> pds = getPropertyDescriptors(propertyType); - subPropertySet.addAll(pds.keySet()); - } - - for (String subproperty : subPropertySet) { - String qualifiedPropertyId = propertyId + "." + subproperty; - addNestedProperty(qualifiedPropertyId); - } - - removeItemProperty(propertyId); - } - - /** - * Adds a nested property to the item. - * - * @param nestedPropertyId - * property id to add. This property must not exist in the item - * already and must of of form "field1.field2" where field2 is a - * field in the object referenced to by field1 - */ - public void addNestedProperty(String nestedPropertyId) { - addItemProperty(nestedPropertyId, new NestedMethodProperty<Object>( - getBean(), nestedPropertyId)); - } - - /** - * Gets the underlying JavaBean object. - * - * @return the bean object. - */ - public BT getBean() { - return bean; - } - -} diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java deleted file mode 100644 index dc4deaebdc..0000000000 --- a/src/com/vaadin/data/util/BeanItemContainer.java +++ /dev/null @@ -1,241 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.util.Collection; - -/** - * An in-memory container for JavaBeans. - * - * <p> - * The properties of the container are determined automatically by introspecting - * the used JavaBean class. Only beans of the same type can be added to the - * container. - * </p> - * - * <p> - * BeanItemContainer uses the beans themselves as identifiers. The - * {@link Object#hashCode()} of a bean is used when storing and looking up beans - * so it must not change during the lifetime of the bean (it should not depend - * on any part of the bean that can be modified). Typically this restricts the - * implementation of {@link Object#equals(Object)} as well in order for it to - * fulfill the contract between {@code equals()} and {@code hashCode()}. - * </p> - * - * <p> - * To add items to the container, use the methods {@link #addBean(Object)}, - * {@link #addBeanAfter(Object, Object)} and {@link #addBeanAt(int, Object)}. - * Also {@link #addItem(Object)}, {@link #addItemAfter(Object, Object)} and - * {@link #addItemAt(int, Object)} can be used as synonyms for them. - * </p> - * - * <p> - * It is not possible to add additional properties to the container and nested - * bean properties are not supported. - * </p> - * - * @param <BEANTYPE> - * The type of the Bean - * - * @since 5.4 - */ -@SuppressWarnings("serial") -public class BeanItemContainer<BEANTYPE> extends - AbstractBeanContainer<BEANTYPE, BEANTYPE> { - - /** - * Bean identity resolver that returns the bean itself as its item - * identifier. - * - * This corresponds to the old behavior of {@link BeanItemContainer}, and - * requires suitable (identity-based) equals() and hashCode() methods on the - * beans. - * - * @param <BT> - * - * @since 6.5 - */ - private static class IdentityBeanIdResolver<BT> implements - BeanIdResolver<BT, BT> { - - @Override - public BT getIdForBean(BT bean) { - return bean; - } - - } - - /** - * Constructs a {@code BeanItemContainer} for beans of the given type. - * - * @param type - * the type of the beans that will be added to the container. - * @throws IllegalArgumentException - * If {@code type} is null - */ - public BeanItemContainer(Class<? super BEANTYPE> type) - throws IllegalArgumentException { - super(type); - super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>()); - } - - /** - * Constructs a {@code BeanItemContainer} and adds the given beans to it. - * The collection must not be empty. - * {@link BeanItemContainer#BeanItemContainer(Class)} can be used for - * creating an initially empty {@code BeanItemContainer}. - * - * Note that when using this constructor, the actual class of the first item - * in the collection is used to determine the bean properties supported by - * the container instance, and only beans of that class or its subclasses - * can be added to the collection. If this is problematic or empty - * collections need to be supported, use {@link #BeanItemContainer(Class)} - * and {@link #addAll(Collection)} instead. - * - * @param collection - * a non empty {@link Collection} of beans. - * @throws IllegalArgumentException - * If the collection is null or empty. - * - * @deprecated use {@link #BeanItemContainer(Class, Collection)} instead - */ - @SuppressWarnings("unchecked") - @Deprecated - public BeanItemContainer(Collection<? extends BEANTYPE> collection) - throws IllegalArgumentException { - // must assume the class is BT - // the class information is erased by the compiler - this((Class<BEANTYPE>) getBeanClassForCollection(collection), - collection); - } - - /** - * Internal helper method to support the deprecated {@link Collection} - * container. - * - * @param <BT> - * @param collection - * @return - * @throws IllegalArgumentException - */ - @SuppressWarnings("unchecked") - @Deprecated - private static <BT> Class<? extends BT> getBeanClassForCollection( - Collection<? extends BT> collection) - throws IllegalArgumentException { - if (collection == null || collection.isEmpty()) { - throw new IllegalArgumentException( - "The collection passed to BeanItemContainer constructor must not be null or empty. Use the other BeanItemContainer constructor."); - } - return (Class<? extends BT>) collection.iterator().next().getClass(); - } - - /** - * Constructs a {@code BeanItemContainer} and adds the given beans to it. - * - * @param type - * the type of the beans that will be added to the container. - * @param collection - * a {@link Collection} of beans (can be empty or null). - * @throws IllegalArgumentException - * If {@code type} is null - */ - public BeanItemContainer(Class<? super BEANTYPE> type, - Collection<? extends BEANTYPE> collection) - throws IllegalArgumentException { - super(type); - super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>()); - - if (collection != null) { - addAll(collection); - } - } - - /** - * Adds all the beans from a {@link Collection} in one go. More efficient - * than adding them one by one. - * - * @param collection - * The collection of beans to add. Must not be null. - */ - @Override - public void addAll(Collection<? extends BEANTYPE> collection) { - super.addAll(collection); - } - - /** - * Adds the bean after the given bean. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param previousItemId - * the bean (of type BT) after which to add newItemId - * @param newItemId - * the bean (of type BT) to add (not null) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object) - */ - @Override - @SuppressWarnings("unchecked") - public BeanItem<BEANTYPE> addItemAfter(Object previousItemId, - Object newItemId) throws IllegalArgumentException { - return super.addBeanAfter((BEANTYPE) previousItemId, - (BEANTYPE) newItemId); - } - - /** - * Adds a new bean at the given index. - * - * The bean is used both as the item contents and as the item identifier. - * - * @param index - * Index at which the bean should be added. - * @param newItemId - * The bean to add to the container. - * @return Returns the new BeanItem or null if the operation fails. - */ - @Override - @SuppressWarnings("unchecked") - public BeanItem<BEANTYPE> addItemAt(int index, Object newItemId) - throws IllegalArgumentException { - return super.addBeanAt(index, (BEANTYPE) newItemId); - } - - /** - * Adds the bean to the Container. - * - * The bean is used both as the item contents and as the item identifier. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - @SuppressWarnings("unchecked") - public BeanItem<BEANTYPE> addItem(Object itemId) { - return super.addBean((BEANTYPE) itemId); - } - - /** - * Adds the bean to the Container. - * - * The bean is used both as the item contents and as the item identifier. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - public BeanItem<BEANTYPE> addBean(BEANTYPE bean) { - return addItem(bean); - } - - /** - * Unsupported in BeanItemContainer. - */ - @Override - protected void setBeanIdResolver( - AbstractBeanContainer.BeanIdResolver<BEANTYPE, BEANTYPE> beanIdResolver) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "BeanItemContainer always uses an IdentityBeanIdResolver"); - } - -} diff --git a/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java deleted file mode 100644 index 717ce834cf..0000000000 --- a/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java +++ /dev/null @@ -1,792 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * <p> - * A wrapper class for adding external hierarchy to containers not implementing - * the {@link com.vaadin.data.Container.Hierarchical} interface. - * </p> - * - * <p> - * If the wrapped container is changed directly (that is, not through the - * wrapper), and does not implement Container.ItemSetChangeNotifier and/or - * Container.PropertySetChangeNotifier the hierarchy information must be updated - * with the {@link #updateHierarchicalWrapper()} method. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class ContainerHierarchicalWrapper implements Container.Hierarchical, - Container.ItemSetChangeNotifier, Container.PropertySetChangeNotifier { - - /** The wrapped container */ - private final Container container; - - /** Set of IDs of those contained Items that can't have children. */ - private HashSet<Object> noChildrenAllowed = null; - - /** Mapping from Item ID to parent Item ID */ - private Hashtable<Object, Object> parent = null; - - /** Mapping from Item ID to a list of child IDs */ - private Hashtable<Object, LinkedList<Object>> children = null; - - /** List that contains all root elements of the container. */ - private LinkedHashSet<Object> roots = null; - - /** Is the wrapped container hierarchical by itself ? */ - private boolean hierarchical; - - /** - * A comparator that sorts the listed items before other items. Otherwise, - * the order is undefined. - */ - private static class ListedItemsFirstComparator implements - Comparator<Object>, Serializable { - private final Collection<?> itemIds; - - private ListedItemsFirstComparator(Collection<?> itemIds) { - this.itemIds = itemIds; - } - - @Override - public int compare(Object o1, Object o2) { - if (o1.equals(o2)) { - return 0; - } - for (Object id : itemIds) { - if (id == o1) { - return -1; - } else if (id == o2) { - return 1; - } - } - return 0; - } - }; - - /** - * Constructs a new hierarchical wrapper for an existing Container. Works - * even if the to-be-wrapped container already implements the - * <code>Container.Hierarchical</code> interface. - * - * @param toBeWrapped - * the container that needs to be accessed hierarchically - * @see #updateHierarchicalWrapper() - */ - public ContainerHierarchicalWrapper(Container toBeWrapped) { - - container = toBeWrapped; - hierarchical = container instanceof Container.Hierarchical; - - // Check arguments - if (container == null) { - throw new NullPointerException("Null can not be wrapped"); - } - - // Create initial order if needed - if (!hierarchical) { - noChildrenAllowed = new HashSet<Object>(); - parent = new Hashtable<Object, Object>(); - children = new Hashtable<Object, LinkedList<Object>>(); - roots = new LinkedHashSet<Object>(container.getItemIds()); - } - - updateHierarchicalWrapper(); - - } - - /** - * Updates the wrapper's internal hierarchy data to include all Items in the - * underlying container. If the contents of the wrapped container change - * without the wrapper's knowledge, this method needs to be called to update - * the hierarchy information of the Items. - */ - public void updateHierarchicalWrapper() { - - if (!hierarchical) { - - // Recreate hierarchy and data structures if missing - if (noChildrenAllowed == null || parent == null || children == null - || roots == null) { - noChildrenAllowed = new HashSet<Object>(); - parent = new Hashtable<Object, Object>(); - children = new Hashtable<Object, LinkedList<Object>>(); - roots = new LinkedHashSet<Object>(container.getItemIds()); - } - - // Check that the hierarchy is up-to-date - else { - - // ensure order of root and child lists is same as in wrapped - // container - Collection<?> itemIds = container.getItemIds(); - Comparator<Object> basedOnOrderFromWrappedContainer = new ListedItemsFirstComparator( - itemIds); - - // Calculate the set of all items in the hierarchy - final HashSet<Object> s = new HashSet<Object>(); - s.addAll(parent.keySet()); - s.addAll(children.keySet()); - s.addAll(roots); - - // Remove unnecessary items - for (final Iterator<Object> i = s.iterator(); i.hasNext();) { - final Object id = i.next(); - if (!container.containsId(id)) { - removeFromHierarchyWrapper(id); - } - } - - // Add all the missing items - final Collection<?> ids = container.getItemIds(); - for (final Iterator<?> i = ids.iterator(); i.hasNext();) { - final Object id = i.next(); - if (!s.contains(id)) { - addToHierarchyWrapper(id); - s.add(id); - } - } - - Object[] array = roots.toArray(); - Arrays.sort(array, basedOnOrderFromWrappedContainer); - roots = new LinkedHashSet<Object>(); - for (int i = 0; i < array.length; i++) { - roots.add(array[i]); - } - for (Object object : children.keySet()) { - LinkedList<Object> object2 = children.get(object); - Collections.sort(object2, basedOnOrderFromWrappedContainer); - } - - } - } - } - - /** - * Removes the specified Item from the wrapper's internal hierarchy - * structure. - * <p> - * Note : The Item is not removed from the underlying Container. - * </p> - * - * @param itemId - * the ID of the item to remove from the hierarchy. - */ - private void removeFromHierarchyWrapper(Object itemId) { - - LinkedList<Object> oprhanedChildren = children.remove(itemId); - if (oprhanedChildren != null) { - for (Object object : oprhanedChildren) { - // make orphaned children root nodes - setParent(object, null); - } - } - - roots.remove(itemId); - final Object p = parent.get(itemId); - if (p != null) { - final LinkedList<Object> c = children.get(p); - if (c != null) { - c.remove(itemId); - } - } - parent.remove(itemId); - noChildrenAllowed.remove(itemId); - } - - /** - * Adds the specified Item specified to the internal hierarchy structure. - * The new item is added as a root Item. The underlying container is not - * modified. - * - * @param itemId - * the ID of the item to add to the hierarchy. - */ - private void addToHierarchyWrapper(Object itemId) { - roots.add(itemId); - - } - - /* - * Can the specified Item have any children? Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container) - .areChildrenAllowed(itemId); - } - - if (noChildrenAllowed.contains(itemId)) { - return false; - } - - return containsId(itemId); - } - - /* - * Gets the IDs of the children of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getChildren(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).getChildren(itemId); - } - - final Collection<?> c = children.get(itemId); - if (c == null) { - return null; - } - return Collections.unmodifiableCollection(c); - } - - /* - * Gets the ID of the parent of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object getParent(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).getParent(itemId); - } - - return parent.get(itemId); - } - - /* - * Is the Item corresponding to the given ID a leaf node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean hasChildren(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).hasChildren(itemId); - } - - LinkedList<Object> list = children.get(itemId); - return (list != null && !list.isEmpty()); - } - - /* - * Is the Item corresponding to the given ID a root node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isRoot(Object itemId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).isRoot(itemId); - } - - if (parent.containsKey(itemId)) { - return false; - } - - return containsId(itemId); - } - - /* - * Gets the IDs of the root elements in the container. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> rootItemIds() { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).rootItemIds(); - } - - return Collections.unmodifiableCollection(roots); - } - - /** - * <p> - * Sets the given Item's capability to have children. If the Item identified - * with the itemId already has children and the areChildrenAllowed is false - * this method fails and <code>false</code> is returned; the children must - * be first explicitly removed with - * {@link #setParent(Object itemId, Object newParentId)} or - * {@link com.vaadin.data.Container#removeItem(Object itemId)}. - * </p> - * - * @param itemId - * the ID of the Item in the container whose child capability is - * to be set. - * @param childrenAllowed - * the boolean value specifying if the Item can have children or - * not. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setChildrenAllowed(Object itemId, boolean childrenAllowed) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).setChildrenAllowed( - itemId, childrenAllowed); - } - - // Check that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Update status - if (childrenAllowed) { - noChildrenAllowed.remove(itemId); - } else { - noChildrenAllowed.add(itemId); - } - - return true; - } - - /** - * <p> - * Sets the parent of an Item. The new parent item must exist and be able to - * have children. (<code>canHaveChildren(newParentId) == true</code>). It is - * also possible to detach a node from the hierarchy (and thus make it root) - * by setting the parent <code>null</code>. - * </p> - * - * @param itemId - * the ID of the item to be set as the child of the Item - * identified with newParentId. - * @param newParentId - * the ID of the Item that's to be the new parent of the Item - * identified with itemId. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setParent(Object itemId, Object newParentId) { - - // If the wrapped container implements the method directly, use it - if (hierarchical) { - return ((Container.Hierarchical) container).setParent(itemId, - newParentId); - } - - // Check that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Get the old parent - final Object oldParentId = parent.get(itemId); - - // Check if no change is necessary - if ((newParentId == null && oldParentId == null) - || (newParentId != null && newParentId.equals(oldParentId))) { - return true; - } - - // Making root - if (newParentId == null) { - - // Remove from old parents children list - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(itemId); - } - } - - // Add to be a root - roots.add(itemId); - - // Update parent - parent.remove(itemId); - - return true; - } - - // Check that the new parent exists in container and can have - // children - if (!containsId(newParentId) || noChildrenAllowed.contains(newParentId)) { - return false; - } - - // Check that setting parent doesn't result to a loop - Object o = newParentId; - while (o != null && !o.equals(itemId)) { - o = parent.get(o); - } - if (o != null) { - return false; - } - - // Update parent - parent.put(itemId, newParentId); - LinkedList<Object> pcl = children.get(newParentId); - if (pcl == null) { - pcl = new LinkedList<Object>(); - children.put(newParentId, pcl); - } - pcl.add(itemId); - - // Remove from old parent or root - if (oldParentId == null) { - roots.remove(itemId); - } else { - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(oldParentId); - } - } - } - - return true; - } - - /** - * Creates a new Item into the Container, assigns it an automatic ID, and - * adds it to the hierarchy. - * - * @return the autogenerated ID of the new Item or <code>null</code> if the - * operation failed - * @throws UnsupportedOperationException - * if the addItem is not supported. - */ - @Override - public Object addItem() throws UnsupportedOperationException { - - final Object id = container.addItem(); - if (!hierarchical && id != null) { - addToHierarchyWrapper(id); - } - return id; - } - - /** - * Adds a new Item by its ID to the underlying container and to the - * hierarchy. - * - * @param itemId - * the ID of the Item to be created. - * @return the added Item or <code>null</code> if the operation failed. - * @throws UnsupportedOperationException - * if the addItem is not supported. - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - - // Null ids are not accepted - if (itemId == null) { - throw new NullPointerException("Container item id can not be null"); - } - - final Item item = container.addItem(itemId); - if (!hierarchical && item != null) { - addToHierarchyWrapper(itemId); - } - return item; - } - - /** - * Removes all items from the underlying container and from the hierarcy. - * - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeAllItems is not supported. - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - - final boolean success = container.removeAllItems(); - - if (!hierarchical && success) { - roots.clear(); - parent.clear(); - children.clear(); - noChildrenAllowed.clear(); - } - return success; - } - - /** - * Removes an Item specified by the itemId from the underlying container and - * from the hierarchy. - * - * @param itemId - * the ID of the Item to be removed. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeItem is not supported. - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - - final boolean success = container.removeItem(itemId); - - if (!hierarchical && success) { - removeFromHierarchyWrapper(itemId); - } - - return success; - } - - /** - * Removes the Item identified by given itemId and all its children. - * - * @see #removeItem(Object) - * @param itemId - * the identifier of the Item to be removed - * @return true if the operation succeeded - */ - public boolean removeItemRecursively(Object itemId) { - return HierarchicalContainer.removeItemRecursively(this, itemId); - } - - /** - * Adds a new Property to all Items in the Container. - * - * @param propertyId - * the ID of the new Property. - * @param type - * the Data type of the new Property. - * @param defaultValue - * the value all created Properties are initialized to. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the addContainerProperty is not supported. - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - - return container.addContainerProperty(propertyId, type, defaultValue); - } - - /** - * Removes the specified Property from the underlying container and from the - * hierarchy. - * <p> - * Note : The Property will be removed from all Items in the Container. - * </p> - * - * @param propertyId - * the ID of the Property to remove. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeContainerProperty is not supported. - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - return container.removeContainerProperty(propertyId); - } - - /* - * Does the container contain the specified Item? Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean containsId(Object itemId) { - return container.containsId(itemId); - } - - /* - * Gets the specified Item from the container. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Item getItem(Object itemId) { - return container.getItem(itemId); - } - - /* - * Gets the ID's of all Items stored in the Container Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getItemIds() { - return container.getItemIds(); - } - - /* - * Gets the Property identified by the given itemId and propertyId from the - * Container Don't add a JavaDoc comment here, we use the default - * documentation from implemented interface. - */ - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - return container.getContainerProperty(itemId, propertyId); - } - - /* - * Gets the ID's of all Properties stored in the Container Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getContainerPropertyIds() { - return container.getContainerPropertyIds(); - } - - /* - * Gets the data type of all Properties identified by the given Property ID. - * Don't add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Class<?> getType(Object propertyId) { - return container.getType(propertyId); - } - - /* - * Gets the number of Items in the Container. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public int size() { - return container.size(); - } - - /* - * Registers a new Item set change listener for this Container. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void addListener(Container.ItemSetChangeListener listener) { - if (container instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) container) - .addListener(new PiggybackListener(listener)); - } - } - - /* - * Removes a Item set change listener from the object. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removeListener(Container.ItemSetChangeListener listener) { - if (container instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) container) - .removeListener(new PiggybackListener(listener)); - } - } - - /* - * Registers a new Property set change listener for this Container. Don't - * add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public void addListener(Container.PropertySetChangeListener listener) { - if (container instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) container) - .addListener(new PiggybackListener(listener)); - } - } - - /* - * Removes a Property set change listener from the object. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - if (container instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) container) - .removeListener(new PiggybackListener(listener)); - } - } - - /** - * This listener 'piggybacks' on the real listener in order to update the - * wrapper when needed. It proxies equals() and hashCode() to the real - * listener so that the correct listener gets removed. - * - */ - private class PiggybackListener implements - Container.PropertySetChangeListener, - Container.ItemSetChangeListener { - - Object listener; - - public PiggybackListener(Object realListener) { - listener = realListener; - } - - @Override - public void containerItemSetChange(ItemSetChangeEvent event) { - updateHierarchicalWrapper(); - ((Container.ItemSetChangeListener) listener) - .containerItemSetChange(event); - - } - - @Override - public void containerPropertySetChange(PropertySetChangeEvent event) { - updateHierarchicalWrapper(); - ((Container.PropertySetChangeListener) listener) - .containerPropertySetChange(event); - - } - - @Override - public boolean equals(Object obj) { - return obj == listener || (obj != null && obj.equals(listener)); - } - - @Override - public int hashCode() { - return listener.hashCode(); - } - - } -} diff --git a/src/com/vaadin/data/util/ContainerOrderedWrapper.java b/src/com/vaadin/data/util/ContainerOrderedWrapper.java deleted file mode 100644 index d3d6f88d3e..0000000000 --- a/src/com/vaadin/data/util/ContainerOrderedWrapper.java +++ /dev/null @@ -1,644 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.util.Collection; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * <p> - * A wrapper class for adding external ordering to containers not implementing - * the {@link com.vaadin.data.Container.Ordered} interface. - * </p> - * - * <p> - * If the wrapped container is changed directly (that is, not through the - * wrapper), and does not implement Container.ItemSetChangeNotifier and/or - * Container.PropertySetChangeNotifier the hierarchy information must be updated - * with the {@link #updateOrderWrapper()} method. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class ContainerOrderedWrapper implements Container.Ordered, - Container.ItemSetChangeNotifier, Container.PropertySetChangeNotifier { - - /** - * The wrapped container - */ - private final Container container; - - /** - * Ordering information, ie. the mapping from Item ID to the next item ID - */ - private Hashtable<Object, Object> next; - - /** - * Reverse ordering information for convenience and performance reasons. - */ - private Hashtable<Object, Object> prev; - - /** - * ID of the first Item in the container. - */ - private Object first; - - /** - * ID of the last Item in the container. - */ - private Object last; - - /** - * Is the wrapped container ordered by itself, ie. does it implement the - * Container.Ordered interface by itself? If it does, this class will use - * the methods of the underlying container directly. - */ - private boolean ordered = false; - - /** - * The last known size of the wrapped container. Used to check whether items - * have been added or removed to the wrapped container, when the wrapped - * container does not send ItemSetChangeEvents. - */ - private int lastKnownSize = -1; - - /** - * Constructs a new ordered wrapper for an existing Container. Works even if - * the to-be-wrapped container already implements the Container.Ordered - * interface. - * - * @param toBeWrapped - * the container whose contents need to be ordered. - */ - public ContainerOrderedWrapper(Container toBeWrapped) { - - container = toBeWrapped; - ordered = container instanceof Container.Ordered; - - // Checks arguments - if (container == null) { - throw new NullPointerException("Null can not be wrapped"); - } - - // Creates initial order if needed - updateOrderWrapper(); - } - - /** - * Removes the specified Item from the wrapper's internal hierarchy - * structure. - * <p> - * Note : The Item is not removed from the underlying Container. - * </p> - * - * @param id - * the ID of the Item to be removed from the ordering. - */ - private void removeFromOrderWrapper(Object id) { - if (id != null) { - final Object pid = prev.get(id); - final Object nid = next.get(id); - if (first.equals(id)) { - first = nid; - } - if (last.equals(id)) { - first = pid; - } - if (nid != null) { - prev.put(nid, pid); - } - if (pid != null) { - next.put(pid, nid); - } - next.remove(id); - prev.remove(id); - } - } - - /** - * Registers the specified Item to the last position in the wrapper's - * internal ordering. The underlying container is not modified. - * - * @param id - * the ID of the Item to be added to the ordering. - */ - private void addToOrderWrapper(Object id) { - - // Adds the if to tail - if (last != null) { - next.put(last, id); - prev.put(id, last); - last = id; - } else { - first = last = id; - } - } - - /** - * Registers the specified Item after the specified itemId in the wrapper's - * internal ordering. The underlying container is not modified. Given item - * id must be in the container, or must be null. - * - * @param id - * the ID of the Item to be added to the ordering. - * @param previousItemId - * the Id of the previous item. - */ - private void addToOrderWrapper(Object id, Object previousItemId) { - - if (last == previousItemId || last == null) { - addToOrderWrapper(id); - } else { - if (previousItemId == null) { - next.put(id, first); - prev.put(first, id); - first = id; - } else { - prev.put(id, previousItemId); - next.put(id, next.get(previousItemId)); - prev.put(next.get(previousItemId), id); - next.put(previousItemId, id); - } - } - } - - /** - * Updates the wrapper's internal ordering information to include all Items - * in the underlying container. - * <p> - * Note : If the contents of the wrapped container change without the - * wrapper's knowledge, this method needs to be called to update the - * ordering information of the Items. - * </p> - */ - public void updateOrderWrapper() { - - if (!ordered) { - - final Collection<?> ids = container.getItemIds(); - - // Recreates ordering if some parts of it are missing - if (next == null || first == null || last == null || prev != null) { - first = null; - last = null; - next = new Hashtable<Object, Object>(); - prev = new Hashtable<Object, Object>(); - } - - // Filter out all the missing items - final LinkedList<?> l = new LinkedList<Object>(next.keySet()); - for (final Iterator<?> i = l.iterator(); i.hasNext();) { - final Object id = i.next(); - if (!container.containsId(id)) { - removeFromOrderWrapper(id); - } - } - - // Adds missing items - for (final Iterator<?> i = ids.iterator(); i.hasNext();) { - final Object id = i.next(); - if (!next.containsKey(id)) { - addToOrderWrapper(id); - } - } - } - } - - /* - * Gets the first item stored in the ordered container Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object firstItemId() { - if (ordered) { - return ((Container.Ordered) container).firstItemId(); - } - return first; - } - - /* - * Tests if the given item is the first item in the container Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isFirstId(Object itemId) { - if (ordered) { - return ((Container.Ordered) container).isFirstId(itemId); - } - return first != null && first.equals(itemId); - } - - /* - * Tests if the given item is the last item in the container Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isLastId(Object itemId) { - if (ordered) { - return ((Container.Ordered) container).isLastId(itemId); - } - return last != null && last.equals(itemId); - } - - /* - * Gets the last item stored in the ordered container Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object lastItemId() { - if (ordered) { - return ((Container.Ordered) container).lastItemId(); - } - return last; - } - - /* - * Gets the item that is next from the specified item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object nextItemId(Object itemId) { - if (ordered) { - return ((Container.Ordered) container).nextItemId(itemId); - } - if (itemId == null) { - return null; - } - return next.get(itemId); - } - - /* - * Gets the item that is previous from the specified item. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object prevItemId(Object itemId) { - if (ordered) { - return ((Container.Ordered) container).prevItemId(itemId); - } - if (itemId == null) { - return null; - } - return prev.get(itemId); - } - - /** - * Registers a new Property to all Items in the Container. - * - * @param propertyId - * the ID of the new Property. - * @param type - * the Data type of the new Property. - * @param defaultValue - * the value all created Properties are initialized to. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - - return container.addContainerProperty(propertyId, type, defaultValue); - } - - /** - * Creates a new Item into the Container, assigns it an automatic ID, and - * adds it to the ordering. - * - * @return the autogenerated ID of the new Item or <code>null</code> if the - * operation failed - * @throws UnsupportedOperationException - * if the addItem is not supported. - */ - @Override - public Object addItem() throws UnsupportedOperationException { - - final Object id = container.addItem(); - if (!ordered && id != null) { - addToOrderWrapper(id); - } - return id; - } - - /** - * Registers a new Item by its ID to the underlying container and to the - * ordering. - * - * @param itemId - * the ID of the Item to be created. - * @return the added Item or <code>null</code> if the operation failed - * @throws UnsupportedOperationException - * if the addItem is not supported. - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - final Item item = container.addItem(itemId); - if (!ordered && item != null) { - addToOrderWrapper(itemId); - } - return item; - } - - /** - * Removes all items from the underlying container and from the ordering. - * - * @return <code>true</code> if the operation succeeded, otherwise - * <code>false</code> - * @throws UnsupportedOperationException - * if the removeAllItems is not supported. - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - final boolean success = container.removeAllItems(); - if (!ordered && success) { - first = last = null; - next.clear(); - prev.clear(); - } - return success; - } - - /** - * Removes an Item specified by the itemId from the underlying container and - * from the ordering. - * - * @param itemId - * the ID of the Item to be removed. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeItem is not supported. - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - - final boolean success = container.removeItem(itemId); - if (!ordered && success) { - removeFromOrderWrapper(itemId); - } - return success; - } - - /** - * Removes the specified Property from the underlying container and from the - * ordering. - * <p> - * Note : The Property will be removed from all the Items in the Container. - * </p> - * - * @param propertyId - * the ID of the Property to remove. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - * @throws UnsupportedOperationException - * if the removeContainerProperty is not supported. - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - return container.removeContainerProperty(propertyId); - } - - /* - * Does the container contain the specified Item? Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean containsId(Object itemId) { - return container.containsId(itemId); - } - - /* - * Gets the specified Item from the container. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Item getItem(Object itemId) { - return container.getItem(itemId); - } - - /* - * Gets the ID's of all Items stored in the Container Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getItemIds() { - return container.getItemIds(); - } - - /* - * Gets the Property identified by the given itemId and propertyId from the - * Container Don't add a JavaDoc comment here, we use the default - * documentation from implemented interface. - */ - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - return container.getContainerProperty(itemId, propertyId); - } - - /* - * Gets the ID's of all Properties stored in the Container Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getContainerPropertyIds() { - return container.getContainerPropertyIds(); - } - - /* - * Gets the data type of all Properties identified by the given Property ID. - * Don't add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Class<?> getType(Object propertyId) { - return container.getType(propertyId); - } - - /* - * Gets the number of Items in the Container. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public int size() { - int newSize = container.size(); - if (lastKnownSize != -1 && newSize != lastKnownSize - && !(container instanceof Container.ItemSetChangeNotifier)) { - // Update the internal cache when the size of the container changes - // and the container is incapable of sending ItemSetChangeEvents - updateOrderWrapper(); - } - lastKnownSize = newSize; - return newSize; - } - - /* - * Registers a new Item set change listener for this Container. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void addListener(Container.ItemSetChangeListener listener) { - if (container instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) container) - .addListener(new PiggybackListener(listener)); - } - } - - /* - * Removes a Item set change listener from the object. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removeListener(Container.ItemSetChangeListener listener) { - if (container instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) container) - .removeListener(new PiggybackListener(listener)); - } - } - - /* - * Registers a new Property set change listener for this Container. Don't - * add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public void addListener(Container.PropertySetChangeListener listener) { - if (container instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) container) - .addListener(new PiggybackListener(listener)); - } - } - - /* - * Removes a Property set change listener from the object. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - if (container instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) container) - .removeListener(new PiggybackListener(listener)); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, - * java.lang.Object) - */ - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - - // If the previous item is not in the container, fail - if (previousItemId != null && !containsId(previousItemId)) { - return null; - } - - // Adds the item to container - final Item item = container.addItem(newItemId); - - // Puts the new item to its correct place - if (!ordered && item != null) { - addToOrderWrapper(newItemId, previousItemId); - } - - return item; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) - */ - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - - // If the previous item is not in the container, fail - if (previousItemId != null && !containsId(previousItemId)) { - return null; - } - - // Adds the item to container - final Object id = container.addItem(); - - // Puts the new item to its correct place - if (!ordered && id != null) { - addToOrderWrapper(id, previousItemId); - } - - return id; - } - - /** - * This listener 'piggybacks' on the real listener in order to update the - * wrapper when needed. It proxies equals() and hashCode() to the real - * listener so that the correct listener gets removed. - * - */ - private class PiggybackListener implements - Container.PropertySetChangeListener, - Container.ItemSetChangeListener { - - Object listener; - - public PiggybackListener(Object realListener) { - listener = realListener; - } - - @Override - public void containerItemSetChange(ItemSetChangeEvent event) { - updateOrderWrapper(); - ((Container.ItemSetChangeListener) listener) - .containerItemSetChange(event); - - } - - @Override - public void containerPropertySetChange(PropertySetChangeEvent event) { - updateOrderWrapper(); - ((Container.PropertySetChangeListener) listener) - .containerPropertySetChange(event); - - } - - @Override - public boolean equals(Object obj) { - return obj == listener || (obj != null && obj.equals(listener)); - } - - @Override - public int hashCode() { - return listener.hashCode(); - } - - } - -} diff --git a/src/com/vaadin/data/util/DefaultItemSorter.java b/src/com/vaadin/data/util/DefaultItemSorter.java deleted file mode 100644 index 81b15ebd4f..0000000000 --- a/src/com/vaadin/data/util/DefaultItemSorter.java +++ /dev/null @@ -1,210 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.Sortable; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * Provides a default implementation of an ItemSorter. The - * <code>DefaultItemSorter</code> adheres to the - * {@link Sortable#sort(Object[], boolean[])} rules and sorts the container - * according to the properties given using - * {@link #setSortProperties(Sortable, Object[], boolean[])}. - * <p> - * A Comparator is used for comparing the individual <code>Property</code> - * values. The comparator can be set using the constructor. If no comparator is - * provided a default comparator is used. - * - */ -public class DefaultItemSorter implements ItemSorter { - - private java.lang.Object[] sortPropertyIds; - private boolean[] sortDirections; - private Container container; - private Comparator<Object> propertyValueComparator; - - /** - * Constructs a DefaultItemSorter using the default <code>Comparator</code> - * for comparing <code>Property</code>values. - * - */ - public DefaultItemSorter() { - this(new DefaultPropertyValueComparator()); - } - - /** - * Constructs a DefaultItemSorter which uses the <code>Comparator</code> - * indicated by the <code>propertyValueComparator</code> parameter for - * comparing <code>Property</code>values. - * - * @param propertyValueComparator - * The comparator to use when comparing individual - * <code>Property</code> values - */ - public DefaultItemSorter(Comparator<Object> propertyValueComparator) { - this.propertyValueComparator = propertyValueComparator; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.ItemSorter#compare(java.lang.Object, - * java.lang.Object) - */ - @Override - public int compare(Object o1, Object o2) { - Item item1 = container.getItem(o1); - Item item2 = container.getItem(o2); - - /* - * Items can be null if the container is filtered. Null is considered - * "less" than not-null. - */ - if (item1 == null) { - if (item2 == null) { - return 0; - } else { - return 1; - } - } else if (item2 == null) { - return -1; - } - - for (int i = 0; i < sortPropertyIds.length; i++) { - - int result = compareProperty(sortPropertyIds[i], sortDirections[i], - item1, item2); - - // If order can be decided - if (result != 0) { - return result; - } - - } - - return 0; - } - - /** - * Compares the property indicated by <code>propertyId</code> in the items - * indicated by <code>item1</code> and <code>item2</code> for order. Returns - * a negative integer, zero, or a positive integer as the property value in - * the first item is less than, equal to, or greater than the property value - * in the second item. If the <code>sortDirection</code> is false the - * returned value is negated. - * <p> - * The comparator set for this <code>DefaultItemSorter</code> is used for - * comparing the two property values. - * - * @param propertyId - * The property id for the property that is used for comparison. - * @param sortDirection - * The direction of the sort. A false value negates the result. - * @param item1 - * The first item to compare. - * @param item2 - * The second item to compare. - * @return a negative, zero, or positive integer if the property value in - * the first item is less than, equal to, or greater than the - * property value in the second item. Negated if - * {@code sortDirection} is false. - */ - protected int compareProperty(Object propertyId, boolean sortDirection, - Item item1, Item item2) { - - // Get the properties to compare - final Property<?> property1 = item1.getItemProperty(propertyId); - final Property<?> property2 = item2.getItemProperty(propertyId); - - // Get the values to compare - final Object value1 = (property1 == null) ? null : property1.getValue(); - final Object value2 = (property2 == null) ? null : property2.getValue(); - - // Result of the comparison - int r = 0; - if (sortDirection) { - r = propertyValueComparator.compare(value1, value2); - } else { - r = propertyValueComparator.compare(value2, value1); - } - - return r; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.ItemSorter#setSortProperties(com.vaadin.data.Container - * .Sortable, java.lang.Object[], boolean[]) - */ - @Override - public void setSortProperties(Container.Sortable container, - Object[] propertyId, boolean[] ascending) { - this.container = container; - - // Removes any non-sortable property ids - final List<Object> ids = new ArrayList<Object>(); - final List<Boolean> orders = new ArrayList<Boolean>(); - final Collection<?> sortable = container - .getSortableContainerPropertyIds(); - for (int i = 0; i < propertyId.length; i++) { - if (sortable.contains(propertyId[i])) { - ids.add(propertyId[i]); - orders.add(Boolean.valueOf(i < ascending.length ? ascending[i] - : true)); - } - } - - sortPropertyIds = ids.toArray(); - sortDirections = new boolean[orders.size()]; - for (int i = 0; i < sortDirections.length; i++) { - sortDirections[i] = (orders.get(i)).booleanValue(); - } - - } - - /** - * Provides a default comparator used for comparing {@link Property} values. - * The <code>DefaultPropertyValueComparator</code> assumes all objects it - * compares can be cast to Comparable. - * - */ - public static class DefaultPropertyValueComparator implements - Comparator<Object>, Serializable { - - @Override - @SuppressWarnings("unchecked") - public int compare(Object o1, Object o2) { - int r = 0; - // Normal non-null comparison - if (o1 != null && o2 != null) { - // Assume the objects can be cast to Comparable, throw - // ClassCastException otherwise. - r = ((Comparable<Object>) o1).compareTo(o2); - } else if (o1 == o2) { - // Objects are equal if both are null - r = 0; - } else { - if (o1 == null) { - r = -1; // null is less than non-null - } else { - r = 1; // non-null is greater than null - } - } - - return r; - } - } - -} diff --git a/src/com/vaadin/data/util/FilesystemContainer.java b/src/com/vaadin/data/util/FilesystemContainer.java deleted file mode 100644 index cdfeb57e14..0000000000 --- a/src/com/vaadin/data/util/FilesystemContainer.java +++ /dev/null @@ -1,918 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.service.FileTypeResolver; -import com.vaadin.terminal.Resource; - -/** - * A hierarchical container wrapper for a filesystem. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class FilesystemContainer implements Container.Hierarchical { - - /** - * String identifier of a file's "name" property. - */ - public static String PROPERTY_NAME = "Name"; - - /** - * String identifier of a file's "size" property. - */ - public static String PROPERTY_SIZE = "Size"; - - /** - * String identifier of a file's "icon" property. - */ - public static String PROPERTY_ICON = "Icon"; - - /** - * String identifier of a file's "last modified" property. - */ - public static String PROPERTY_LASTMODIFIED = "Last Modified"; - - /** - * List of the string identifiers for the available properties. - */ - public static Collection<String> FILE_PROPERTIES; - - private final static Method FILEITEM_LASTMODIFIED; - - private final static Method FILEITEM_NAME; - - private final static Method FILEITEM_ICON; - - private final static Method FILEITEM_SIZE; - - static { - - FILE_PROPERTIES = new ArrayList<String>(); - FILE_PROPERTIES.add(PROPERTY_NAME); - FILE_PROPERTIES.add(PROPERTY_ICON); - FILE_PROPERTIES.add(PROPERTY_SIZE); - FILE_PROPERTIES.add(PROPERTY_LASTMODIFIED); - FILE_PROPERTIES = Collections.unmodifiableCollection(FILE_PROPERTIES); - try { - FILEITEM_LASTMODIFIED = FileItem.class.getMethod("lastModified", - new Class[] {}); - FILEITEM_NAME = FileItem.class.getMethod("getName", new Class[] {}); - FILEITEM_ICON = FileItem.class.getMethod("getIcon", new Class[] {}); - FILEITEM_SIZE = FileItem.class.getMethod("getSize", new Class[] {}); - } catch (final NoSuchMethodException e) { - throw new RuntimeException( - "Internal error finding methods in FilesystemContainer"); - } - } - - private File[] roots = new File[] {}; - - private FilenameFilter filter = null; - - private boolean recursive = true; - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified file - * as the root of the filesystem. The files are included recursively. - * - * @param root - * the root file for the new file-system container. Null values - * are ignored. - */ - public FilesystemContainer(File root) { - if (root != null) { - roots = new File[] { root }; - } - } - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified file - * as the root of the filesystem. The files are included recursively. - * - * @param root - * the root file for the new file-system container. - * @param recursive - * should the container recursively contain subdirectories. - */ - public FilesystemContainer(File root, boolean recursive) { - this(root); - setRecursive(recursive); - } - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified file - * as the root of the filesystem. - * - * @param root - * the root file for the new file-system container. - * @param extension - * the Filename extension (w/o separator) to limit the files in - * container. - * @param recursive - * should the container recursively contain subdirectories. - */ - public FilesystemContainer(File root, String extension, boolean recursive) { - this(root); - this.setFilter(extension); - setRecursive(recursive); - } - - /** - * Constructs a new <code>FileSystemContainer</code> with the specified root - * and recursivity status. - * - * @param root - * the root file for the new file-system container. - * @param filter - * the Filename filter to limit the files in container. - * @param recursive - * should the container recursively contain subdirectories. - */ - public FilesystemContainer(File root, FilenameFilter filter, - boolean recursive) { - this(root); - this.setFilter(filter); - setRecursive(recursive); - } - - /** - * Adds new root file directory. Adds a file to be included as root file - * directory in the <code>FilesystemContainer</code>. - * - * @param root - * the File to be added as root directory. Null values are - * ignored. - */ - public void addRoot(File root) { - if (root != null) { - final File[] newRoots = new File[roots.length + 1]; - for (int i = 0; i < roots.length; i++) { - newRoots[i] = roots[i]; - } - newRoots[roots.length] = root; - roots = newRoots; - } - } - - /** - * Tests if the specified Item in the container may have children. Since a - * <code>FileSystemContainer</code> contains files and directories, this - * method returns <code>true</code> for directory Items only. - * - * @param itemId - * the id of the item. - * @return <code>true</code> if the specified Item is a directory, - * <code>false</code> otherwise. - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - return itemId instanceof File && ((File) itemId).canRead() - && ((File) itemId).isDirectory(); - } - - /* - * Gets the ID's of all Items who are children of the specified Item. Don't - * add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Collection<File> getChildren(Object itemId) { - - if (!(itemId instanceof File)) { - return Collections.unmodifiableCollection(new LinkedList<File>()); - } - File[] f; - if (filter != null) { - f = ((File) itemId).listFiles(filter); - } else { - f = ((File) itemId).listFiles(); - } - - if (f == null) { - return Collections.unmodifiableCollection(new LinkedList<File>()); - } - - final List<File> l = Arrays.asList(f); - Collections.sort(l); - - return Collections.unmodifiableCollection(l); - } - - /* - * Gets the parent item of the specified Item. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Object getParent(Object itemId) { - - if (!(itemId instanceof File)) { - return null; - } - return ((File) itemId).getParentFile(); - } - - /* - * Tests if the specified Item has any children. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean hasChildren(Object itemId) { - - if (!(itemId instanceof File)) { - return false; - } - String[] l; - if (filter != null) { - l = ((File) itemId).list(filter); - } else { - l = ((File) itemId).list(); - } - return (l != null) && (l.length > 0); - } - - /* - * Tests if the specified Item is the root of the filesystem. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isRoot(Object itemId) { - - if (!(itemId instanceof File)) { - return false; - } - for (int i = 0; i < roots.length; i++) { - if (roots[i].equals(itemId)) { - return true; - } - } - return false; - } - - /* - * Gets the ID's of all root Items in the container. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<File> rootItemIds() { - - File[] f; - - // in single root case we use children - if (roots.length == 1) { - if (filter != null) { - f = roots[0].listFiles(filter); - } else { - f = roots[0].listFiles(); - } - } else { - f = roots; - } - - if (f == null) { - return Collections.unmodifiableCollection(new LinkedList<File>()); - } - - final List<File> l = Arrays.asList(f); - Collections.sort(l); - - return Collections.unmodifiableCollection(l); - } - - /** - * Returns <code>false</code> when conversion from files to directories is - * not supported. - * - * @param itemId - * the ID of the item. - * @param areChildrenAllowed - * the boolean value specifying if the Item can have children or - * not. - * @return <code>true</code> if the operaton is successful otherwise - * <code>false</code>. - * @throws UnsupportedOperationException - * if the setChildrenAllowed is not supported. - */ - @Override - public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) - throws UnsupportedOperationException { - - throw new UnsupportedOperationException( - "Conversion file to/from directory is not supported"); - } - - /** - * Returns <code>false</code> when moving files around in the filesystem is - * not supported. - * - * @param itemId - * the ID of the item. - * @param newParentId - * the ID of the Item that's to be the new parent of the Item - * identified with itemId. - * @return <code>true</code> if the operation is successful otherwise - * <code>false</code>. - * @throws UnsupportedOperationException - * if the setParent is not supported. - */ - @Override - public boolean setParent(Object itemId, Object newParentId) - throws UnsupportedOperationException { - - throw new UnsupportedOperationException("File moving is not supported"); - } - - /* - * Tests if the filesystem contains the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean containsId(Object itemId) { - - if (!(itemId instanceof File)) { - return false; - } - boolean val = false; - - // Try to match all roots - for (int i = 0; i < roots.length; i++) { - try { - val |= ((File) itemId).getCanonicalPath().startsWith( - roots[i].getCanonicalPath()); - } catch (final IOException e) { - // Exception ignored - } - - } - if (val && filter != null) { - val &= filter.accept(((File) itemId).getParentFile(), - ((File) itemId).getName()); - } - return val; - } - - /* - * Gets the specified Item from the filesystem. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Item getItem(Object itemId) { - - if (!(itemId instanceof File)) { - return null; - } - return new FileItem((File) itemId); - } - - /** - * Internal recursive method to add the files under the specified directory - * to the collection. - * - * @param col - * the collection where the found items are added - * @param f - * the root file where to start adding files - */ - private void addItemIds(Collection<File> col, File f) { - File[] l; - if (filter != null) { - l = f.listFiles(filter); - } else { - l = f.listFiles(); - } - if (l == null) { - // File.listFiles returns null if File does not exist or if there - // was an IO error (permission denied) - return; - } - final List<File> ll = Arrays.asList(l); - Collections.sort(ll); - - for (final Iterator<File> i = ll.iterator(); i.hasNext();) { - final File lf = i.next(); - col.add(lf); - if (lf.isDirectory()) { - addItemIds(col, lf); - } - } - } - - /* - * Gets the IDs of Items in the filesystem. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Collection<File> getItemIds() { - - if (recursive) { - final Collection<File> col = new ArrayList<File>(); - for (int i = 0; i < roots.length; i++) { - addItemIds(col, roots[i]); - } - return Collections.unmodifiableCollection(col); - } else { - File[] f; - if (roots.length == 1) { - if (filter != null) { - f = roots[0].listFiles(filter); - } else { - f = roots[0].listFiles(); - } - } else { - f = roots; - } - - if (f == null) { - return Collections - .unmodifiableCollection(new LinkedList<File>()); - } - - final List<File> l = Arrays.asList(f); - Collections.sort(l); - return Collections.unmodifiableCollection(l); - } - - } - - /** - * Gets the specified property of the specified file Item. The available - * file properties are "Name", "Size" and "Last Modified". If propertyId is - * not one of those, <code>null</code> is returned. - * - * @param itemId - * the ID of the file whose property is requested. - * @param propertyId - * the property's ID. - * @return the requested property's value, or <code>null</code> - */ - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - - if (!(itemId instanceof File)) { - return null; - } - - if (propertyId.equals(PROPERTY_NAME)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_NAME, null); - } - - if (propertyId.equals(PROPERTY_ICON)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_ICON, null); - } - - if (propertyId.equals(PROPERTY_SIZE)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_SIZE, null); - } - - if (propertyId.equals(PROPERTY_LASTMODIFIED)) { - return new MethodProperty<Object>(getType(propertyId), - new FileItem((File) itemId), FILEITEM_LASTMODIFIED, null); - } - - return null; - } - - /** - * Gets the collection of available file properties. - * - * @return Unmodifiable collection containing all available file properties. - */ - @Override - public Collection<String> getContainerPropertyIds() { - return FILE_PROPERTIES; - } - - /** - * Gets the specified property's data type. "Name" is a <code>String</code>, - * "Size" is a <code>Long</code>, "Last Modified" is a <code>Date</code>. If - * propertyId is not one of those, <code>null</code> is returned. - * - * @param propertyId - * the ID of the property whose type is requested. - * @return data type of the requested property, or <code>null</code> - */ - @Override - public Class<?> getType(Object propertyId) { - - if (propertyId.equals(PROPERTY_NAME)) { - return String.class; - } - if (propertyId.equals(PROPERTY_ICON)) { - return Resource.class; - } - if (propertyId.equals(PROPERTY_SIZE)) { - return Long.class; - } - if (propertyId.equals(PROPERTY_LASTMODIFIED)) { - return Date.class; - } - return null; - } - - /** - * Internal method to recursively calculate the number of files under a root - * directory. - * - * @param f - * the root to start counting from. - */ - private int getFileCounts(File f) { - File[] l; - if (filter != null) { - l = f.listFiles(filter); - } else { - l = f.listFiles(); - } - - if (l == null) { - return 0; - } - int ret = l.length; - for (int i = 0; i < l.length; i++) { - if (l[i].isDirectory()) { - ret += getFileCounts(l[i]); - } - } - return ret; - } - - /** - * Gets the number of Items in the container. In effect, this is the - * combined amount of files and directories. - * - * @return Number of Items in the container. - */ - @Override - public int size() { - - if (recursive) { - int counts = 0; - for (int i = 0; i < roots.length; i++) { - counts += getFileCounts(roots[i]); - } - return counts; - } else { - File[] f; - if (roots.length == 1) { - if (filter != null) { - f = roots[0].listFiles(filter); - } else { - f = roots[0].listFiles(); - } - } else { - f = roots; - } - - if (f == null) { - return 0; - } - return f.length; - } - } - - /** - * A Item wrapper for files in a filesystem. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public class FileItem implements Item { - - /** - * The wrapped file. - */ - private final File file; - - /** - * Constructs a FileItem from a existing file. - */ - private FileItem(File file) { - this.file = file; - } - - /* - * Gets the specified property of this file. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Property<?> getItemProperty(Object id) { - return getContainerProperty(file, id); - } - - /* - * Gets the IDs of all properties available for this item Don't add a - * JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Collection<String> getItemPropertyIds() { - return getContainerPropertyIds(); - } - - /** - * Calculates a integer hash-code for the Property that's unique inside - * the Item containing the Property. Two different Properties inside the - * same Item contained in the same list always have different - * hash-codes, though Properties in different Items may have identical - * hash-codes. - * - * @return A locally unique hash-code as integer - */ - @Override - public int hashCode() { - return file.hashCode() ^ FilesystemContainer.this.hashCode(); - } - - /** - * Tests if the given object is the same as the this object. Two - * Properties got from an Item with the same ID are equal. - * - * @param obj - * an object to compare with this object. - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof FileItem)) { - return false; - } - final FileItem fi = (FileItem) obj; - return fi.getHost() == getHost() && fi.file.equals(file); - } - - /** - * Gets the host of this file. - */ - private FilesystemContainer getHost() { - return FilesystemContainer.this; - } - - /** - * Gets the last modified date of this file. - * - * @return Date - */ - public Date lastModified() { - return new Date(file.lastModified()); - } - - /** - * Gets the name of this file. - * - * @return file name of this file. - */ - public String getName() { - return file.getName(); - } - - /** - * Gets the icon of this file. - * - * @return the icon of this file. - */ - public Resource getIcon() { - return FileTypeResolver.getIcon(file); - } - - /** - * Gets the size of this file. - * - * @return size - */ - public long getSize() { - if (file.isDirectory()) { - return 0; - } - return file.length(); - } - - /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - if ("".equals(file.getName())) { - return file.getAbsolutePath(); - } - return file.getName(); - } - - /** - * Filesystem container does not support adding new properties. - * - * @see com.vaadin.data.Item#addItemProperty(Object, Property) - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException("Filesystem container " - + "does not support adding new properties"); - } - - /** - * Filesystem container does not support removing properties. - * - * @see com.vaadin.data.Item#removeItemProperty(Object) - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Filesystem container does not support property removal"); - } - - } - - /** - * Generic file extension filter for displaying only files having certain - * extension. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public class FileExtensionFilter implements FilenameFilter, Serializable { - - private final String filter; - - /** - * Constructs a new FileExtensionFilter using given extension. - * - * @param fileExtension - * the File extension without the separator (dot). - */ - public FileExtensionFilter(String fileExtension) { - filter = "." + fileExtension; - } - - /** - * Allows only files with the extension and directories. - * - * @see java.io.FilenameFilter#accept(File, String) - */ - @Override - public boolean accept(File dir, String name) { - if (name.endsWith(filter)) { - return true; - } - return new File(dir, name).isDirectory(); - } - - } - - /** - * Returns the file filter used to limit the files in this container. - * - * @return Used filter instance or null if no filter is assigned. - */ - public FilenameFilter getFilter() { - return filter; - } - - /** - * Sets the file filter used to limit the files in this container. - * - * @param filter - * The filter to set. <code>null</code> disables filtering. - */ - public void setFilter(FilenameFilter filter) { - this.filter = filter; - } - - /** - * Sets the file filter used to limit the files in this container. - * - * @param extension - * the Filename extension (w/o separator) to limit the files in - * container. - */ - public void setFilter(String extension) { - filter = new FileExtensionFilter(extension); - } - - /** - * Is this container recursive filesystem. - * - * @return <code>true</code> if container is recursive, <code>false</code> - * otherwise. - */ - public boolean isRecursive() { - return recursive; - } - - /** - * Sets the container recursive property. Set this to false to limit the - * files directly under the root file. - * <p> - * Note : This is meaningful only if the root really is a directory. - * </p> - * - * @param recursive - * the New value for recursive property. - */ - public void setRecursive(boolean recursive) { - this.recursive = recursive; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem() - */ - @Override - public Object addItem() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object ) - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "File system container does not support this operation"); - } -} diff --git a/src/com/vaadin/data/util/HierarchicalContainer.java b/src/com/vaadin/data/util/HierarchicalContainer.java deleted file mode 100644 index 06ab77c0e7..0000000000 --- a/src/com/vaadin/data/util/HierarchicalContainer.java +++ /dev/null @@ -1,814 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Set; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; - -/** - * A specialized Container whose contents can be accessed like it was a - * tree-like structure. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class HierarchicalContainer extends IndexedContainer implements - Container.Hierarchical { - - /** - * Set of IDs of those contained Items that can't have children. - */ - private final HashSet<Object> noChildrenAllowed = new HashSet<Object>(); - - /** - * Mapping from Item ID to parent Item ID. - */ - private final HashMap<Object, Object> parent = new HashMap<Object, Object>(); - - /** - * Mapping from Item ID to parent Item ID for items included in the filtered - * container. - */ - private HashMap<Object, Object> filteredParent = null; - - /** - * Mapping from Item ID to a list of child IDs. - */ - private final HashMap<Object, LinkedList<Object>> children = new HashMap<Object, LinkedList<Object>>(); - - /** - * Mapping from Item ID to a list of child IDs when filtered - */ - private HashMap<Object, LinkedList<Object>> filteredChildren = null; - - /** - * List that contains all root elements of the container. - */ - private final LinkedList<Object> roots = new LinkedList<Object>(); - - /** - * List that contains all filtered root elements of the container. - */ - private LinkedList<Object> filteredRoots = null; - - /** - * Determines how filtering of the container is done. - */ - private boolean includeParentsWhenFiltering = true; - - private boolean contentChangedEventsDisabled = false; - - private boolean contentsChangedEventPending; - - /* - * Can the specified Item have any children? Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean areChildrenAllowed(Object itemId) { - if (noChildrenAllowed.contains(itemId)) { - return false; - } - return containsId(itemId); - } - - /* - * Gets the IDs of the children of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> getChildren(Object itemId) { - LinkedList<Object> c; - - if (filteredChildren != null) { - c = filteredChildren.get(itemId); - } else { - c = children.get(itemId); - } - - if (c == null) { - return null; - } - return Collections.unmodifiableCollection(c); - } - - /* - * Gets the ID of the parent of the specified Item. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Object getParent(Object itemId) { - if (filteredParent != null) { - return filteredParent.get(itemId); - } - return parent.get(itemId); - } - - /* - * Is the Item corresponding to the given ID a leaf node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean hasChildren(Object itemId) { - if (filteredChildren != null) { - return filteredChildren.containsKey(itemId); - } else { - return children.containsKey(itemId); - } - } - - /* - * Is the Item corresponding to the given ID a root node? Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public boolean isRoot(Object itemId) { - // If the container is filtered the itemId must be among filteredRoots - // to be a root. - if (filteredRoots != null) { - if (!filteredRoots.contains(itemId)) { - return false; - } - } else { - // Container is not filtered - if (parent.containsKey(itemId)) { - return false; - } - } - - return containsId(itemId); - } - - /* - * Gets the IDs of the root elements in the container. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public Collection<?> rootItemIds() { - if (filteredRoots != null) { - return Collections.unmodifiableCollection(filteredRoots); - } else { - return Collections.unmodifiableCollection(roots); - } - } - - /** - * <p> - * Sets the given Item's capability to have children. If the Item identified - * with the itemId already has children and the areChildrenAllowed is false - * this method fails and <code>false</code> is returned; the children must - * be first explicitly removed with - * {@link #setParent(Object itemId, Object newParentId)} or - * {@link com.vaadin.data.Container#removeItem(Object itemId)}. - * </p> - * - * @param itemId - * the ID of the Item in the container whose child capability is - * to be set. - * @param childrenAllowed - * the boolean value specifying if the Item can have children or - * not. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setChildrenAllowed(Object itemId, boolean childrenAllowed) { - - // Checks that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Updates status - if (childrenAllowed) { - noChildrenAllowed.remove(itemId); - } else { - noChildrenAllowed.add(itemId); - } - - return true; - } - - /** - * <p> - * Sets the parent of an Item. The new parent item must exist and be able to - * have children. (<code>canHaveChildren(newParentId) == true</code>). It is - * also possible to detach a node from the hierarchy (and thus make it root) - * by setting the parent <code>null</code>. - * </p> - * - * @param itemId - * the ID of the item to be set as the child of the Item - * identified with newParentId. - * @param newParentId - * the ID of the Item that's to be the new parent of the Item - * identified with itemId. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean setParent(Object itemId, Object newParentId) { - - // Checks that the item is in the container - if (!containsId(itemId)) { - return false; - } - - // Gets the old parent - final Object oldParentId = parent.get(itemId); - - // Checks if no change is necessary - if ((newParentId == null && oldParentId == null) - || ((newParentId != null) && newParentId.equals(oldParentId))) { - return true; - } - - // Making root? - if (newParentId == null) { - // The itemId should become a root so we need to - // - Remove it from the old parent's children list - // - Add it as a root - // - Remove it from the item -> parent list (parent is null for - // roots) - - // Removes from old parents children list - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(oldParentId); - } - - } - - // Add to be a root - roots.add(itemId); - - // Updates parent - parent.remove(itemId); - - if (hasFilters()) { - // Refilter the container if setParent is called when filters - // are applied. Changing parent can change what is included in - // the filtered version (if includeParentsWhenFiltering==true). - doFilterContainer(hasFilters()); - } - - fireItemSetChange(); - - return true; - } - - // We get here when the item should not become a root and we need to - // - Verify the new parent exists and can have children - // - Check that the new parent is not a child of the selected itemId - // - Updated the item -> parent mapping to point to the new parent - // - Remove the item from the roots list if it was a root - // - Remove the item from the old parent's children list if it was not a - // root - - // Checks that the new parent exists in container and can have - // children - if (!containsId(newParentId) || noChildrenAllowed.contains(newParentId)) { - return false; - } - - // Checks that setting parent doesn't result to a loop - Object o = newParentId; - while (o != null && !o.equals(itemId)) { - o = parent.get(o); - } - if (o != null) { - return false; - } - - // Updates parent - parent.put(itemId, newParentId); - LinkedList<Object> pcl = children.get(newParentId); - if (pcl == null) { - // Create an empty list for holding children if one were not - // previously created - pcl = new LinkedList<Object>(); - children.put(newParentId, pcl); - } - pcl.add(itemId); - - // Removes from old parent or root - if (oldParentId == null) { - roots.remove(itemId); - } else { - final LinkedList<Object> l = children.get(oldParentId); - if (l != null) { - l.remove(itemId); - if (l.isEmpty()) { - children.remove(oldParentId); - } - } - } - - if (hasFilters()) { - // Refilter the container if setParent is called when filters - // are applied. Changing parent can change what is included in - // the filtered version (if includeParentsWhenFiltering==true). - doFilterContainer(hasFilters()); - } - - fireItemSetChange(); - - return true; - } - - private boolean hasFilters() { - return (filteredRoots != null); - } - - /** - * Moves a node (an Item) in the container immediately after a sibling node. - * The two nodes must have the same parent in the container. - * - * @param itemId - * the identifier of the moved node (Item) - * @param siblingId - * the identifier of the reference node (Item), after which the - * other node will be located - */ - public void moveAfterSibling(Object itemId, Object siblingId) { - Object parent2 = getParent(itemId); - LinkedList<Object> childrenList; - if (parent2 == null) { - childrenList = roots; - } else { - childrenList = children.get(parent2); - } - if (siblingId == null) { - childrenList.remove(itemId); - childrenList.addFirst(itemId); - - } else { - int oldIndex = childrenList.indexOf(itemId); - int indexOfSibling = childrenList.indexOf(siblingId); - if (indexOfSibling != -1 && oldIndex != -1) { - int newIndex; - if (oldIndex > indexOfSibling) { - newIndex = indexOfSibling + 1; - } else { - newIndex = indexOfSibling; - } - childrenList.remove(oldIndex); - childrenList.add(newIndex, itemId); - } else { - throw new IllegalArgumentException( - "Given identifiers no not have the same parent."); - } - } - fireItemSetChange(); - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#addItem() - */ - @Override - public Object addItem() { - disableContentsChangeEvents(); - final Object itemId = super.addItem(); - if (itemId == null) { - return null; - } - - if (!roots.contains(itemId)) { - roots.add(itemId); - if (filteredRoots != null) { - if (passesFilters(itemId)) { - filteredRoots.add(itemId); - } - } - } - enableAndFireContentsChangeEvents(); - return itemId; - } - - @Override - protected void fireItemSetChange( - com.vaadin.data.Container.ItemSetChangeEvent event) { - if (contentsChangeEventsOn()) { - super.fireItemSetChange(event); - } else { - contentsChangedEventPending = true; - } - } - - private boolean contentsChangeEventsOn() { - return !contentChangedEventsDisabled; - } - - private void disableContentsChangeEvents() { - contentChangedEventsDisabled = true; - } - - private void enableAndFireContentsChangeEvents() { - contentChangedEventsDisabled = false; - if (contentsChangedEventPending) { - fireItemSetChange(); - } - contentsChangedEventPending = false; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) { - disableContentsChangeEvents(); - final Item item = super.addItem(itemId); - if (item == null) { - return null; - } - - roots.add(itemId); - - if (filteredRoots != null) { - if (passesFilters(itemId)) { - filteredRoots.add(itemId); - } - } - enableAndFireContentsChangeEvents(); - return item; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#removeAllItems() - */ - @Override - public boolean removeAllItems() { - disableContentsChangeEvents(); - final boolean success = super.removeAllItems(); - - if (success) { - roots.clear(); - parent.clear(); - children.clear(); - noChildrenAllowed.clear(); - if (filteredRoots != null) { - filteredRoots = null; - } - if (filteredChildren != null) { - filteredChildren = null; - } - if (filteredParent != null) { - filteredParent = null; - } - } - enableAndFireContentsChangeEvents(); - return success; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#removeItem(java.lang.Object ) - */ - @Override - public boolean removeItem(Object itemId) { - disableContentsChangeEvents(); - final boolean success = super.removeItem(itemId); - - if (success) { - // Remove from roots if this was a root - if (roots.remove(itemId)) { - - // If filtering is enabled we might need to remove it from the - // filtered list also - if (filteredRoots != null) { - filteredRoots.remove(itemId); - } - } - - // Clear the children list. Old children will now become root nodes - LinkedList<Object> childNodeIds = children.remove(itemId); - if (childNodeIds != null) { - if (filteredChildren != null) { - filteredChildren.remove(itemId); - } - for (Object childId : childNodeIds) { - setParent(childId, null); - } - } - - // Parent of the item that we are removing will contain the item id - // in its children list - final Object parentItemId = parent.get(itemId); - if (parentItemId != null) { - final LinkedList<Object> c = children.get(parentItemId); - if (c != null) { - c.remove(itemId); - - if (c.isEmpty()) { - children.remove(parentItemId); - } - - // Found in the children list so might also be in the - // filteredChildren list - if (filteredChildren != null) { - LinkedList<Object> f = filteredChildren - .get(parentItemId); - if (f != null) { - f.remove(itemId); - if (f.isEmpty()) { - filteredChildren.remove(parentItemId); - } - } - } - } - } - parent.remove(itemId); - if (filteredParent != null) { - // Item id no longer has a parent as the item id is not in the - // container. - filteredParent.remove(itemId); - } - noChildrenAllowed.remove(itemId); - } - - enableAndFireContentsChangeEvents(); - - return success; - } - - /** - * Removes the Item identified by given itemId and all its children. - * - * @see #removeItem(Object) - * @param itemId - * the identifier of the Item to be removed - * @return true if the operation succeeded - */ - public boolean removeItemRecursively(Object itemId) { - disableContentsChangeEvents(); - boolean removeItemRecursively = removeItemRecursively(this, itemId); - enableAndFireContentsChangeEvents(); - return removeItemRecursively; - } - - /** - * Removes the Item identified by given itemId and all its children from the - * given Container. - * - * @param container - * the container where the item is to be removed - * @param itemId - * the identifier of the Item to be removed - * @return true if the operation succeeded - */ - public static boolean removeItemRecursively( - Container.Hierarchical container, Object itemId) { - boolean success = true; - Collection<?> children2 = container.getChildren(itemId); - if (children2 != null) { - Object[] array = children2.toArray(); - for (int i = 0; i < array.length; i++) { - boolean removeItemRecursively = removeItemRecursively( - container, array[i]); - if (!removeItemRecursively) { - success = false; - } - } - } - // remove the root of subtree if children where succesfully removed - if (success) { - success = container.removeItem(itemId); - } - return success; - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#doSort() - */ - @Override - protected void doSort() { - super.doSort(); - - Collections.sort(roots, getItemSorter()); - for (LinkedList<Object> childList : children.values()) { - Collections.sort(childList, getItemSorter()); - } - } - - /** - * Used to control how filtering works. @see - * {@link #setIncludeParentsWhenFiltering(boolean)} for more information. - * - * @return true if all parents for items that match the filter are included - * when filtering, false if only the matching items are included - */ - public boolean isIncludeParentsWhenFiltering() { - return includeParentsWhenFiltering; - } - - /** - * Controls how the filtering of the container works. Set this to true to - * make filtering include parents for all matched items in addition to the - * items themselves. Setting this to false causes the filtering to only - * include the matching items and make items with excluded parents into root - * items. - * - * @param includeParentsWhenFiltering - * true to include all parents for items that match the filter, - * false to only include the matching items - */ - public void setIncludeParentsWhenFiltering( - boolean includeParentsWhenFiltering) { - this.includeParentsWhenFiltering = includeParentsWhenFiltering; - if (filteredRoots != null) { - // Currently filtered so needs to be re-filtered - doFilterContainer(true); - } - } - - /* - * Overridden to provide filtering for root & children items. - * - * (non-Javadoc) - * - * @see com.vaadin.data.util.IndexedContainer#updateContainerFiltering() - */ - @Override - protected boolean doFilterContainer(boolean hasFilters) { - if (!hasFilters) { - // All filters removed - filteredRoots = null; - filteredChildren = null; - filteredParent = null; - - return super.doFilterContainer(hasFilters); - } - - // Reset data structures - filteredRoots = new LinkedList<Object>(); - filteredChildren = new HashMap<Object, LinkedList<Object>>(); - filteredParent = new HashMap<Object, Object>(); - - if (includeParentsWhenFiltering) { - // Filter so that parents for items that match the filter are also - // included - HashSet<Object> includedItems = new HashSet<Object>(); - for (Object rootId : roots) { - if (filterIncludingParents(rootId, includedItems)) { - filteredRoots.add(rootId); - addFilteredChildrenRecursively(rootId, includedItems); - } - } - // includedItemIds now contains all the item ids that should be - // included. Filter IndexedContainer based on this - filterOverride = includedItems; - super.doFilterContainer(hasFilters); - filterOverride = null; - - return true; - } else { - // Filter by including all items that pass the filter and make items - // with no parent new root items - - // Filter IndexedContainer first so getItemIds return the items that - // match - super.doFilterContainer(hasFilters); - - LinkedHashSet<Object> filteredItemIds = new LinkedHashSet<Object>( - getItemIds()); - - for (Object itemId : filteredItemIds) { - Object itemParent = parent.get(itemId); - if (itemParent == null || !filteredItemIds.contains(itemParent)) { - // Parent is not included or this was a root, in both cases - // this should be a filtered root - filteredRoots.add(itemId); - } else { - // Parent is included. Add this to the children list (create - // it first if necessary) - addFilteredChild(itemParent, itemId); - } - } - - return true; - } - } - - /** - * Adds the given childItemId as a filteredChildren for the parentItemId and - * sets it filteredParent. - * - * @param parentItemId - * @param childItemId - */ - private void addFilteredChild(Object parentItemId, Object childItemId) { - LinkedList<Object> parentToChildrenList = filteredChildren - .get(parentItemId); - if (parentToChildrenList == null) { - parentToChildrenList = new LinkedList<Object>(); - filteredChildren.put(parentItemId, parentToChildrenList); - } - filteredParent.put(childItemId, parentItemId); - parentToChildrenList.add(childItemId); - - } - - /** - * Recursively adds all items in the includedItems list to the - * filteredChildren map in the same order as they are in the children map. - * Starts from parentItemId and recurses down as long as child items that - * should be included are found. - * - * @param parentItemId - * The item id to start recurse from. Not added to a - * filteredChildren list - * @param includedItems - * Set containing the item ids for the items that should be - * included in the filteredChildren map - */ - private void addFilteredChildrenRecursively(Object parentItemId, - HashSet<Object> includedItems) { - LinkedList<Object> childList = children.get(parentItemId); - if (childList == null) { - return; - } - - for (Object childItemId : childList) { - if (includedItems.contains(childItemId)) { - addFilteredChild(parentItemId, childItemId); - addFilteredChildrenRecursively(childItemId, includedItems); - } - } - } - - /** - * Scans the itemId and all its children for which items should be included - * when filtering. All items which passes the filters are included. - * Additionally all items that have a child node that should be included are - * also themselves included. - * - * @param itemId - * @param includedItems - * @return true if the itemId should be included in the filtered container. - */ - private boolean filterIncludingParents(Object itemId, - HashSet<Object> includedItems) { - boolean toBeIncluded = passesFilters(itemId); - - LinkedList<Object> childList = children.get(itemId); - if (childList != null) { - for (Object childItemId : children.get(itemId)) { - toBeIncluded |= filterIncludingParents(childItemId, - includedItems); - } - } - - if (toBeIncluded) { - includedItems.add(itemId); - } - return toBeIncluded; - } - - private Set<Object> filterOverride = null; - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.IndexedContainer#passesFilters(java.lang.Object) - */ - @Override - protected boolean passesFilters(Object itemId) { - if (filterOverride != null) { - return filterOverride.contains(itemId); - } else { - return super.passesFilters(itemId); - } - } -} diff --git a/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java b/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java deleted file mode 100644 index 172dc0dd4f..0000000000 --- a/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java +++ /dev/null @@ -1,70 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.util.Collection; - -import com.vaadin.data.Container.Hierarchical; - -/** - * A wrapper class for adding external ordering to containers not implementing - * the {@link com.vaadin.data.Container.Ordered} interface while retaining - * {@link Hierarchical} features. - * - * @see ContainerOrderedWrapper - */ -@SuppressWarnings({ "serial" }) -public class HierarchicalContainerOrderedWrapper extends - ContainerOrderedWrapper implements Hierarchical { - - private Hierarchical hierarchical; - - public HierarchicalContainerOrderedWrapper(Hierarchical toBeWrapped) { - super(toBeWrapped); - hierarchical = toBeWrapped; - } - - @Override - public boolean areChildrenAllowed(Object itemId) { - return hierarchical.areChildrenAllowed(itemId); - } - - @Override - public Collection<?> getChildren(Object itemId) { - return hierarchical.getChildren(itemId); - } - - @Override - public Object getParent(Object itemId) { - return hierarchical.getParent(itemId); - } - - @Override - public boolean hasChildren(Object itemId) { - return hierarchical.hasChildren(itemId); - } - - @Override - public boolean isRoot(Object itemId) { - return hierarchical.isRoot(itemId); - } - - @Override - public Collection<?> rootItemIds() { - return hierarchical.rootItemIds(); - } - - @Override - public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) - throws UnsupportedOperationException { - return hierarchical.setChildrenAllowed(itemId, areChildrenAllowed); - } - - @Override - public boolean setParent(Object itemId, Object newParentId) - throws UnsupportedOperationException { - return hierarchical.setParent(itemId, newParentId); - } - -} diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java deleted file mode 100644 index b95b2c4de8..0000000000 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ /dev/null @@ -1,1109 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.filter.UnsupportedFilterException; - -/** - * An implementation of the <code>{@link Container.Indexed}</code> interface - * with all important features.</p> - * - * Features: - * <ul> - * <li> {@link Container.Indexed} - * <li> {@link Container.Ordered} - * <li> {@link Container.Sortable} - * <li> {@link Container.Filterable} - * <li> {@link Cloneable} (deprecated, might be removed in the future) - * <li>Sends all needed events on content changes. - * </ul> - * - * @see com.vaadin.data.Container - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - -@SuppressWarnings("serial") -// item type is really IndexedContainerItem, but using Item not to show it in -// public API -public class IndexedContainer extends - AbstractInMemoryContainer<Object, Object, Item> implements - Container.PropertySetChangeNotifier, Property.ValueChangeNotifier, - Container.Sortable, Cloneable, Container.Filterable, - Container.SimpleFilterable { - - /* Internal structure */ - - /** - * Linked list of ordered Property IDs. - */ - private ArrayList<Object> propertyIds = new ArrayList<Object>(); - - /** - * Property ID to type mapping. - */ - private Hashtable<Object, Class<?>> types = new Hashtable<Object, Class<?>>(); - - /** - * Hash of Items, where each Item is implemented as a mapping from Property - * ID to Property value. - */ - private Hashtable<Object, Map<Object, Object>> items = new Hashtable<Object, Map<Object, Object>>(); - - /** - * Set of properties that are read-only. - */ - private HashSet<Property<?>> readOnlyProperties = new HashSet<Property<?>>(); - - /** - * List of all Property value change event listeners listening all the - * properties. - */ - private LinkedList<Property.ValueChangeListener> propertyValueChangeListeners = null; - - /** - * Data structure containing all listeners interested in changes to single - * Properties. The data structure is a hashtable mapping Property IDs to a - * hashtable that maps Item IDs to a linked list of listeners listening - * Property identified by given Property ID and Item ID. - */ - private Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>> singlePropertyValueChangeListeners = null; - - private HashMap<Object, Object> defaultPropertyValues; - - private int nextGeneratedItemId = 1; - - /* Container constructors */ - - public IndexedContainer() { - super(); - } - - public IndexedContainer(Collection<?> itemIds) { - this(); - if (items != null) { - for (final Iterator<?> i = itemIds.iterator(); i.hasNext();) { - Object itemId = i.next(); - internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId), - false); - } - filterAll(); - } - } - - /* Container methods */ - - @Override - protected Item getUnfilteredItem(Object itemId) { - if (itemId != null && items.containsKey(itemId)) { - return new IndexedContainerItem(itemId); - } - return null; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - @Override - public Collection<?> getContainerPropertyIds() { - return Collections.unmodifiableCollection(propertyIds); - } - - /** - * Gets the type of a Property stored in the list. - * - * @param id - * the ID of the Property. - * @return Type of the requested Property - */ - @Override - public Class<?> getType(Object propertyId) { - return types.get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, - * java.lang.Object) - */ - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - if (!containsId(itemId)) { - return null; - } - - return new IndexedContainerProperty(itemId, propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) { - - // Fails, if nulls are given - if (propertyId == null || type == null) { - return false; - } - - // Fails if the Property is already present - if (propertyIds.contains(propertyId)) { - return false; - } - - // Adds the Property to Property list and types - propertyIds.add(propertyId); - types.put(propertyId, type); - - // If default value is given, set it - if (defaultValue != null) { - // for existing rows - for (final Iterator<?> i = getAllItemIds().iterator(); i.hasNext();) { - getItem(i.next()).getItemProperty(propertyId).setValue( - defaultValue); - } - // store for next rows - if (defaultPropertyValues == null) { - defaultPropertyValues = new HashMap<Object, Object>(); - } - defaultPropertyValues.put(propertyId, defaultValue); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() { - int origSize = size(); - - internalRemoveAllItems(); - - items.clear(); - - // fire event only if the visible view changed, regardless of whether - // filtered out items were removed or not - if (origSize != 0) { - // Sends a change event - fireItemSetChange(); - } - - return true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem() - */ - @Override - public Object addItem() { - - // Creates a new id - final Object id = generateId(); - - // Adds the Item into container - addItem(id); - - return id; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) { - Item item = internalAddItemAtEnd(itemId, new IndexedContainerItem( - itemId), false); - if (!isFiltered()) { - // always the last item - fireItemAdded(size() - 1, itemId, item); - } else if (passesFilters(itemId) && !containsId(itemId)) { - getFilteredItemIds().add(itemId); - // always the last item - fireItemAdded(size() - 1, itemId, item); - } - return item; - } - - /** - * Helper method to add default values for items if available - * - * @param t - * data table of added item - */ - private void addDefaultValues(Hashtable<Object, Object> t) { - if (defaultPropertyValues != null) { - for (Object key : defaultPropertyValues.keySet()) { - t.put(key, defaultPropertyValues.get(key)); - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) { - if (itemId == null || items.remove(itemId) == null) { - return false; - } - int origSize = size(); - int position = indexOfId(itemId); - if (internalRemoveItem(itemId)) { - // fire event only if the visible view changed, regardless of - // whether filtered out items were removed or not - if (size() != origSize) { - fireItemRemoved(position, itemId); - } - - return true; - } else { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object ) - */ - @Override - public boolean removeContainerProperty(Object propertyId) { - - // Fails if the Property is not present - if (!propertyIds.contains(propertyId)) { - return false; - } - - // Removes the Property to Property list and types - propertyIds.remove(propertyId); - types.remove(propertyId); - if (defaultPropertyValues != null) { - defaultPropertyValues.remove(propertyId); - } - - // If remove the Property from all Items - for (final Iterator<Object> i = getAllItemIds().iterator(); i.hasNext();) { - items.get(i.next()).remove(propertyId); - } - - // Sends a change event - fireContainerPropertySetChange(); - - return true; - } - - /* Container.Ordered methods */ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, - * java.lang.Object) - */ - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) { - return internalAddItemAfter(previousItemId, newItemId, - new IndexedContainerItem(newItemId), true); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) - */ - @Override - public Object addItemAfter(Object previousItemId) { - - // Creates a new id - final Object id = generateId(); - - if (addItemAfter(previousItemId, id) != null) { - return id; - } else { - return null; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object) - */ - @Override - public Item addItemAt(int index, Object newItemId) { - return internalAddItemAt(index, newItemId, new IndexedContainerItem( - newItemId), true); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int) - */ - @Override - public Object addItemAt(int index) { - - // Creates a new id - final Object id = generateId(); - - // Adds the Item into container - addItemAt(index, id); - - return id; - } - - /** - * Generates an unique identifier for use as an item id. Guarantees that the - * generated id is not currently used as an id. - * - * @return - */ - private Serializable generateId() { - Serializable id; - do { - id = Integer.valueOf(nextGeneratedItemId++); - } while (items.containsKey(id)); - - return id; - } - - @Override - protected void registerNewItem(int index, Object newItemId, Item item) { - Hashtable<Object, Object> t = new Hashtable<Object, Object>(); - items.put(newItemId, t); - addDefaultValues(t); - } - - /* Event notifiers */ - - /** - * An <code>event</code> object specifying the list whose Item set has - * changed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public static class ItemSetChangeEvent extends BaseItemSetChangeEvent { - - private final int addedItemIndex; - - private ItemSetChangeEvent(IndexedContainer source, int addedItemIndex) { - super(source); - this.addedItemIndex = addedItemIndex; - } - - /** - * Iff one item is added, gives its index. - * - * @return -1 if either multiple items are changed or some other change - * than add is done. - */ - public int getAddedItemIndex() { - return addedItemIndex; - } - - } - - /** - * An <code>event</code> object specifying the Property in a list whose - * value has changed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - private static class PropertyValueChangeEvent extends EventObject implements - Property.ValueChangeEvent, Serializable { - - private PropertyValueChangeEvent(Property source) { - super(source); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeEvent#getProperty() - */ - @Override - public Property getProperty() { - return (Property) getSource(); - } - - } - - @Override - public void addListener(Container.PropertySetChangeListener listener) { - super.addListener(listener); - } - - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - super.removeListener(listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#addListener(com. - * vaadin.data.Property.ValueChangeListener) - */ - @Override - public void addListener(Property.ValueChangeListener listener) { - if (propertyValueChangeListeners == null) { - propertyValueChangeListeners = new LinkedList<Property.ValueChangeListener>(); - } - propertyValueChangeListeners.add(listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener(com - * .vaadin.data.Property.ValueChangeListener) - */ - @Override - public void removeListener(Property.ValueChangeListener listener) { - if (propertyValueChangeListeners != null) { - propertyValueChangeListeners.remove(listener); - } - } - - /** - * Sends a Property value change event to all interested listeners. - * - * @param source - * the IndexedContainerProperty object. - */ - private void firePropertyValueChange(IndexedContainerProperty source) { - - // Sends event to listeners listening all value changes - if (propertyValueChangeListeners != null) { - final Object[] l = propertyValueChangeListeners.toArray(); - final Property.ValueChangeEvent event = new IndexedContainer.PropertyValueChangeEvent( - source); - for (int i = 0; i < l.length; i++) { - ((Property.ValueChangeListener) l[i]).valueChange(event); - } - } - - // Sends event to single property value change listeners - if (singlePropertyValueChangeListeners != null) { - final Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(source.propertyId); - if (propertySetToListenerListMap != null) { - final List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap - .get(source.itemId); - if (listenerList != null) { - final Property.ValueChangeEvent event = new IndexedContainer.PropertyValueChangeEvent( - source); - Object[] listeners = listenerList.toArray(); - for (int i = 0; i < listeners.length; i++) { - ((Property.ValueChangeListener) listeners[i]) - .valueChange(event); - } - } - } - } - - } - - @Override - public Collection<?> getListeners(Class<?> eventType) { - if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) { - if (propertyValueChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertyValueChangeListeners); - } - } - return super.getListeners(eventType); - } - - @Override - protected void fireItemAdded(int position, Object itemId, Item item) { - if (position >= 0) { - fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this, - position)); - } - } - - @Override - protected void fireItemSetChange() { - fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this, -1)); - } - - /** - * Adds new single Property change listener. - * - * @param propertyId - * the ID of the Property to add. - * @param itemId - * the ID of the Item . - * @param listener - * the listener to be added. - */ - private void addSinglePropertyChangeListener(Object propertyId, - Object itemId, Property.ValueChangeListener listener) { - if (listener != null) { - if (singlePropertyValueChangeListeners == null) { - singlePropertyValueChangeListeners = new Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>(); - } - Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(propertyId); - if (propertySetToListenerListMap == null) { - propertySetToListenerListMap = new Hashtable<Object, List<Property.ValueChangeListener>>(); - singlePropertyValueChangeListeners.put(propertyId, - propertySetToListenerListMap); - } - List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap - .get(itemId); - if (listenerList == null) { - listenerList = new LinkedList<Property.ValueChangeListener>(); - propertySetToListenerListMap.put(itemId, listenerList); - } - listenerList.add(listener); - } - } - - /** - * Removes a previously registered single Property change listener. - * - * @param propertyId - * the ID of the Property to remove. - * @param itemId - * the ID of the Item. - * @param listener - * the listener to be removed. - */ - private void removeSinglePropertyChangeListener(Object propertyId, - Object itemId, Property.ValueChangeListener listener) { - if (listener != null && singlePropertyValueChangeListeners != null) { - final Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(propertyId); - if (propertySetToListenerListMap != null) { - final List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap - .get(itemId); - if (listenerList != null) { - listenerList.remove(listener); - if (listenerList.isEmpty()) { - propertySetToListenerListMap.remove(itemId); - } - } - if (propertySetToListenerListMap.isEmpty()) { - singlePropertyValueChangeListeners.remove(propertyId); - } - } - if (singlePropertyValueChangeListeners.isEmpty()) { - singlePropertyValueChangeListeners = null; - } - } - } - - /* Internal Item and Property implementations */ - - /* - * A class implementing the com.vaadin.data.Item interface to be contained - * in the list. - * - * @author Vaadin Ltd. - * - * @version @VERSION@ - * - * @since 3.0 - */ - class IndexedContainerItem implements Item { - - /** - * Item ID in the host container for this Item. - */ - private final Object itemId; - - /** - * Constructs a new ListItem instance and connects it to a host - * container. - * - * @param itemId - * the Item ID of the new Item. - */ - private IndexedContainerItem(Object itemId) { - - // Gets the item contents from the host - if (itemId == null) { - throw new NullPointerException(); - } - this.itemId = itemId; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Item#getItemProperty(java.lang.Object) - */ - @Override - public Property<?> getItemProperty(Object id) { - return new IndexedContainerProperty(itemId, id); - } - - @Override - public Collection<?> getItemPropertyIds() { - return Collections.unmodifiableCollection(propertyIds); - } - - /** - * Gets the <code>String</code> representation of the contents of the - * Item. The format of the string is a space separated catenation of the - * <code>String</code> representations of the values of the Properties - * contained by the Item. - * - * @return <code>String</code> representation of the Item contents - */ - @Override - public String toString() { - String retValue = ""; - - for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) { - final Object propertyId = i.next(); - retValue += getItemProperty(propertyId).getValue(); - if (i.hasNext()) { - retValue += " "; - } - } - - return retValue; - } - - /** - * Calculates a integer hash-code for the Item that's unique inside the - * list. Two Items inside the same list have always different - * hash-codes, though Items in different lists may have identical - * hash-codes. - * - * @return A locally unique hash-code as integer - */ - @Override - public int hashCode() { - return itemId.hashCode(); - } - - /** - * Tests if the given object is the same as the this object. Two Items - * got from a list container with the same ID are equal. - * - * @param obj - * an object to compare with this object - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (obj == null - || !obj.getClass().equals(IndexedContainerItem.class)) { - return false; - } - final IndexedContainerItem li = (IndexedContainerItem) obj; - return getHost() == li.getHost() && itemId.equals(li.itemId); - } - - private IndexedContainer getHost() { - return IndexedContainer.this; - } - - /** - * IndexedContainerItem does not support adding new properties. Add - * properties at container level. See - * {@link IndexedContainer#addContainerProperty(Object, Class, Object)} - * - * @see com.vaadin.data.Item#addProperty(Object, Property) - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException("Indexed container item " - + "does not support adding new properties"); - } - - /** - * Indexed container does not support removing properties. Remove - * properties at container level. See - * {@link IndexedContainer#removeContainerProperty(Object)} - * - * @see com.vaadin.data.Item#removeProperty(Object) - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException( - "Indexed container item does not support property removal"); - } - - } - - /** - * A class implementing the {@link Property} interface to be contained in - * the {@link IndexedContainerItem} contained in the - * {@link IndexedContainer}. - * - * @author Vaadin Ltd. - * - * @version - * @VERSION@ - * @since 3.0 - */ - private class IndexedContainerProperty implements Property<Object>, - Property.ValueChangeNotifier { - - /** - * ID of the Item, where this property resides. - */ - private final Object itemId; - - /** - * Id of the Property. - */ - private final Object propertyId; - - /** - * Constructs a new {@link IndexedContainerProperty} object. - * - * @param itemId - * the ID of the Item to connect the new Property to. - * @param propertyId - * the Property ID of the new Property. - * @param host - * the list that contains the Item to contain the new - * Property. - */ - private IndexedContainerProperty(Object itemId, Object propertyId) { - if (itemId == null || propertyId == null) { - // Null ids are not accepted - throw new NullPointerException( - "Container item or property ids can not be null"); - } - this.propertyId = propertyId; - this.itemId = itemId; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#getType() - */ - @Override - public Class<?> getType() { - return types.get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#getValue() - */ - @Override - public Object getValue() { - return items.get(itemId).get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#isReadOnly() - */ - @Override - public boolean isReadOnly() { - return readOnlyProperties.contains(this); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#setReadOnly(boolean) - */ - @Override - public void setReadOnly(boolean newStatus) { - if (newStatus) { - readOnlyProperties.add(this); - } else { - readOnlyProperties.remove(this); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#setValue(java.lang.Object) - */ - @Override - public void setValue(Object newValue) throws Property.ReadOnlyException { - // Gets the Property set - final Map<Object, Object> propertySet = items.get(itemId); - - // Support null values on all types - if (newValue == null) { - propertySet.remove(propertyId); - } else if (getType().isAssignableFrom(newValue.getClass())) { - propertySet.put(propertyId, newValue); - } else { - throw new IllegalArgumentException( - "Value is of invalid type, got " - + newValue.getClass().getName() + " but " - + getType().getName() + " was expected"); - } - - // update the container filtering if this property is being filtered - if (isPropertyFiltered(propertyId)) { - filterAll(); - } - - firePropertyValueChange(this); - } - - /** - * Returns the value of the Property in human readable textual format. - * The return value should be assignable to the <code>setValue</code> - * method if the Property is not in read-only mode. - * - * @return <code>String</code> representation of the value stored in the - * Property - * @deprecated use {@link #getValue()} instead and possibly toString on - * that - */ - @Deprecated - @Override - public String toString() { - throw new UnsupportedOperationException( - "Use Property.getValue() instead of IndexedContainerProperty.toString()"); - } - - /** - * Calculates a integer hash-code for the Property that's unique inside - * the Item containing the Property. Two different Properties inside the - * same Item contained in the same list always have different - * hash-codes, though Properties in different Items may have identical - * hash-codes. - * - * @return A locally unique hash-code as integer - */ - @Override - public int hashCode() { - return itemId.hashCode() ^ propertyId.hashCode(); - } - - /** - * Tests if the given object is the same as the this object. Two - * Properties got from an Item with the same ID are equal. - * - * @param obj - * an object to compare with this object - * @return <code>true</code> if the given object is the same as this - * object, <code>false</code> if not - */ - @Override - public boolean equals(Object obj) { - if (obj == null - || !obj.getClass().equals(IndexedContainerProperty.class)) { - return false; - } - final IndexedContainerProperty lp = (IndexedContainerProperty) obj; - return lp.getHost() == getHost() - && lp.propertyId.equals(propertyId) - && lp.itemId.equals(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#addListener( - * com.vaadin.data.Property.ValueChangeListener) - */ - @Override - public void addListener(Property.ValueChangeListener listener) { - addSinglePropertyChangeListener(propertyId, itemId, listener); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener - * (com.vaadin.data.Property.ValueChangeListener) - */ - @Override - public void removeListener(Property.ValueChangeListener listener) { - removeSinglePropertyChangeListener(propertyId, itemId, listener); - } - - private IndexedContainer getHost() { - return IndexedContainer.this; - } - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - sortContainer(propertyId, ascending); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds - * () - */ - @Override - public Collection<?> getSortableContainerPropertyIds() { - return getSortablePropertyIds(); - } - - @Override - public ItemSorter getItemSorter() { - return super.getItemSorter(); - } - - @Override - public void setItemSorter(ItemSorter itemSorter) { - super.setItemSorter(itemSorter); - } - - /** - * Supports cloning of the IndexedContainer cleanly. - * - * @throws CloneNotSupportedException - * if an object cannot be cloned. . - * - * @deprecated cloning support might be removed from IndexedContainer in the - * future - */ - @Deprecated - @Override - public Object clone() throws CloneNotSupportedException { - - // Creates the clone - final IndexedContainer nc = new IndexedContainer(); - - // Clone the shallow properties - nc.setAllItemIds(getAllItemIds() != null ? (ListSet<Object>) ((ListSet<Object>) getAllItemIds()) - .clone() : null); - nc.setItemSetChangeListeners(getItemSetChangeListeners() != null ? new LinkedList<Container.ItemSetChangeListener>( - getItemSetChangeListeners()) : null); - nc.propertyIds = propertyIds != null ? (ArrayList<Object>) propertyIds - .clone() : null; - nc.setPropertySetChangeListeners(getPropertySetChangeListeners() != null ? new LinkedList<Container.PropertySetChangeListener>( - getPropertySetChangeListeners()) : null); - nc.propertyValueChangeListeners = propertyValueChangeListeners != null ? (LinkedList<Property.ValueChangeListener>) propertyValueChangeListeners - .clone() : null; - nc.readOnlyProperties = readOnlyProperties != null ? (HashSet<Property<?>>) readOnlyProperties - .clone() : null; - nc.singlePropertyValueChangeListeners = singlePropertyValueChangeListeners != null ? (Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>) singlePropertyValueChangeListeners - .clone() : null; - - nc.types = types != null ? (Hashtable<Object, Class<?>>) types.clone() - : null; - - nc.setFilters((HashSet<Filter>) ((HashSet<Filter>) getFilters()) - .clone()); - - nc.setFilteredItemIds(getFilteredItemIds() == null ? null - : (ListSet<Object>) ((ListSet<Object>) getFilteredItemIds()) - .clone()); - - // Clone property-values - if (items == null) { - nc.items = null; - } else { - nc.items = new Hashtable<Object, Map<Object, Object>>(); - for (final Iterator<?> i = items.keySet().iterator(); i.hasNext();) { - final Object id = i.next(); - final Hashtable<Object, Object> it = (Hashtable<Object, Object>) items - .get(id); - nc.items.put(id, (Map<Object, Object>) it.clone()); - } - } - - return nc; - } - - @Override - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - try { - addFilter(new SimpleStringFilter(propertyId, filterString, - ignoreCase, onlyMatchPrefix)); - } catch (UnsupportedFilterException e) { - // the filter instance created here is always valid for in-memory - // containers - } - } - - @Override - public void removeAllContainerFilters() { - removeAllFilters(); - } - - @Override - public void removeContainerFilters(Object propertyId) { - removeFilters(propertyId); - } - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - addFilter(filter); - } - - @Override - public void removeContainerFilter(Filter filter) { - removeFilter(filter); - } - -} diff --git a/src/com/vaadin/data/util/ItemSorter.java b/src/com/vaadin/data/util/ItemSorter.java deleted file mode 100644 index 4399dbe292..0000000000 --- a/src/com/vaadin/data/util/ItemSorter.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.io.Serializable; -import java.util.Comparator; - -import com.vaadin.data.Container; -import com.vaadin.data.Container.Sortable; - -/** - * An item comparator which is compatible with the {@link Sortable} interface. - * The <code>ItemSorter</code> interface can be used in <code>Sortable</code> - * implementations to provide a custom sorting method. - */ -public interface ItemSorter extends Comparator<Object>, Cloneable, Serializable { - - /** - * Sets the parameters for an upcoming sort operation. The parameters - * determine what container to sort and how the <code>ItemSorter</code> - * sorts the container. - * - * @param container - * The container that will be sorted. The container must contain - * the propertyIds given in the <code>propertyId</code> - * parameter. - * @param propertyId - * The property ids used for sorting. The property ids must exist - * in the container and should only be used if they are also - * sortable, i.e include in the collection returned by - * <code>container.getSortableContainerPropertyIds()</code>. See - * {@link Sortable#sort(Object[], boolean[])} for more - * information. - * @param ascending - * Sorting order flags for each property id. See - * {@link Sortable#sort(Object[], boolean[])} for more - * information. - */ - void setSortProperties(Container.Sortable container, Object[] propertyId, - boolean[] ascending); - - /** - * Compares its two arguments for order. Returns a negative integer, zero, - * or a positive integer as the first argument is less than, equal to, or - * greater than the second. - * <p> - * The parameters for the <code>ItemSorter</code> <code>compare()</code> - * method must always be item ids which exist in the container set using - * {@link #setSortProperties(Sortable, Object[], boolean[])}. - * - * @see Comparator#compare(Object, Object) - */ - @Override - int compare(Object itemId1, Object itemId2); - -} diff --git a/src/com/vaadin/data/util/ListSet.java b/src/com/vaadin/data/util/ListSet.java deleted file mode 100644 index b71cc46898..0000000000 --- a/src/com/vaadin/data/util/ListSet.java +++ /dev/null @@ -1,264 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; - -/** - * ListSet is an internal Vaadin class which implements a combination of a List - * and a Set. The main purpose of this class is to provide a list with a fast - * {@link #contains(Object)} method. Each inserted object must by unique (as - * specified by {@link #equals(Object)}). The {@link #set(int, Object)} method - * allows duplicates because of the way {@link Collections#sort(java.util.List)} - * works. - * - * This class is subject to change and should not be used outside Vaadin core. - */ -public class ListSet<E> extends ArrayList<E> { - private HashSet<E> itemSet = null; - - /** - * Contains a map from an element to the number of duplicates it has. Used - * to temporarily allow duplicates in the list. - */ - private HashMap<E, Integer> duplicates = new HashMap<E, Integer>(); - - public ListSet() { - super(); - itemSet = new HashSet<E>(); - } - - public ListSet(Collection<? extends E> c) { - super(c); - itemSet = new HashSet<E>(c.size()); - itemSet.addAll(c); - } - - public ListSet(int initialCapacity) { - super(initialCapacity); - itemSet = new HashSet<E>(initialCapacity); - } - - // Delegate contains operations to the set - @Override - public boolean contains(Object o) { - return itemSet.contains(o); - } - - @Override - public boolean containsAll(Collection<?> c) { - return itemSet.containsAll(c); - } - - // Methods for updating the set when the list is updated. - @Override - public boolean add(E e) { - if (contains(e)) { - // Duplicates are not allowed - return false; - } - - if (super.add(e)) { - itemSet.add(e); - return true; - } else { - return false; - } - }; - - /** - * Works as java.util.ArrayList#add(int, java.lang.Object) but returns - * immediately if the element is already in the ListSet. - */ - @Override - public void add(int index, E element) { - if (contains(element)) { - // Duplicates are not allowed - return; - } - - super.add(index, element); - itemSet.add(element); - } - - @Override - public boolean addAll(Collection<? extends E> c) { - boolean modified = false; - Iterator<? extends E> i = c.iterator(); - while (i.hasNext()) { - E e = i.next(); - if (contains(e)) { - continue; - } - - if (add(e)) { - itemSet.add(e); - modified = true; - } - } - return modified; - } - - @Override - public boolean addAll(int index, Collection<? extends E> c) { - ensureCapacity(size() + c.size()); - - boolean modified = false; - Iterator<? extends E> i = c.iterator(); - while (i.hasNext()) { - E e = i.next(); - if (contains(e)) { - continue; - } - - add(index++, e); - itemSet.add(e); - modified = true; - } - - return modified; - } - - @Override - public void clear() { - super.clear(); - itemSet.clear(); - } - - @Override - public int indexOf(Object o) { - if (!contains(o)) { - return -1; - } - - return super.indexOf(o); - } - - @Override - public int lastIndexOf(Object o) { - if (!contains(o)) { - return -1; - } - - return super.lastIndexOf(o); - } - - @Override - public E remove(int index) { - E e = super.remove(index); - - if (e != null) { - itemSet.remove(e); - } - - return e; - } - - @Override - public boolean remove(Object o) { - if (super.remove(o)) { - itemSet.remove(o); - return true; - } else { - return false; - } - } - - @Override - protected void removeRange(int fromIndex, int toIndex) { - HashSet<E> toRemove = new HashSet<E>(); - for (int idx = fromIndex; idx < toIndex; idx++) { - toRemove.add(get(idx)); - } - super.removeRange(fromIndex, toIndex); - itemSet.removeAll(toRemove); - } - - @Override - public E set(int index, E element) { - if (contains(element)) { - // Element already exist in the list - if (get(index) == element) { - // At the same position, nothing to be done - return element; - } else { - // Adding at another position. We assume this is a sort - // operation and temporarily allow it. - - // We could just remove (null) the old element and keep the list - // unique. This would require finding the index of the old - // element (indexOf(element)) which is not a fast operation in a - // list. So we instead allow duplicates temporarily. - addDuplicate(element); - } - } - - E old = super.set(index, element); - removeFromSet(old); - itemSet.add(element); - - return old; - } - - /** - * Removes "e" from the set if it no longer exists in the list. - * - * @param e - */ - private void removeFromSet(E e) { - Integer dupl = duplicates.get(e); - if (dupl != null) { - // A duplicate was present so we only decrement the duplicate count - // and continue - if (dupl == 1) { - // This is what always should happen. A sort sets the items one - // by one, temporarily breaking the uniqueness requirement. - duplicates.remove(e); - } else { - duplicates.put(e, dupl - 1); - } - } else { - // The "old" value is no longer in the list. - itemSet.remove(e); - } - - } - - /** - * Marks the "element" can be found more than once from the list. Allowed in - * {@link #set(int, Object)} to make sorting work. - * - * @param element - */ - private void addDuplicate(E element) { - Integer nr = duplicates.get(element); - if (nr == null) { - nr = 1; - } else { - nr++; - } - - /* - * Store the number of duplicates of this element so we know later on if - * we should remove an element from the set or if it was a duplicate (in - * removeFromSet) - */ - duplicates.put(element, nr); - - } - - @SuppressWarnings("unchecked") - @Override - public Object clone() { - ListSet<E> v = (ListSet<E>) super.clone(); - v.itemSet = new HashSet<E>(itemSet); - return v; - } - -} diff --git a/src/com/vaadin/data/util/MethodProperty.java b/src/com/vaadin/data/util/MethodProperty.java deleted file mode 100644 index 0c64d90481..0000000000 --- a/src/com/vaadin/data/util/MethodProperty.java +++ /dev/null @@ -1,784 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -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; - -/** - * <p> - * Proxy class for creating Properties from pairs of getter and setter methods - * of a Bean property. An instance of this class can be thought as having been - * attached to a field of an object. Accessing the object through the Property - * interface directly manipulates the underlying field. - * </p> - * - * <p> - * It's assumed that the return value returned by the getter method is - * assignable to the type of the property, and the setter method parameter is - * assignable to that value. - * </p> - * - * <p> - * A valid getter method must always be available, but instance of this class - * can be constructed with a <code>null</code> setter method in which case the - * resulting MethodProperty is read-only. - * </p> - * - * <p> - * MethodProperty implements Property.ValueChangeNotifier, but does not - * automatically know whether or not the getter method will actually return a - * new value - value change listeners are always notified when setValue is - * called, without verifying what the getter returns. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class MethodProperty<T> extends AbstractProperty<T> { - - /** - * The object that includes the property the MethodProperty is bound to. - */ - private transient Object instance; - - /** - * Argument arrays for the getter and setter methods. - */ - private transient Object[] setArgs, getArgs; - - /** - * The getter and setter methods. - */ - private transient Method setMethod, getMethod; - - /** - * Index of the new value in the argument list for the setter method. If the - * setter method requires several parameters, this index tells which one is - * the actual value to change. - */ - private int setArgumentIndex; - - /** - * Type of the property. - */ - private transient Class<? extends T> type; - - /* Special serialization to handle method references */ - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - SerializerHelper.writeClass(out, type); - out.writeObject(instance); - out.writeObject(setArgs); - out.writeObject(getArgs); - if (setMethod != null) { - out.writeObject(setMethod.getName()); - SerializerHelper - .writeClassArray(out, setMethod.getParameterTypes()); - } else { - out.writeObject(null); - out.writeObject(null); - } - if (getMethod != null) { - out.writeObject(getMethod.getName()); - SerializerHelper - .writeClassArray(out, getMethod.getParameterTypes()); - } else { - 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<T> class1 = (Class<T>) SerializerHelper.readClass(in); - type = class1; - instance = in.readObject(); - setArgs = (Object[]) in.readObject(); - getArgs = (Object[]) in.readObject(); - String name = (String) in.readObject(); - Class<?>[] paramTypes = SerializerHelper.readClassArray(in); - if (name != null) { - setMethod = instance.getClass().getMethod(name, paramTypes); - } else { - setMethod = null; - } - - name = (String) in.readObject(); - paramTypes = SerializerHelper.readClassArray(in); - if (name != null) { - getMethod = instance.getClass().getMethod(name, paramTypes); - } else { - getMethod = null; - } - } catch (SecurityException e) { - getLogger().log(Level.SEVERE, "Internal deserialization error", e); - } catch (NoSuchMethodException e) { - getLogger().log(Level.SEVERE, "Internal deserialization error", e); - } - }; - - /** - * <p> - * Creates a new instance of <code>MethodProperty</code> from a named bean - * property. This constructor takes an object and the name of a bean - * property and initializes itself with the accessor methods for the - * property. - * </p> - * <p> - * The getter method of a <code>MethodProperty</code> instantiated with this - * constructor will be called with no arguments, and the setter method with - * only the new value as the sole argument. - * </p> - * - * <p> - * If the setter method is unavailable, the resulting - * <code>MethodProperty</code> will be read-only, otherwise it will be - * read-write. - * </p> - * - * <p> - * Method names are constructed from the bean property by adding - * get/is/are/set prefix and capitalising the first character in the name of - * the given bean property. - * </p> - * - * @param instance - * the object that includes the property. - * @param beanPropertyName - * the name of the property to bind to. - */ - @SuppressWarnings("unchecked") - public MethodProperty(Object instance, String beanPropertyName) { - - final Class<?> beanClass = instance.getClass(); - - // Assure that the first letter is upper cased (it is a common - // mistake to write firstName, not FirstName). - if (Character.isLowerCase(beanPropertyName.charAt(0))) { - final char[] buf = beanPropertyName.toCharArray(); - buf[0] = Character.toUpperCase(buf[0]); - beanPropertyName = new String(buf); - } - - // Find the get method - getMethod = null; - try { - getMethod = initGetterMethod(beanPropertyName, beanClass); - } catch (final java.lang.NoSuchMethodException ignored) { - throw new MethodException(this, "Bean property " + beanPropertyName - + " can not be found"); - } - - // In case the get method is found, resolve the type - Class<?> returnType = getMethod.getReturnType(); - - // Finds the set method - setMethod = null; - try { - setMethod = beanClass.getMethod("set" + beanPropertyName, - new Class[] { returnType }); - } catch (final java.lang.NoSuchMethodException skipped) { - } - - // Gets the return type from get method - if (returnType.isPrimitive()) { - type = (Class<T>) convertPrimitiveType(returnType); - if (type.isPrimitive()) { - throw new MethodException(this, "Bean property " - + beanPropertyName - + " getter return type must not be void"); - } - } else { - type = (Class<T>) returnType; - } - - setArguments(new Object[] {}, new Object[] { null }, 0); - this.instance = instance; - } - - /** - * <p> - * Creates a new instance of <code>MethodProperty</code> from named getter - * and setter methods. The getter method of a <code>MethodProperty</code> - * instantiated with this constructor will be called with no arguments, and - * the setter method with only the new value as the sole argument. - * </p> - * - * <p> - * If the setter method is <code>null</code>, the resulting - * <code>MethodProperty</code> will be read-only, otherwise it will be - * read-write. - * </p> - * - * @param type - * the type of the property. - * @param instance - * the object that includes the property. - * @param getMethodName - * the name of the getter method. - * @param setMethodName - * the name of the setter method. - * - */ - public MethodProperty(Class<? extends T> type, Object instance, - String getMethodName, String setMethodName) { - this(type, instance, getMethodName, setMethodName, new Object[] {}, - new Object[] { null }, 0); - } - - /** - * <p> - * Creates a new instance of <code>MethodProperty</code> with the getter and - * setter methods. The getter method of a <code>MethodProperty</code> - * instantiated with this constructor will be called with no arguments, and - * the setter method with only the new value as the sole argument. - * </p> - * - * <p> - * If the setter method is <code>null</code>, the resulting - * <code>MethodProperty</code> will be read-only, otherwise it will be - * read-write. - * </p> - * - * @param type - * the type of the property. - * @param instance - * the object that includes the property. - * @param getMethod - * the getter method. - * @param setMethod - * the setter method. - */ - public MethodProperty(Class<? extends T> type, Object instance, - Method getMethod, Method setMethod) { - this(type, instance, getMethod, setMethod, new Object[] {}, - new Object[] { null }, 0); - } - - /** - * <p> - * Creates a new instance of <code>MethodProperty</code> from named getter - * and setter methods and argument lists. The getter method of a - * <code>MethodProperty</code> instantiated with this constructor will be - * called with the getArgs as arguments. The setArgs will be used as the - * arguments for the setter method, though the argument indexed by the - * setArgumentIndex will be replaced with the argument passed to the - * {@link #setValue(Object newValue)} method. - * </p> - * - * <p> - * For example, if the <code>setArgs</code> contains <code>A</code>, - * <code>B</code> and <code>C</code>, and <code>setArgumentIndex = - * 1</code>, the call <code>methodProperty.setValue(X)</code> would result - * in the setter method to be called with the parameter set of - * <code>{A, X, C}</code> - * </p> - * - * @param type - * the type of the property. - * @param instance - * the object that includes the property. - * @param getMethodName - * the name of the getter method. - * @param setMethodName - * the name of the setter method. - * @param getArgs - * the fixed argument list to be passed to the getter method. - * @param setArgs - * the fixed argument list to be passed to the setter method. - * @param setArgumentIndex - * the index of the argument in <code>setArgs</code> to be - * replaced with <code>newValue</code> when - * {@link #setValue(Object newValue)} is called. - */ - @SuppressWarnings("unchecked") - public MethodProperty(Class<? extends T> type, Object instance, - String getMethodName, String setMethodName, Object[] getArgs, - Object[] setArgs, int setArgumentIndex) { - - // Check the setargs and setargs index - if (setMethodName != null && setArgs == null) { - throw new IndexOutOfBoundsException("The setArgs can not be null"); - } - if (setMethodName != null - && (setArgumentIndex < 0 || setArgumentIndex >= setArgs.length)) { - throw new IndexOutOfBoundsException( - "The setArgumentIndex must be >= 0 and < setArgs.length"); - } - - // Set type - this.type = type; - - // Find set and get -methods - final Method[] m = instance.getClass().getMethods(); - - // Finds get method - boolean found = false; - for (int i = 0; i < m.length; i++) { - - // Tests the name of the get Method - if (!m[i].getName().equals(getMethodName)) { - - // name does not match, try next method - continue; - } - - // Tests return type - if (!type.equals(m[i].getReturnType())) { - continue; - } - - // Tests the parameter types - final Class<?>[] c = m[i].getParameterTypes(); - if (c.length != getArgs.length) { - - // not the right amount of parameters, try next method - continue; - } - int j = 0; - while (j < c.length) { - if (getArgs[j] != null - && !c[j].isAssignableFrom(getArgs[j].getClass())) { - - // parameter type does not match, try next method - break; - } - j++; - } - if (j == c.length) { - - // all paramteters matched - if (found == true) { - throw new MethodException(this, - "Could not uniquely identify " + getMethodName - + "-method"); - } else { - found = true; - getMethod = m[i]; - } - } - } - if (found != true) { - throw new MethodException(this, "Could not find " + getMethodName - + "-method"); - } - - // Finds set method - if (setMethodName != null) { - - // Finds setMethod - found = false; - for (int i = 0; i < m.length; i++) { - - // Checks name - if (!m[i].getName().equals(setMethodName)) { - - // name does not match, try next method - continue; - } - - // Checks parameter compatibility - final Class<?>[] c = m[i].getParameterTypes(); - if (c.length != setArgs.length) { - - // not the right amount of parameters, try next method - continue; - } - int j = 0; - while (j < c.length) { - if (setArgs[j] != null - && !c[j].isAssignableFrom(setArgs[j].getClass())) { - - // parameter type does not match, try next method - break; - } else if (j == setArgumentIndex && !c[j].equals(type)) { - - // Property type is not the same as setArg type - break; - } - j++; - } - if (j == c.length) { - - // all parameters match - if (found == true) { - throw new MethodException(this, - "Could not identify unique " + setMethodName - + "-method"); - } else { - found = true; - setMethod = m[i]; - } - } - } - if (found != true) { - throw new MethodException(this, "Could not identify " - + setMethodName + "-method"); - } - } - - // Gets the return type from get method - this.type = (Class<T>) convertPrimitiveType(type); - - setArguments(getArgs, setArgs, setArgumentIndex); - this.instance = instance; - } - - /** - * <p> - * Creates a new instance of <code>MethodProperty</code> from the getter and - * setter methods, and argument lists. - * </p> - * <p> - * This constructor behaves exactly like - * {@link #MethodProperty(Class type, Object instance, String getMethodName, String setMethodName, Object [] getArgs, Object [] setArgs, int setArgumentIndex)} - * except that instead of names of the getter and setter methods this - * constructor is given the actual methods themselves. - * </p> - * - * @param type - * the type of the property. - * @param instance - * the object that includes the property. - * @param getMethod - * the getter method. - * @param setMethod - * the setter method. - * @param getArgs - * the fixed argument list to be passed to the getter method. - * @param setArgs - * the fixed argument list to be passed to the setter method. - * @param setArgumentIndex - * the index of the argument in <code>setArgs</code> to be - * replaced with <code>newValue</code> when - * {@link #setValue(Object newValue)} is called. - */ - @SuppressWarnings("unchecked") - // cannot use "Class<? extends T>" because of automatic primitive type - // conversions - public MethodProperty(Class<?> type, Object instance, Method getMethod, - Method setMethod, Object[] getArgs, Object[] setArgs, - int setArgumentIndex) { - - if (getMethod == null) { - throw new MethodException(this, - "Property GET-method cannot not be null: " + type); - } - - if (setMethod != null) { - if (setArgs == null) { - throw new IndexOutOfBoundsException( - "The setArgs can not be null"); - } - if (setArgumentIndex < 0 || setArgumentIndex >= setArgs.length) { - throw new IndexOutOfBoundsException( - "The setArgumentIndex must be >= 0 and < setArgs.length"); - } - } - - // Gets the return type from get method - Class<? extends T> convertedType = (Class<? extends T>) convertPrimitiveType(type); - - this.getMethod = getMethod; - this.setMethod = setMethod; - setArguments(getArgs, setArgs, setArgumentIndex); - this.instance = instance; - this.type = convertedType; - } - - /** - * Find a getter method for a property (getXyz(), isXyz() or areXyz()). - * - * @param propertyName - * name of the property - * @param beanClass - * class in which to look for the getter methods - * @return Method - * @throws NoSuchMethodException - * if no getter found - */ - static Method initGetterMethod(String propertyName, final Class<?> beanClass) - throws NoSuchMethodException { - propertyName = propertyName.substring(0, 1).toUpperCase() - + propertyName.substring(1); - - Method getMethod = null; - try { - getMethod = beanClass.getMethod("get" + propertyName, - new Class[] {}); - } catch (final java.lang.NoSuchMethodException ignored) { - try { - getMethod = beanClass.getMethod("is" + propertyName, - new Class[] {}); - } catch (final java.lang.NoSuchMethodException ignoredAsWell) { - getMethod = beanClass.getMethod("are" + propertyName, - new Class[] {}); - } - } - return getMethod; - } - - static Class<?> convertPrimitiveType(Class<?> type) { - // Gets the return type from get method - if (type.isPrimitive()) { - if (type.equals(Boolean.TYPE)) { - type = Boolean.class; - } else if (type.equals(Integer.TYPE)) { - type = Integer.class; - } else if (type.equals(Float.TYPE)) { - type = Float.class; - } else if (type.equals(Double.TYPE)) { - type = Double.class; - } else if (type.equals(Byte.TYPE)) { - type = Byte.class; - } else if (type.equals(Character.TYPE)) { - type = Character.class; - } else if (type.equals(Short.TYPE)) { - type = Short.class; - } else if (type.equals(Long.TYPE)) { - type = Long.class; - } - } - return type; - } - - /** - * Returns the type of the Property. The methods <code>getValue</code> and - * <code>setValue</code> must be compatible with this type: one must be able - * to safely cast the value returned from <code>getValue</code> to the given - * type and pass any variable assignable to this type as an argument to - * <code>setValue</code>. - * - * @return type of the Property - */ - @Override - public final Class<? extends T> getType() { - return type; - } - - /** - * Tests if the object is in read-only mode. In read-only mode calls to - * <code>setValue</code> will throw <code>ReadOnlyException</code> and will - * not modify the value of the Property. - * - * @return <code>true</code> if the object is in read-only mode, - * <code>false</code> if it's not - */ - @Override - public boolean isReadOnly() { - return super.isReadOnly() || (setMethod == null); - } - - /** - * Gets the value stored in the Property. The value is resolved by calling - * the specified getter method with the argument specified at instantiation. - * - * @return the value of the Property - */ - @Override - public T getValue() { - try { - return (T) getMethod.invoke(instance, getArgs); - } catch (final Throwable e) { - throw new MethodException(this, e); - } - } - - /** - * <p> - * Sets the setter method and getter method argument lists. - * </p> - * - * @param getArgs - * the fixed argument list to be passed to the getter method. - * @param setArgs - * the fixed argument list to be passed to the setter method. - * @param setArgumentIndex - * the index of the argument in <code>setArgs</code> to be - * replaced with <code>newValue</code> when - * {@link #setValue(Object newValue)} is called. - */ - public void setArguments(Object[] getArgs, Object[] setArgs, - int setArgumentIndex) { - this.getArgs = new Object[getArgs.length]; - for (int i = 0; i < getArgs.length; i++) { - this.getArgs[i] = getArgs[i]; - } - this.setArgs = new Object[setArgs.length]; - for (int i = 0; i < setArgs.length; i++) { - this.setArgs[i] = setArgs[i]; - } - this.setArgumentIndex = setArgumentIndex; - } - - /** - * Sets the value of the property. - * - * Note that since Vaadin 7, no conversions are performed and the value must - * be of the correct type. - * - * @param newValue - * the New value of the property. - * @throws <code>Property.ReadOnlyException</code> if the object is in - * read-only mode. - * @see #invokeSetMethod(Object) - */ - @Override - @SuppressWarnings("unchecked") - public void setValue(Object newValue) throws Property.ReadOnlyException { - - // Checks the mode - if (isReadOnly()) { - throw new Property.ReadOnlyException(); - } - - // Checks the type of the value - if (newValue != null && !type.isAssignableFrom(newValue.getClass())) { - throw new IllegalArgumentException( - "Invalid value type for ObjectProperty."); - } - - invokeSetMethod((T) newValue); - fireValueChange(); - } - - /** - * Internal method to actually call the setter method of the wrapped - * property. - * - * @param value - */ - protected void invokeSetMethod(T value) { - - try { - // Construct a temporary argument array only if needed - if (setArgs.length == 1) { - setMethod.invoke(instance, new Object[] { value }); - } else { - - // Sets the value to argument array - final Object[] args = new Object[setArgs.length]; - for (int i = 0; i < setArgs.length; i++) { - args[i] = (i == setArgumentIndex) ? value : setArgs[i]; - } - setMethod.invoke(instance, args); - } - } catch (final InvocationTargetException e) { - final Throwable targetException = e.getTargetException(); - throw new MethodException(this, targetException); - } catch (final Exception e) { - throw new MethodException(this, e); - } - } - - /** - * <code>Exception</code> object that signals that there were problems - * calling or finding the specified getter or setter methods of the - * property. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - @SuppressWarnings("rawtypes") - // Exceptions cannot be parameterized, ever. - public static class MethodException extends RuntimeException { - - /** - * The method property from which the exception originates from - */ - private final Property property; - - /** - * Cause of the method exception - */ - private Throwable cause; - - /** - * Constructs a new <code>MethodException</code> with the specified - * detail message. - * - * @param property - * the property. - * @param msg - * the detail message. - */ - public MethodException(Property property, String msg) { - super(msg); - this.property = property; - } - - /** - * Constructs a new <code>MethodException</code> from another exception. - * - * @param property - * the property. - * @param cause - * the cause of the exception. - */ - public MethodException(Property property, Throwable cause) { - this.property = property; - this.cause = cause; - } - - /** - * @see java.lang.Throwable#getCause() - */ - @Override - public Throwable getCause() { - return cause; - } - - /** - * Gets the method property this exception originates from. - * - * @return MethodProperty or null if not a valid MethodProperty - */ - public MethodProperty getMethodProperty() { - return (property instanceof MethodProperty) ? (MethodProperty) property - : null; - } - - /** - * Gets the method property this exception originates from. - * - * @return Property from which the exception originates - */ - public Property getProperty() { - return property; - } - } - - /** - * Sends a value change event to all registered listeners. - * - * Public for backwards compatibility, visibility may be reduced in future - * versions. - */ - @Override - public void fireValueChange() { - super.fireValueChange(); - } - - private static final Logger getLogger() { - return Logger.getLogger(MethodProperty.class.getName()); - } -} diff --git a/src/com/vaadin/data/util/MethodPropertyDescriptor.java b/src/com/vaadin/data/util/MethodPropertyDescriptor.java deleted file mode 100644 index a2a76ec6cf..0000000000 --- a/src/com/vaadin/data/util/MethodPropertyDescriptor.java +++ /dev/null @@ -1,134 +0,0 @@ -/* -@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()); - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/NestedMethodProperty.java b/src/com/vaadin/data/util/NestedMethodProperty.java deleted file mode 100644 index 9bff38456d..0000000000 --- a/src/com/vaadin/data/util/NestedMethodProperty.java +++ /dev/null @@ -1,257 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.vaadin.data.Property; -import com.vaadin.data.util.MethodProperty.MethodException; - -/** - * Nested accessor based property for a bean. - * - * The property is specified in the dotted notation, e.g. "address.street", and - * can contain multiple levels of nesting. - * - * When accessing the property value, all intermediate getters must return - * non-null values. - * - * @see MethodProperty - * - * @since 6.6 - */ -public class NestedMethodProperty<T> extends AbstractProperty<T> { - - // needed for de-serialization - private String propertyName; - - // chain of getter methods - private transient List<Method> getMethods; - /** - * The setter method. - */ - private transient Method setMethod; - - /** - * Bean instance used as a starting point for accessing the property value. - */ - private Object instance; - - private Class<? extends T> type; - - /* Special serialization to handle method references */ - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - // getMethods and setMethod are reconstructed on read based on - // propertyName - } - - /* Special serialization to handle method references */ - private void readObject(java.io.ObjectInputStream in) throws IOException, - ClassNotFoundException { - in.defaultReadObject(); - - initialize(instance.getClass(), propertyName); - } - - /** - * Constructs a nested method property for a given object instance. The - * property name is a dot separated string pointing to a nested property, - * e.g. "manager.address.street". - * - * @param instance - * top-level bean to which the property applies - * @param propertyName - * dot separated nested property name - * @throws IllegalArgumentException - * if the property name is invalid - */ - public NestedMethodProperty(Object instance, String propertyName) { - this.instance = instance; - initialize(instance.getClass(), propertyName); - } - - /** - * For internal use to deduce property type etc. without a bean instance. - * Calling {@link #setValue(Object)} or {@link #getValue()} on properties - * constructed this way is not supported. - * - * @param instanceClass - * class of the top-level bean - * @param propertyName - */ - NestedMethodProperty(Class<?> instanceClass, String propertyName) { - instance = null; - initialize(instanceClass, propertyName); - } - - /** - * Initializes most of the internal fields based on the top-level bean - * instance and property name (dot-separated string). - * - * @param beanClass - * class of the top-level bean to which the property applies - * @param propertyName - * dot separated nested property name - * @throws IllegalArgumentException - * if the property name is invalid - */ - private void initialize(Class<?> beanClass, String propertyName) - throws IllegalArgumentException { - - List<Method> getMethods = new ArrayList<Method>(); - - String lastSimplePropertyName = propertyName; - Class<?> lastClass = beanClass; - - // first top-level property, then go deeper in a loop - Class<?> propertyClass = beanClass; - String[] simplePropertyNames = propertyName.split("\\."); - if (propertyName.endsWith(".") || 0 == simplePropertyNames.length) { - throw new IllegalArgumentException("Invalid property name '" - + propertyName + "'"); - } - for (int i = 0; i < simplePropertyNames.length; i++) { - String simplePropertyName = simplePropertyNames[i].trim(); - if (simplePropertyName.length() > 0) { - lastSimplePropertyName = simplePropertyName; - lastClass = propertyClass; - try { - Method getter = MethodProperty.initGetterMethod( - simplePropertyName, propertyClass); - propertyClass = getter.getReturnType(); - getMethods.add(getter); - } catch (final java.lang.NoSuchMethodException e) { - throw new IllegalArgumentException("Bean property '" - + simplePropertyName + "' not found", e); - } - } else { - throw new IllegalArgumentException( - "Empty or invalid bean property identifier in '" - + propertyName + "'"); - } - } - - // In case the get method is found, resolve the type - Method lastGetMethod = getMethods.get(getMethods.size() - 1); - Class<?> type = lastGetMethod.getReturnType(); - - // Finds the set method - Method setMethod = null; - try { - // Assure that the first letter is upper cased (it is a common - // mistake to write firstName, not FirstName). - if (Character.isLowerCase(lastSimplePropertyName.charAt(0))) { - final char[] buf = lastSimplePropertyName.toCharArray(); - buf[0] = Character.toUpperCase(buf[0]); - lastSimplePropertyName = new String(buf); - } - - setMethod = lastClass.getMethod("set" + lastSimplePropertyName, - new Class[] { type }); - } catch (final NoSuchMethodException skipped) { - } - - this.type = (Class<? extends T>) MethodProperty - .convertPrimitiveType(type); - this.propertyName = propertyName; - this.getMethods = getMethods; - this.setMethod = setMethod; - } - - @Override - public Class<? extends T> getType() { - return type; - } - - @Override - public boolean isReadOnly() { - return super.isReadOnly() || (null == setMethod); - } - - /** - * Gets the value stored in the Property. The value is resolved by calling - * the specified getter method with the argument specified at instantiation. - * - * @return the value of the Property - */ - @Override - public T getValue() { - try { - Object object = instance; - for (Method m : getMethods) { - object = m.invoke(object); - } - return (T) object; - } catch (final Throwable e) { - throw new MethodException(this, e); - } - } - - /** - * Sets the value of the property. The new value must be assignable to the - * type of this property. - * - * @param newValue - * the New value of the property. - * @throws <code>Property.ReadOnlyException</code> if the object is in - * read-only mode. - * @see #invokeSetMethod(Object) - */ - @Override - public void setValue(Object newValue) throws ReadOnlyException { - // Checks the mode - if (isReadOnly()) { - throw new Property.ReadOnlyException(); - } - - // Checks the type of the value - if (newValue != null && !type.isAssignableFrom(newValue.getClass())) { - throw new IllegalArgumentException( - "Invalid value type for NestedMethodProperty."); - } - - invokeSetMethod((T) newValue); - fireValueChange(); - } - - /** - * Internal method to actually call the setter method of the wrapped - * property. - * - * @param value - */ - protected void invokeSetMethod(T value) { - try { - Object object = instance; - for (int i = 0; i < getMethods.size() - 1; i++) { - object = getMethods.get(i).invoke(object); - } - setMethod.invoke(object, new Object[] { value }); - } catch (final InvocationTargetException e) { - throw new MethodException(this, e.getTargetException()); - } catch (final Exception e) { - throw new MethodException(this, e); - } - } - - /** - * Returns an unmodifiable list of getter methods to call in sequence to get - * the property value. - * - * This API may change in future versions. - * - * @return unmodifiable list of getter methods corresponding to each segment - * of the property name - */ - protected List<Method> getGetMethods() { - return Collections.unmodifiableList(getMethods); - } - -} diff --git a/src/com/vaadin/data/util/NestedPropertyDescriptor.java b/src/com/vaadin/data/util/NestedPropertyDescriptor.java deleted file mode 100644 index b67b425d1d..0000000000 --- a/src/com/vaadin/data/util/NestedPropertyDescriptor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import com.vaadin.data.Property; - -/** - * Property descriptor that is able to create nested property instances for a - * bean. - * - * The property is specified in the dotted notation, e.g. "address.street", and - * can contain multiple levels of nesting. - * - * @param <BT> - * bean type - * - * @since 6.6 - */ -public class NestedPropertyDescriptor<BT> implements - VaadinPropertyDescriptor<BT> { - - private final String name; - private final Class<?> propertyType; - - /** - * Creates a property descriptor that can create MethodProperty instances to - * access the underlying bean property. - * - * @param name - * of the property in a dotted path format, e.g. "address.street" - * @param beanType - * type (class) of the top-level bean - * @throws IllegalArgumentException - * if the property name is invalid - */ - public NestedPropertyDescriptor(String name, Class<BT> beanType) - throws IllegalArgumentException { - this.name = name; - NestedMethodProperty<?> property = new NestedMethodProperty<Object>( - beanType, name); - this.propertyType = property.getType(); - } - - @Override - public String getName() { - return name; - } - - @Override - public Class<?> getPropertyType() { - return propertyType; - } - - @Override - public Property<?> createProperty(BT bean) { - return new NestedMethodProperty<Object>(bean, name); - } - -} diff --git a/src/com/vaadin/data/util/ObjectProperty.java b/src/com/vaadin/data/util/ObjectProperty.java deleted file mode 100644 index cb85b44c2a..0000000000 --- a/src/com/vaadin/data/util/ObjectProperty.java +++ /dev/null @@ -1,141 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import com.vaadin.data.Property; - -/** - * A simple data object containing one typed value. This class is a - * straightforward implementation of the the {@link com.vaadin.data.Property} - * interface. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class ObjectProperty<T> extends AbstractProperty<T> { - - /** - * The value contained by the Property. - */ - private T value; - - /** - * Data type of the Property's value. - */ - private final Class<T> type; - - /** - * Creates a new instance of ObjectProperty with the given value. The type - * of the property is automatically initialized to be the type of the given - * value. - * - * @param value - * the Initial value of the Property. - */ - @SuppressWarnings("unchecked") - // the cast is safe, because an object of type T has class Class<T> - public ObjectProperty(T value) { - this(value, (Class<T>) value.getClass()); - } - - /** - * Creates a new instance of ObjectProperty with the given value and type. - * - * Since Vaadin 7, only values of the correct type are accepted, and no - * automatic conversions are performed. - * - * @param value - * the Initial value of the Property. - * @param type - * the type of the value. The value must be assignable to given - * type. - */ - public ObjectProperty(T value, Class<T> type) { - - // Set the values - this.type = type; - setValue(value); - } - - /** - * Creates a new instance of ObjectProperty with the given value, type and - * read-only mode status. - * - * Since Vaadin 7, only the correct type of values is accepted, see - * {@link #ObjectProperty(Object, Class)}. - * - * @param value - * the Initial value of the property. - * @param type - * the type of the value. <code>value</code> must be assignable - * to this type. - * @param readOnly - * Sets the read-only mode. - */ - public ObjectProperty(T value, Class<T> type, boolean readOnly) { - this(value, type); - setReadOnly(readOnly); - } - - /** - * Returns the type of the ObjectProperty. The methods <code>getValue</code> - * and <code>setValue</code> must be compatible with this type: one must be - * able to safely cast the value returned from <code>getValue</code> to the - * given type and pass any variable assignable to this type as an argument - * to <code>setValue</code>. - * - * @return type of the Property - */ - @Override - public final Class<T> getType() { - return type; - } - - /** - * Gets the value stored in the Property. - * - * @return the value stored in the Property - */ - @Override - public T getValue() { - return value; - } - - /** - * Sets the value of the property. - * - * Note that since Vaadin 7, no conversions are performed and the value must - * be of the correct type. - * - * @param newValue - * the New value of the property. - * @throws <code>Property.ReadOnlyException</code> if the object is in - * read-only mode - */ - @Override - @SuppressWarnings("unchecked") - public void setValue(Object newValue) throws Property.ReadOnlyException { - - // Checks the mode - if (isReadOnly()) { - throw new Property.ReadOnlyException(); - } - - // Checks the type of the value - if (newValue != null && !type.isAssignableFrom(newValue.getClass())) { - throw new IllegalArgumentException("Invalid value type " - + newValue.getClass().getName() - + " for ObjectProperty of type " + type.getName() + "."); - } - - // the cast is safe after an isAssignableFrom check - this.value = (T) newValue; - - fireValueChange(); - } -} diff --git a/src/com/vaadin/data/util/PropertyFormatter.java b/src/com/vaadin/data/util/PropertyFormatter.java deleted file mode 100644 index 3d65726309..0000000000 --- a/src/com/vaadin/data/util/PropertyFormatter.java +++ /dev/null @@ -1,245 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import com.vaadin.data.Property; -import com.vaadin.data.util.converter.Converter; - -/** - * Formatting proxy for a {@link Property}. - * - * <p> - * This class can be used to implement formatting for any type of Property - * datasources. The idea is to connect this as proxy between UI component and - * the original datasource. - * </p> - * - * <p> - * For example <code> - * <pre>textfield.setPropertyDataSource(new PropertyFormatter(property) { - public String format(Object value) { - return ((Double) value).toString() + "000000000"; - } - - public Object parse(String formattedValue) throws Exception { - return Double.parseDouble(formattedValue); - } - - });</pre></code> adds formatter for Double-typed property that extends - * standard "1.0" notation with more zeroes. - * </p> - * - * @param T - * type of the underlying property (a PropertyFormatter is always a - * Property<String>) - * - * @deprecated Since 7.0 replaced by {@link Converter} - * @author Vaadin Ltd. - * @since 5.3.0 - */ -@SuppressWarnings("serial") -@Deprecated -public abstract class PropertyFormatter<T> extends AbstractProperty<String> - implements Property.Viewer, Property.ValueChangeListener, - Property.ReadOnlyStatusChangeListener { - - /** Datasource that stores the actual value. */ - Property<T> dataSource; - - /** - * Construct a new {@code PropertyFormatter} that is not connected to any - * data source. Call {@link #setPropertyDataSource(Property)} later on to - * attach it to a property. - * - */ - protected PropertyFormatter() { - } - - /** - * Construct a new formatter that is connected to given data source. Calls - * {@link #format(Object)} which can be a problem if the formatter has not - * yet been initialized. - * - * @param propertyDataSource - * to connect this property to. - */ - public PropertyFormatter(Property<T> propertyDataSource) { - - setPropertyDataSource(propertyDataSource); - } - - /** - * Gets the current data source of the formatter, if any. - * - * @return the current data source as a Property, or <code>null</code> if - * none defined. - */ - @Override - public Property<T> getPropertyDataSource() { - return dataSource; - } - - /** - * Sets the specified Property as the data source for the formatter. - * - * - * <p> - * Remember that new data sources getValue() must return objects that are - * compatible with parse() and format() methods. - * </p> - * - * @param newDataSource - * the new data source Property. - */ - @Override - public void setPropertyDataSource(Property newDataSource) { - - boolean readOnly = false; - String prevValue = null; - - if (dataSource != null) { - if (dataSource instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) dataSource) - .removeListener(this); - } - if (dataSource instanceof Property.ReadOnlyStatusChangeListener) { - ((Property.ReadOnlyStatusChangeNotifier) dataSource) - .removeListener(this); - } - readOnly = isReadOnly(); - prevValue = getValue(); - } - - dataSource = newDataSource; - - if (dataSource != null) { - if (dataSource instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) dataSource).addListener(this); - } - if (dataSource instanceof Property.ReadOnlyStatusChangeListener) { - ((Property.ReadOnlyStatusChangeNotifier) dataSource) - .addListener(this); - } - } - - if (isReadOnly() != readOnly) { - fireReadOnlyStatusChange(); - } - String newVal = getValue(); - if ((prevValue == null && newVal != null) - || (prevValue != null && !prevValue.equals(newVal))) { - fireValueChange(); - } - } - - /* Documented in the interface */ - @Override - public Class<String> getType() { - return String.class; - } - - /** - * Get the formatted value. - * - * @return If the datasource returns null, this is null. Otherwise this is - * String given by format(). - */ - @Override - public String getValue() { - T value = dataSource == null ? null : dataSource.getValue(); - if (value == null) { - return null; - } - return format(value); - } - - /** Reflects the read-only status of the datasource. */ - @Override - public boolean isReadOnly() { - return dataSource == null ? false : dataSource.isReadOnly(); - } - - /** - * This method must be implemented to format the values received from - * DataSource. - * - * @param value - * Value object got from the datasource. This is guaranteed to be - * non-null and of the type compatible with getType() of the - * datasource. - * @return - */ - abstract public String format(T value); - - /** - * Parse string and convert it to format compatible with datasource. - * - * The method is required to assure that parse(format(x)) equals x. - * - * @param formattedValue - * This is guaranteed to be non-null string. - * @return Non-null value compatible with datasource. - * @throws Exception - * Any type of exception can be thrown to indicate that the - * conversion was not succesful. - */ - abstract public T parse(String formattedValue) throws Exception; - - /** - * Sets the Property's read-only mode to the specified status. - * - * @param newStatus - * the new read-only status of the Property. - */ - @Override - public void setReadOnly(boolean newStatus) { - if (dataSource != null) { - dataSource.setReadOnly(newStatus); - } - } - - @Override - public void setValue(Object newValue) throws ReadOnlyException { - if (dataSource == null) { - return; - } - if (newValue == null) { - if (dataSource.getValue() != null) { - dataSource.setValue(null); - fireValueChange(); - } - } else { - try { - dataSource.setValue(parse(newValue.toString())); - if (!newValue.equals(getValue())) { - fireValueChange(); - } - } catch (Exception e) { - throw new IllegalArgumentException("Could not parse value", e); - } - } - } - - /** - * Listens for changes in the datasource. - * - * This should not be called directly. - */ - @Override - public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) { - fireValueChange(); - } - - /** - * Listens for changes in the datasource. - * - * This should not be called directly. - */ - @Override - public void readOnlyStatusChange( - com.vaadin.data.Property.ReadOnlyStatusChangeEvent event) { - fireReadOnlyStatusChange(); - } - -} diff --git a/src/com/vaadin/data/util/PropertysetItem.java b/src/com/vaadin/data/util/PropertysetItem.java deleted file mode 100644 index 22f2da75b2..0000000000 --- a/src/com/vaadin/data/util/PropertysetItem.java +++ /dev/null @@ -1,340 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.util.Collection; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; - -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * Class for handling a set of identified Properties. The elements contained in - * a </code>MapItem</code> can be referenced using locally unique identifiers. - * The class supports listeners who are interested in changes to the Property - * set managed by the class. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class PropertysetItem implements Item, Item.PropertySetChangeNotifier, - Cloneable { - - /* Private representation of the item */ - - /** - * Mapping from property id to property. - */ - private HashMap<Object, Property<?>> map = new HashMap<Object, Property<?>>(); - - /** - * List of all property ids to maintain the order. - */ - private LinkedList<Object> list = new LinkedList<Object>(); - - /** - * List of property set modification listeners. - */ - private LinkedList<Item.PropertySetChangeListener> propertySetChangeListeners = null; - - /* Item methods */ - - /** - * Gets the Property corresponding to the given Property ID stored in the - * Item. If the Item does not contain the Property, <code>null</code> is - * returned. - * - * @param id - * the identifier of the Property to get. - * @return the Property with the given ID or <code>null</code> - */ - @Override - public Property<?> getItemProperty(Object id) { - return map.get(id); - } - - /** - * Gets the collection of IDs of all Properties stored in the Item. - * - * @return unmodifiable collection containing IDs of the Properties stored - * the Item - */ - @Override - public Collection<?> getItemPropertyIds() { - return Collections.unmodifiableCollection(list); - } - - /* Item.Managed methods */ - - /** - * Removes the Property identified by ID from the Item. This functionality - * is optional. If the method is not implemented, the method always returns - * <code>false</code>. - * - * @param id - * the ID of the Property to be removed. - * @return <code>true</code> if the operation succeeded <code>false</code> - * if not - */ - @Override - public boolean removeItemProperty(Object id) { - - // Cant remove missing properties - if (map.remove(id) == null) { - return false; - } - list.remove(id); - - // Send change events - fireItemPropertySetChange(); - - return true; - } - - /** - * Tries to add a new Property into the Item. - * - * @param id - * the ID of the new Property. - * @param property - * the Property to be added and associated with the id. - * @return <code>true</code> if the operation succeeded, <code>false</code> - * if not - */ - @Override - public boolean addItemProperty(Object id, Property property) { - - // Null ids are not accepted - if (id == null) { - throw new NullPointerException("Item property id can not be null"); - } - - // Cant add a property twice - if (map.containsKey(id)) { - return false; - } - - // Put the property to map - map.put(id, property); - list.add(id); - - // Send event - fireItemPropertySetChange(); - - return true; - } - - /** - * Gets the <code>String</code> representation of the contents of the Item. - * The format of the string is a space separated catenation of the - * <code>String</code> representations of the Properties contained by the - * Item. - * - * @return <code>String</code> representation of the Item contents - */ - @Override - public String toString() { - String retValue = ""; - - for (final Iterator<?> i = getItemPropertyIds().iterator(); i.hasNext();) { - final Object propertyId = i.next(); - retValue += getItemProperty(propertyId).getValue(); - if (i.hasNext()) { - retValue += " "; - } - } - - return retValue; - } - - /* Notifiers */ - - /** - * An <code>event</code> object specifying an Item whose Property set has - * changed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - private static class PropertySetChangeEvent extends EventObject implements - Item.PropertySetChangeEvent { - - private PropertySetChangeEvent(Item source) { - super(source); - } - - /** - * Gets the Item whose Property set has changed. - * - * @return source object of the event as an <code>Item</code> - */ - @Override - public Item getItem() { - return (Item) getSource(); - } - } - - /** - * Registers a new property set change listener for this Item. - * - * @param listener - * the new Listener to be registered. - */ - @Override - public void addListener(Item.PropertySetChangeListener listener) { - if (propertySetChangeListeners == null) { - propertySetChangeListeners = new LinkedList<PropertySetChangeListener>(); - } - propertySetChangeListeners.add(listener); - } - - /** - * Removes a previously registered property set change listener. - * - * @param listener - * the Listener to be removed. - */ - @Override - public void removeListener(Item.PropertySetChangeListener listener) { - if (propertySetChangeListeners != null) { - propertySetChangeListeners.remove(listener); - } - } - - /** - * Sends a Property set change event to all interested listeners. - */ - private void fireItemPropertySetChange() { - if (propertySetChangeListeners != null) { - final Object[] l = propertySetChangeListeners.toArray(); - final Item.PropertySetChangeEvent event = new PropertysetItem.PropertySetChangeEvent( - this); - for (int i = 0; i < l.length; i++) { - ((Item.PropertySetChangeListener) l[i]) - .itemPropertySetChange(event); - } - } - } - - public Collection<?> getListeners(Class<?> eventType) { - if (Item.PropertySetChangeEvent.class.isAssignableFrom(eventType)) { - if (propertySetChangeListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertySetChangeListeners); - } - } - - return Collections.EMPTY_LIST; - } - - /** - * Creates and returns a copy of this object. - * <p> - * The method <code>clone</code> performs a shallow copy of the - * <code>PropertysetItem</code>. - * </p> - * <p> - * Note : All arrays are considered to implement the interface Cloneable. - * Otherwise, this method creates a new instance of the class of this object - * and initializes all its fields with exactly the contents of the - * corresponding fields of this object, as if by assignment, the contents of - * the fields are not themselves cloned. Thus, this method performs a - * "shallow copy" of this object, not a "deep copy" operation. - * </p> - * - * @throws CloneNotSupportedException - * if the object's class does not support the Cloneable - * interface. - * - * @see java.lang.Object#clone() - */ - @Override - public Object clone() throws CloneNotSupportedException { - - final PropertysetItem npsi = new PropertysetItem(); - - npsi.list = list != null ? (LinkedList<Object>) list.clone() : null; - npsi.propertySetChangeListeners = propertySetChangeListeners != null ? (LinkedList<PropertySetChangeListener>) propertySetChangeListeners - .clone() : null; - npsi.map = (HashMap<Object, Property<?>>) map.clone(); - - return npsi; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - - if (obj == null || !(obj instanceof PropertysetItem)) { - return false; - } - - final PropertysetItem other = (PropertysetItem) obj; - - if (other.list != list) { - if (other.list == null) { - return false; - } - if (!other.list.equals(list)) { - return false; - } - } - if (other.map != map) { - if (other.map == null) { - return false; - } - if (!other.map.equals(map)) { - return false; - } - } - if (other.propertySetChangeListeners != propertySetChangeListeners) { - boolean thisEmpty = (propertySetChangeListeners == null || propertySetChangeListeners - .isEmpty()); - boolean otherEmpty = (other.propertySetChangeListeners == null || other.propertySetChangeListeners - .isEmpty()); - if (thisEmpty && otherEmpty) { - return true; - } - if (otherEmpty) { - return false; - } - if (!other.propertySetChangeListeners - .equals(propertySetChangeListeners)) { - return false; - } - } - - return true; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - - return (list == null ? 0 : list.hashCode()) - ^ (map == null ? 0 : map.hashCode()) - ^ ((propertySetChangeListeners == null || propertySetChangeListeners - .isEmpty()) ? 0 : propertySetChangeListeners.hashCode()); - } -} diff --git a/src/com/vaadin/data/util/QueryContainer.java b/src/com/vaadin/data/util/QueryContainer.java deleted file mode 100644 index dc7c883a7e..0000000000 --- a/src/com/vaadin/data/util/QueryContainer.java +++ /dev/null @@ -1,675 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * <p> - * The <code>QueryContainer</code> is the specialized form of Container which is - * Ordered and Indexed. This is used to represent the contents of relational - * database tables accessed through the JDBC Connection in the Vaadin Table. - * This creates Items based on the queryStatement provided to the container. - * </p> - * - * <p> - * The <code>QueryContainer</code> can be visualized as a representation of a - * relational database table.Each Item in the container represents the row - * fetched by the query.All cells in a column have same data type and the data - * type information is retrieved from the metadata of the resultset. - * </p> - * - * <p> - * Note : If data in the tables gets modified, Container will not get reflected - * with the updates, we have to explicity invoke QueryContainer.refresh method. - * {@link com.vaadin.data.util.QueryContainer#refresh() refresh()} - * </p> - * - * @see com.vaadin.data.Container - * - * @author Vaadin Ltd. - * @version - * @since 4.0 - * - * @deprecated will be removed in the future, use the SQLContainer add-on - */ - -@Deprecated -@SuppressWarnings("serial") -public class QueryContainer implements Container, Container.Ordered, - Container.Indexed { - - // default ResultSet type - public static final int DEFAULT_RESULTSET_TYPE = ResultSet.TYPE_SCROLL_INSENSITIVE; - - // default ResultSet concurrency - public static final int DEFAULT_RESULTSET_CONCURRENCY = ResultSet.CONCUR_READ_ONLY; - - private int resultSetType = DEFAULT_RESULTSET_TYPE; - - private int resultSetConcurrency = DEFAULT_RESULTSET_CONCURRENCY; - - private final String queryStatement; - - private final Connection connection; - - private ResultSet result; - - private Collection<String> propertyIds; - - private final HashMap<String, Class<?>> propertyTypes = new HashMap<String, Class<?>>(); - - private int size = -1; - - private Statement statement; - - /** - * Constructs new <code>QueryContainer</code> with the specified - * <code>queryStatement</code>. - * - * @param queryStatement - * Database query - * @param connection - * Connection object - * @param resultSetType - * @param resultSetConcurrency - * @throws SQLException - * when database operation fails - */ - public QueryContainer(String queryStatement, Connection connection, - int resultSetType, int resultSetConcurrency) throws SQLException { - this.queryStatement = queryStatement; - this.connection = connection; - this.resultSetType = resultSetType; - this.resultSetConcurrency = resultSetConcurrency; - init(); - } - - /** - * Constructs new <code>QueryContainer</code> with the specified - * queryStatement using the default resultset type and default resultset - * concurrency. - * - * @param queryStatement - * Database query - * @param connection - * Connection object - * @see QueryContainer#DEFAULT_RESULTSET_TYPE - * @see QueryContainer#DEFAULT_RESULTSET_CONCURRENCY - * @throws SQLException - * when database operation fails - */ - public QueryContainer(String queryStatement, Connection connection) - throws SQLException { - this(queryStatement, connection, DEFAULT_RESULTSET_TYPE, - DEFAULT_RESULTSET_CONCURRENCY); - } - - /** - * Fills the Container with the items and properties. Invoked by the - * constructor. - * - * @throws SQLException - * when parameter initialization fails. - * @see QueryContainer#QueryContainer(String, Connection, int, int). - */ - private void init() throws SQLException { - refresh(); - ResultSetMetaData metadata; - metadata = result.getMetaData(); - final int count = metadata.getColumnCount(); - final ArrayList<String> list = new ArrayList<String>(count); - for (int i = 1; i <= count; i++) { - final String columnName = metadata.getColumnName(i); - list.add(columnName); - final Property<?> p = getContainerProperty(new Integer(1), - columnName); - propertyTypes.put(columnName, - p == null ? Object.class : p.getType()); - } - propertyIds = Collections.unmodifiableCollection(list); - } - - /** - * <p> - * Restores items in the container. This method will update the latest data - * to the container. - * </p> - * Note: This method should be used to update the container with the latest - * items. - * - * @throws SQLException - * when database operation fails - * - */ - - public void refresh() throws SQLException { - close(); - statement = connection.createStatement(resultSetType, - resultSetConcurrency); - result = statement.executeQuery(queryStatement); - result.last(); - size = result.getRow(); - } - - /** - * Releases and nullifies the <code>statement</code>. - * - * @throws SQLException - * when database operation fails - */ - - public void close() throws SQLException { - if (statement != null) { - statement.close(); - } - statement = null; - } - - /** - * Gets the Item with the given Item ID from the Container. - * - * @param id - * ID of the Item to retrieve - * @return Item Id. - */ - - @Override - public Item getItem(Object id) { - return new Row(id); - } - - /** - * Gets the collection of propertyId from the Container. - * - * @return Collection of Property ID. - */ - - @Override - public Collection<String> getContainerPropertyIds() { - return propertyIds; - } - - /** - * Gets an collection of all the item IDs in the container. - * - * @return collection of Item IDs - */ - @Override - public Collection<?> getItemIds() { - final Collection<Integer> c = new ArrayList<Integer>(size); - for (int i = 1; i <= size; i++) { - c.add(new Integer(i)); - } - return c; - } - - /** - * Gets the property identified by the given itemId and propertyId from the - * container. If the container does not contain the property - * <code>null</code> is returned. - * - * @param itemId - * ID of the Item which contains the Property - * @param propertyId - * ID of the Property to retrieve - * - * @return Property with the given ID if exists; <code>null</code> - * otherwise. - */ - - @Override - public synchronized Property<?> getContainerProperty(Object itemId, - Object propertyId) { - if (!(itemId instanceof Integer && propertyId instanceof String)) { - return null; - } - Object value; - try { - result.absolute(((Integer) itemId).intValue()); - value = result.getObject((String) propertyId); - } catch (final Exception e) { - return null; - } - - // Handle also null values from the database - return new ObjectProperty<Object>(value != null ? value - : new String("")); - } - - /** - * Gets the data type of all properties identified by the given type ID. - * - * @param id - * ID identifying the Properties - * - * @return data type of the Properties - */ - - @Override - public Class<?> getType(Object id) { - return propertyTypes.get(id); - } - - /** - * Gets the number of items in the container. - * - * @return the number of items in the container. - */ - @Override - public int size() { - return size; - } - - /** - * Tests if the list contains the specified Item. - * - * @param id - * ID the of Item to be tested. - * @return <code>true</code> if given id is in the container; - * <code>false</code> otherwise. - */ - @Override - public boolean containsId(Object id) { - if (!(id instanceof Integer)) { - return false; - } - final int i = ((Integer) id).intValue(); - if (i < 1) { - return false; - } - if (i > size) { - return false; - } - return true; - } - - /** - * Creates new Item with the given ID into the Container. - * - * @param itemId - * ID of the Item to be created. - * - * @return Created new Item, or <code>null</code> if it fails. - * - * @throws UnsupportedOperationException - * if the addItem method is not supported. - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Creates a new Item into the Container, and assign it an ID. - * - * @return ID of the newly created Item, or <code>null</code> if it fails. - * @throws UnsupportedOperationException - * if the addItem method is not supported. - */ - @Override - public Object addItem() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Removes the Item identified by ItemId from the Container. - * - * @param itemId - * ID of the Item to remove. - * @return <code>true</code> if the operation succeeded; <code>false</code> - * otherwise. - * @throws UnsupportedOperationException - * if the removeItem method is not supported. - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Adds new Property to all Items in the Container. - * - * @param propertyId - * ID of the Property - * @param type - * Data type of the new Property - * @param defaultValue - * The value all created Properties are initialized to. - * @return <code>true</code> if the operation succeeded; <code>false</code> - * otherwise. - * @throws UnsupportedOperationException - * if the addContainerProperty method is not supported. - */ - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Removes a Property specified by the given Property ID from the Container. - * - * @param propertyId - * ID of the Property to remove - * @return <code>true</code> if the operation succeeded; <code>false</code> - * otherwise. - * @throws UnsupportedOperationException - * if the removeContainerProperty method is not supported. - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Removes all Items from the Container. - * - * @return <code>true</code> if the operation succeeded; <code>false</code> - * otherwise. - * @throws UnsupportedOperationException - * if the removeAllItems method is not supported. - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Adds new item after the given item. - * - * @param previousItemId - * Id of the previous item in ordered container. - * @param newItemId - * Id of the new item to be added. - * @return Returns new item or <code>null</code> if the operation fails. - * @throws UnsupportedOperationException - * if the addItemAfter method is not supported. - */ - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Adds new item after the given item. - * - * @param previousItemId - * Id of the previous item in ordered container. - * @return Returns item id created new item or <code>null</code> if the - * operation fails. - * @throws UnsupportedOperationException - * if the addItemAfter method is not supported. - */ - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Returns id of first item in the Container. - * - * @return ID of the first Item in the list. - */ - @Override - public Object firstItemId() { - if (size < 1) { - return null; - } - return new Integer(1); - } - - /** - * Returns <code>true</code> if given id is first id at first index. - * - * @param id - * ID of an Item in the Container. - */ - @Override - public boolean isFirstId(Object id) { - return size > 0 && (id instanceof Integer) - && ((Integer) id).intValue() == 1; - } - - /** - * Returns <code>true</code> if given id is last id at last index. - * - * @param id - * ID of an Item in the Container - * - */ - @Override - public boolean isLastId(Object id) { - return size > 0 && (id instanceof Integer) - && ((Integer) id).intValue() == size; - } - - /** - * Returns id of last item in the Container. - * - * @return ID of the last Item. - */ - @Override - public Object lastItemId() { - if (size < 1) { - return null; - } - return new Integer(size); - } - - /** - * Returns id of next item in container at next index. - * - * @param id - * ID of an Item in the Container. - * @return ID of the next Item or null. - */ - @Override - public Object nextItemId(Object id) { - if (size < 1 || !(id instanceof Integer)) { - return null; - } - final int i = ((Integer) id).intValue(); - if (i >= size) { - return null; - } - return new Integer(i + 1); - } - - /** - * Returns id of previous item in container at previous index. - * - * @param id - * ID of an Item in the Container. - * @return ID of the previous Item or null. - */ - @Override - public Object prevItemId(Object id) { - if (size < 1 || !(id instanceof Integer)) { - return null; - } - final int i = ((Integer) id).intValue(); - if (i <= 1) { - return null; - } - return new Integer(i - 1); - } - - /** - * The <code>Row</code> class implements methods of Item. - * - * @author Vaadin Ltd. - * @version - * @since 4.0 - */ - class Row implements Item { - - Object id; - - private Row(Object rowId) { - id = rowId; - } - - /** - * Adds the item property. - * - * @param id - * ID of the new Property. - * @param property - * Property to be added and associated with ID. - * @return <code>true</code> if the operation succeeded; - * <code>false</code> otherwise. - * @throws UnsupportedOperationException - * if the addItemProperty method is not supported. - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Gets the property corresponding to the given property ID stored in - * the Item. - * - * @param propertyId - * identifier of the Property to get - * @return the Property with the given ID or <code>null</code> - */ - @Override - public Property<?> getItemProperty(Object propertyId) { - return getContainerProperty(id, propertyId); - } - - /** - * Gets the collection of property IDs stored in the Item. - * - * @return unmodifiable collection containing IDs of the Properties - * stored the Item. - */ - @Override - public Collection<String> getItemPropertyIds() { - return propertyIds; - } - - /** - * Removes given item property. - * - * @param id - * ID of the Property to be removed. - * @return <code>true</code> if the item property is removed; - * <code>false</code> otherwise. - * @throws UnsupportedOperationException - * if the removeItemProperty is not supported. - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - } - - /** - * Closes the statement. - * - * @see #close() - */ - @Override - public void finalize() { - try { - close(); - } catch (final SQLException ignored) { - - } - } - - /** - * Adds the given item at the position of given index. - * - * @param index - * Index to add the new item. - * @param newItemId - * Id of the new item to be added. - * @return new item or <code>null</code> if the operation fails. - * @throws UnsupportedOperationException - * if the addItemAt is not supported. - */ - @Override - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Adds item at the position of provided index in the container. - * - * @param index - * Index to add the new item. - * @return item id created new item or <code>null</code> if the operation - * fails. - * - * @throws UnsupportedOperationException - * if the addItemAt is not supported. - */ - - @Override - public Object addItemAt(int index) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Gets the Index id in the container. - * - * @param index - * Index Id. - * @return ID in the given index. - */ - @Override - public Object getIdByIndex(int index) { - if (size < 1 || index < 0 || index >= size) { - return null; - } - return new Integer(index + 1); - } - - /** - * Gets the index of the Item corresponding to id in the container. - * - * @param id - * ID of an Item in the Container - * @return index of the Item, or -1 if the Container does not include the - * Item - */ - - @Override - public int indexOfId(Object id) { - if (size < 1 || !(id instanceof Integer)) { - return -1; - } - final int i = ((Integer) id).intValue(); - if (i >= size || i < 1) { - return -1; - } - return i - 1; - } - -} diff --git a/src/com/vaadin/data/util/TextFileProperty.java b/src/com/vaadin/data/util/TextFileProperty.java deleted file mode 100644 index 598b721a9c..0000000000 --- a/src/com/vaadin/data/util/TextFileProperty.java +++ /dev/null @@ -1,144 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; - -/** - * Property implementation for wrapping a text file. - * - * Supports reading and writing of a File from/to String. - * - * {@link ValueChangeListener}s are supported, but only fire when - * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s - * are supported but only fire when setReadOnly(boolean) is explicitly called. - * - */ -@SuppressWarnings("serial") -public class TextFileProperty extends AbstractProperty<String> { - - private File file; - private Charset charset = null; - - /** - * Wrap given file with property interface. - * - * Setting the file to null works, but getValue() will return null. - * - * @param file - * File to be wrapped. - */ - public TextFileProperty(File file) { - this.file = file; - } - - /** - * Wrap the given file with the property interface and specify character - * set. - * - * Setting the file to null works, but getValue() will return null. - * - * @param file - * File to be wrapped. - * @param charset - * Charset to be used for reading and writing the file. - */ - public TextFileProperty(File file, Charset charset) { - this.file = file; - this.charset = charset; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#getType() - */ - @Override - public Class<String> getType() { - return String.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#getValue() - */ - @Override - public String getValue() { - if (file == null) { - return null; - } - try { - FileInputStream fis = new FileInputStream(file); - InputStreamReader isr = charset == null ? new InputStreamReader(fis) - : new InputStreamReader(fis, charset); - BufferedReader r = new BufferedReader(isr); - StringBuilder b = new StringBuilder(); - char buf[] = new char[8 * 1024]; - int len; - while ((len = r.read(buf)) != -1) { - b.append(buf, 0, len); - } - r.close(); - isr.close(); - fis.close(); - return b.toString(); - } catch (FileNotFoundException e) { - return null; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#isReadOnly() - */ - @Override - public boolean isReadOnly() { - return file == null || super.isReadOnly() || !file.canWrite(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property#setValue(java.lang.Object) - */ - @Override - public void setValue(Object newValue) throws ReadOnlyException { - if (isReadOnly()) { - throw new ReadOnlyException(); - } - if (file == null) { - return; - } - - try { - FileOutputStream fos = new FileOutputStream(file); - OutputStreamWriter osw = charset == null ? new OutputStreamWriter( - fos) : new OutputStreamWriter(fos, charset); - BufferedWriter w = new BufferedWriter(osw); - w.append(newValue.toString()); - w.flush(); - w.close(); - osw.close(); - fos.close(); - fireValueChange(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java deleted file mode 100644 index d042bfaac2..0000000000 --- a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import com.vaadin.data.Property; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeNotifier; - -/** - * Wrapper class that helps implement two-phase commit for a non-transactional - * property. - * - * When accessing the property through the wrapper, getting and setting the - * property value take place immediately. However, the wrapper keeps track of - * the old value of the property so that it can be set for the property in case - * of a roll-back. This can result in the underlying property value changing - * multiple times (first based on modifications made by the application, then - * back upon roll-back). - * - * Value change events on the {@link TransactionalPropertyWrapper} are only - * fired at the end of a successful transaction, whereas listeners attached to - * the underlying property may receive multiple value change events. - * - * @see com.vaadin.data.Property.Transactional - * - * @author Vaadin Ltd - * @version @version@ - * @since 7.0 - * - * @param <T> - */ -public class TransactionalPropertyWrapper<T> extends AbstractProperty<T> - implements ValueChangeNotifier, Property.Transactional<T> { - - private Property<T> wrappedProperty; - private boolean inTransaction = false; - private boolean valueChangePending; - private T valueBeforeTransaction; - - public TransactionalPropertyWrapper(Property<T> wrappedProperty) { - this.wrappedProperty = wrappedProperty; - if (wrappedProperty instanceof ValueChangeNotifier) { - ((ValueChangeNotifier) wrappedProperty) - .addListener(new ValueChangeListener() { - - @Override - public void valueChange(ValueChangeEvent event) { - fireValueChange(); - } - }); - } - } - - @Override - public Class getType() { - return wrappedProperty.getType(); - } - - @Override - public T getValue() { - return wrappedProperty.getValue(); - } - - @Override - public void setValue(Object newValue) throws ReadOnlyException { - // Causes a value change to be sent to this listener which in turn fires - // a new value change event for this property - wrappedProperty.setValue(newValue); - } - - @Override - public void startTransaction() { - inTransaction = true; - valueBeforeTransaction = getValue(); - } - - @Override - public void commit() { - endTransaction(); - } - - @Override - public void rollback() { - try { - wrappedProperty.setValue(valueBeforeTransaction); - } finally { - valueChangePending = false; - endTransaction(); - } - } - - protected void endTransaction() { - inTransaction = false; - valueBeforeTransaction = null; - if (valueChangePending) { - fireValueChange(); - } - } - - @Override - protected void fireValueChange() { - if (inTransaction) { - valueChangePending = true; - } else { - super.fireValueChange(); - } - } - - public Property<T> getWrappedProperty() { - return wrappedProperty; - } - -} diff --git a/src/com/vaadin/data/util/VaadinPropertyDescriptor.java b/src/com/vaadin/data/util/VaadinPropertyDescriptor.java deleted file mode 100644 index ee1e525540..0000000000 --- a/src/com/vaadin/data/util/VaadinPropertyDescriptor.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util; - -import java.io.Serializable; - -import com.vaadin.data.Property; - -/** - * Property descriptor that can create a property instance for a bean. - * - * Used by {@link BeanItem} and {@link AbstractBeanContainer} to keep track of - * the set of properties of items. - * - * @param <BT> - * bean type - * - * @since 6.6 - */ -public interface VaadinPropertyDescriptor<BT> extends Serializable { - /** - * Returns the name of the property. - * - * @return - */ - public String getName(); - - /** - * Returns the type of the property. - * - * @return Class<?> - */ - public Class<?> getPropertyType(); - - /** - * Creates a new {@link Property} instance for this property for a bean. - * - * @param bean - * @return - */ - public Property<?> createProperty(BT bean); -} diff --git a/src/com/vaadin/data/util/converter/Converter.java b/src/com/vaadin/data/util/converter/Converter.java deleted file mode 100644 index b8c15e8cdc..0000000000 --- a/src/com/vaadin/data/util/converter/Converter.java +++ /dev/null @@ -1,159 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.io.Serializable; -import java.util.Locale; - -/** - * Interface that implements conversion between a model and a presentation type. - * <p> - * Typically {@link #convertToPresentation(Object, Locale)} and - * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining - * these together returns the original result for all input but this is not a - * requirement. - * </p> - * <p> - * Converters must not have any side effects (never update UI from inside a - * converter). - * </p> - * <p> - * All Converters must be stateless and thread safe. - * </p> - * <p> - * If conversion of a value fails, a {@link ConversionException} is thrown. - * </p> - * - * @param <MODEL> - * The model type. Must be compatible with what - * {@link #getModelType()} returns. - * @param <PRESENTATION> - * The presentation type. Must be compatible with what - * {@link #getPresentationType()} returns. - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - */ -public interface Converter<PRESENTATION, MODEL> extends Serializable { - - /** - * Converts the given value from target type to source type. - * <p> - * A converter can optionally use locale to do the conversion. - * </p> - * A converter should in most cases be symmetric so chaining - * {@link #convertToPresentation(Object, Locale)} and - * {@link #convertToModel(Object, Locale)} should return the original value. - * - * @param value - * The value to convert, compatible with the target type. Can be - * null - * @param locale - * The locale to use for conversion. Can be null. - * @return The converted value compatible with the source type - * @throws ConversionException - * If the value could not be converted - */ - public MODEL convertToModel(PRESENTATION value, Locale locale) - throws ConversionException; - - /** - * Converts the given value from source type to target type. - * <p> - * A converter can optionally use locale to do the conversion. - * </p> - * A converter should in most cases be symmetric so chaining - * {@link #convertToPresentation(Object, Locale)} and - * {@link #convertToModel(Object, Locale)} should return the original value. - * - * @param value - * The value to convert, compatible with the target type. Can be - * null - * @param locale - * The locale to use for conversion. Can be null. - * @return The converted value compatible with the source type - * @throws ConversionException - * If the value could not be converted - */ - public PRESENTATION convertToPresentation(MODEL value, Locale locale) - throws ConversionException; - - /** - * The source type of the converter. - * - * Values of this type can be passed to - * {@link #convertToPresentation(Object, Locale)}. - * - * @return The source type - */ - public Class<MODEL> getModelType(); - - /** - * The target type of the converter. - * - * Values of this type can be passed to - * {@link #convertToModel(Object, Locale)}. - * - * @return The target type - */ - public Class<PRESENTATION> getPresentationType(); - - /** - * An exception that signals that the value passed to - * {@link Converter#convertToPresentation(Object, Locale)} or - * {@link Converter#convertToModel(Object, Locale)} could not be converted. - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ - public static class ConversionException extends RuntimeException { - - /** - * Constructs a new <code>ConversionException</code> without a detail - * message. - */ - public ConversionException() { - } - - /** - * Constructs a new <code>ConversionException</code> with the specified - * detail message. - * - * @param msg - * the detail message - */ - public ConversionException(String msg) { - super(msg); - } - - /** - * Constructs a new {@code ConversionException} with the specified - * cause. - * - * @param cause - * The cause of the the exception - */ - public ConversionException(Throwable cause) { - super(cause); - } - - /** - * Constructs a new <code>ConversionException</code> with the specified - * detail message and cause. - * - * @param message - * the detail message - * @param cause - * The cause of the the exception - */ - public ConversionException(String message, Throwable cause) { - super(message, cause); - } - } - -} diff --git a/src/com/vaadin/data/util/converter/ConverterFactory.java b/src/com/vaadin/data/util/converter/ConverterFactory.java deleted file mode 100644 index ed4ab41ac0..0000000000 --- a/src/com/vaadin/data/util/converter/ConverterFactory.java +++ /dev/null @@ -1,23 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.io.Serializable; - -/** - * Factory interface for providing Converters based on a presentation type and a - * model type. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - * - */ -public interface ConverterFactory extends Serializable { - public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter( - Class<PRESENTATION> presentationType, Class<MODEL> modelType); - -} diff --git a/src/com/vaadin/data/util/converter/ConverterUtil.java b/src/com/vaadin/data/util/converter/ConverterUtil.java deleted file mode 100644 index 7011496ed7..0000000000 --- a/src/com/vaadin/data/util/converter/ConverterUtil.java +++ /dev/null @@ -1,168 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.converter; - -import java.io.Serializable; -import java.util.Locale; - -import com.vaadin.Application; - -public class ConverterUtil implements Serializable { - - /** - * Finds a converter that can convert from the given presentation type to - * the given model type and back. Uses the given application to find a - * {@link ConverterFactory} or, if application is null, uses the - * {@link Application#getCurrent()}. - * - * @param <PRESENTATIONTYPE> - * The presentation type - * @param <MODELTYPE> - * The model type - * @param presentationType - * The presentation type - * @param modelType - * The model type - * @param application - * The application to use to find a ConverterFactory or null to - * use the current application - * @return A Converter capable of converting between the given types or null - * if no converter was found - */ - public static <PRESENTATIONTYPE, MODELTYPE> Converter<PRESENTATIONTYPE, MODELTYPE> getConverter( - Class<PRESENTATIONTYPE> presentationType, - Class<MODELTYPE> modelType, Application application) { - Converter<PRESENTATIONTYPE, MODELTYPE> converter = null; - if (application == null) { - application = Application.getCurrent(); - } - - if (application != null) { - ConverterFactory factory = application.getConverterFactory(); - converter = factory.createConverter(presentationType, modelType); - } - return converter; - - } - - /** - * Convert the given value from the data source type to the UI type. - * - * @param modelValue - * The model value to convert - * @param presentationType - * The type of the presentation value - * @param converter - * The converter to (try to) use - * @param locale - * The locale to use for conversion - * @param <PRESENTATIONTYPE> - * Presentation type - * - * @return The converted value, compatible with the presentation type, or - * the original value if its type is compatible and no converter is - * set. - * @throws Converter.ConversionException - * if there is no converter and the type is not compatible with - * the model type. - */ - @SuppressWarnings("unchecked") - public static <PRESENTATIONTYPE, MODELTYPE> PRESENTATIONTYPE convertFromModel( - MODELTYPE modelValue, - Class<? extends PRESENTATIONTYPE> presentationType, - Converter<PRESENTATIONTYPE, MODELTYPE> converter, Locale locale) - throws Converter.ConversionException { - if (converter != null) { - return converter.convertToPresentation(modelValue, locale); - } - if (modelValue == null) { - return null; - } - - if (presentationType.isAssignableFrom(modelValue.getClass())) { - return (PRESENTATIONTYPE) modelValue; - } else { - throw new Converter.ConversionException( - "Unable to convert value of type " - + modelValue.getClass().getName() - + " to presentation type " - + presentationType - + ". No converter is set and the types are not compatible."); - } - } - - /** - * @param <MODELTYPE> - * @param <PRESENTATIONTYPE> - * @param presentationValue - * @param modelType - * @param converter - * @param locale - * @return - * @throws Converter.ConversionException - */ - public static <MODELTYPE, PRESENTATIONTYPE> MODELTYPE convertToModel( - PRESENTATIONTYPE presentationValue, Class<MODELTYPE> modelType, - Converter<PRESENTATIONTYPE, MODELTYPE> converter, Locale locale) - throws Converter.ConversionException { - if (converter != null) { - /* - * If there is a converter, always use it. It must convert or throw - * an exception. - */ - return converter.convertToModel(presentationValue, locale); - } - - if (presentationValue == null) { - // Null should always be passed through the converter but if there - // is no converter we can safely return null - return null; - } - - if (modelType == null) { - // No model type, return original value - return (MODELTYPE) presentationValue; - } else if (modelType.isAssignableFrom(presentationValue.getClass())) { - // presentation type directly compatible with model type - return modelType.cast(presentationValue); - } else { - throw new Converter.ConversionException( - "Unable to convert value of type " - + presentationValue.getClass().getName() - + " to model type " - + modelType - + ". No converter is set and the types are not compatible."); - } - - } - - /** - * Checks if the given converter can handle conversion between the given - * presentation and model type - * - * @param converter - * The converter to check - * @param presentationType - * The presentation type - * @param modelType - * The model type - * @return true if the converter supports conversion between the given - * presentation and model type, false otherwise - */ - public static boolean canConverterHandle(Converter<?, ?> converter, - Class<?> presentationType, Class<?> modelType) { - if (converter == null) { - return false; - } - - if (!modelType.isAssignableFrom(converter.getModelType())) { - return false; - } - if (!presentationType.isAssignableFrom(converter.getPresentationType())) { - return false; - } - - return true; - } -} diff --git a/src/com/vaadin/data/util/converter/DateToLongConverter.java b/src/com/vaadin/data/util/converter/DateToLongConverter.java deleted file mode 100644 index aeba38aa1f..0000000000 --- a/src/com/vaadin/data/util/converter/DateToLongConverter.java +++ /dev/null @@ -1,72 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.util.Date; -import java.util.Locale; - -/** - * A converter that converts from {@link Long} to {@link Date} and back. - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class DateToLongConverter implements Converter<Date, Long> { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, - * java.util.Locale) - */ - @Override - public Long convertToModel(Date value, Locale locale) { - if (value == null) { - return null; - } - - return value.getTime(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang - * .Object, java.util.Locale) - */ - @Override - public Date convertToPresentation(Long value, Locale locale) { - if (value == null) { - return null; - } - - return new Date(value); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getModelType() - */ - @Override - public Class<Long> getModelType() { - return Long.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class<Date> getPresentationType() { - return Date.class; - } - -} diff --git a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java deleted file mode 100644 index afb95d81ed..0000000000 --- a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java +++ /dev/null @@ -1,101 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.util.Date; -import java.util.logging.Logger; - -import com.vaadin.Application; - -/** - * Default implementation of {@link ConverterFactory}. Provides converters for - * standard types like {@link String}, {@link Double} and {@link Date}. </p> - * <p> - * Custom converters can be provided by extending this class and using - * {@link Application#setConverterFactory(ConverterFactory)}. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class DefaultConverterFactory implements ConverterFactory { - - private final static Logger log = Logger - .getLogger(DefaultConverterFactory.class.getName()); - - @Override - public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter( - Class<PRESENTATION> presentationType, Class<MODEL> modelType) { - Converter<PRESENTATION, MODEL> converter = findConverter( - presentationType, modelType); - if (converter != null) { - log.finest(getClass().getName() + " created a " - + converter.getClass()); - return converter; - } - - // Try to find a reverse converter - Converter<MODEL, PRESENTATION> reverseConverter = findConverter( - modelType, presentationType); - if (reverseConverter != null) { - log.finest(getClass().getName() + " created a reverse " - + reverseConverter.getClass()); - return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter); - } - - log.finest(getClass().getName() + " could not find a converter for " - + presentationType.getName() + " to " + modelType.getName() - + " conversion"); - return null; - - } - - protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter( - Class<PRESENTATION> presentationType, Class<MODEL> modelType) { - if (presentationType == String.class) { - // TextField converters and more - Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType); - if (converter != null) { - return converter; - } - } else if (presentationType == Date.class) { - // DateField converters and more - Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType); - if (converter != null) { - return converter; - } - } - - return null; - - } - - protected Converter<Date, ?> createDateConverter(Class<?> sourceType) { - if (Long.class.isAssignableFrom(sourceType)) { - return new DateToLongConverter(); - } else { - return null; - } - } - - protected Converter<String, ?> createStringConverter(Class<?> sourceType) { - if (Double.class.isAssignableFrom(sourceType)) { - return new StringToDoubleConverter(); - } else if (Integer.class.isAssignableFrom(sourceType)) { - return new StringToIntegerConverter(); - } else if (Boolean.class.isAssignableFrom(sourceType)) { - return new StringToBooleanConverter(); - } else if (Number.class.isAssignableFrom(sourceType)) { - return new StringToNumberConverter(); - } else if (Date.class.isAssignableFrom(sourceType)) { - return new StringToDateConverter(); - } else { - return null; - } - } - -} diff --git a/src/com/vaadin/data/util/converter/ReverseConverter.java b/src/com/vaadin/data/util/converter/ReverseConverter.java deleted file mode 100644 index fa1bb5daf1..0000000000 --- a/src/com/vaadin/data/util/converter/ReverseConverter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.util.Locale; - -/** - * A converter that wraps another {@link Converter} and reverses source and - * target types. - * - * @param <MODEL> - * The source type - * @param <PRESENTATION> - * The target type - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class ReverseConverter<PRESENTATION, MODEL> implements - Converter<PRESENTATION, MODEL> { - - private Converter<MODEL, PRESENTATION> realConverter; - - /** - * Creates a converter from source to target based on a converter that - * converts from target to source. - * - * @param converter - * The converter to use in a reverse fashion - */ - public ReverseConverter(Converter<MODEL, PRESENTATION> converter) { - this.realConverter = converter; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#convertToModel(java - * .lang.Object, java.util.Locale) - */ - @Override - public MODEL convertToModel(PRESENTATION value, Locale locale) - throws com.vaadin.data.util.converter.Converter.ConversionException { - return realConverter.convertToPresentation(value, locale); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang - * .Object, java.util.Locale) - */ - @Override - public PRESENTATION convertToPresentation(MODEL value, Locale locale) - throws com.vaadin.data.util.converter.Converter.ConversionException { - return realConverter.convertToModel(value, locale); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getSourceType() - */ - @Override - public Class<MODEL> getModelType() { - return realConverter.getPresentationType(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getTargetType() - */ - @Override - public Class<PRESENTATION> getPresentationType() { - return realConverter.getModelType(); - } - -} diff --git a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java deleted file mode 100644 index 999f575dc4..0000000000 --- a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java +++ /dev/null @@ -1,108 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.util.Locale; - -/** - * A converter that converts from {@link String} to {@link Boolean} and back. - * The String representation is given by Boolean.toString(). - * <p> - * Leading and trailing white spaces are ignored when converting from a String. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToBooleanConverter implements Converter<String, Boolean> { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, - * java.util.Locale) - */ - @Override - public Boolean convertToModel(String value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - // Remove leading and trailing white space - value = value.trim(); - - if (getTrueString().equals(value)) { - return true; - } else if (getFalseString().equals(value)) { - return false; - } else { - throw new ConversionException("Cannot convert " + value + " to " - + getModelType().getName()); - } - } - - /** - * Gets the string representation for true. Default is "true". - * - * @return the string representation for true - */ - protected String getTrueString() { - return Boolean.TRUE.toString(); - } - - /** - * Gets the string representation for false. Default is "false". - * - * @return the string representation for false - */ - protected String getFalseString() { - return Boolean.FALSE.toString(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang - * .Object, java.util.Locale) - */ - @Override - public String convertToPresentation(Boolean value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - if (value) { - return getTrueString(); - } else { - return getFalseString(); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getModelType() - */ - @Override - public Class<Boolean> getModelType() { - return Boolean.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class<String> getPresentationType() { - return String.class; - } - -} diff --git a/src/com/vaadin/data/util/converter/StringToDateConverter.java b/src/com/vaadin/data/util/converter/StringToDateConverter.java deleted file mode 100644 index 487b02b2aa..0000000000 --- a/src/com/vaadin/data/util/converter/StringToDateConverter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.text.DateFormat; -import java.text.ParsePosition; -import java.util.Date; -import java.util.Locale; - -/** - * A converter that converts from {@link Date} to {@link String} and back. Uses - * the given locale and {@link DateFormat} for formatting and parsing. - * <p> - * Leading and trailing white spaces are ignored when converting from a String. - * </p> - * <p> - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToDateConverter implements Converter<String, Date> { - - /** - * Returns the format used by {@link #convertToPresentation(Date, Locale)} - * and {@link #convertToModel(String, Locale)}. - * - * @param locale - * The locale to use - * @return A DateFormat instance - */ - protected DateFormat getFormat(Locale locale) { - if (locale == null) { - locale = Locale.getDefault(); - } - - DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, - DateFormat.MEDIUM, locale); - f.setLenient(false); - return f; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, - * java.util.Locale) - */ - @Override - public Date convertToModel(String value, Locale locale) - throws com.vaadin.data.util.converter.Converter.ConversionException { - if (value == null) { - return null; - } - - // Remove leading and trailing white space - value = value.trim(); - - ParsePosition parsePosition = new ParsePosition(0); - Date parsedValue = getFormat(locale).parse(value, parsePosition); - if (parsePosition.getIndex() != value.length()) { - throw new ConversionException("Could not convert '" + value - + "' to " + getModelType().getName()); - } - - return parsedValue; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang - * .Object, java.util.Locale) - */ - @Override - public String convertToPresentation(Date value, Locale locale) - throws com.vaadin.data.util.converter.Converter.ConversionException { - if (value == null) { - return null; - } - - return getFormat(locale).format(value); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getModelType() - */ - @Override - public Class<Date> getModelType() { - return Date.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class<String> getPresentationType() { - return String.class; - } - -} diff --git a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java deleted file mode 100644 index 251f91855b..0000000000 --- a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java +++ /dev/null @@ -1,107 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.text.NumberFormat; -import java.text.ParsePosition; -import java.util.Locale; - -/** - * A converter that converts from {@link String} to {@link Double} and back. - * Uses the given locale and a {@link NumberFormat} instance for formatting and - * parsing. - * <p> - * Leading and trailing white spaces are ignored when converting from a String. - * </p> - * <p> - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToDoubleConverter implements Converter<String, Double> { - - /** - * Returns the format used by {@link #convertToPresentation(Double, Locale)} - * and {@link #convertToModel(String, Locale)}. - * - * @param locale - * The locale to use - * @return A NumberFormat instance - */ - protected NumberFormat getFormat(Locale locale) { - if (locale == null) { - locale = Locale.getDefault(); - } - - return NumberFormat.getNumberInstance(locale); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, - * java.util.Locale) - */ - @Override - public Double convertToModel(String value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - // Remove leading and trailing white space - value = value.trim(); - - ParsePosition parsePosition = new ParsePosition(0); - Number parsedValue = getFormat(locale).parse(value, parsePosition); - if (parsePosition.getIndex() != value.length()) { - throw new ConversionException("Could not convert '" + value - + "' to " + getModelType().getName()); - } - return parsedValue.doubleValue(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang - * .Object, java.util.Locale) - */ - @Override - public String convertToPresentation(Double value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - return getFormat(locale).format(value); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getModelType() - */ - @Override - public Class<Double> getModelType() { - return Double.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class<String> getPresentationType() { - return String.class; - } -} diff --git a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java deleted file mode 100644 index 950f01c6ab..0000000000 --- a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java +++ /dev/null @@ -1,88 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.text.NumberFormat; -import java.text.ParsePosition; -import java.util.Locale; - -/** - * A converter that converts from {@link String} to {@link Integer} and back. - * Uses the given locale and a {@link NumberFormat} instance for formatting and - * parsing. - * <p> - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToIntegerConverter implements Converter<String, Integer> { - - /** - * Returns the format used by - * {@link #convertToPresentation(Integer, Locale)} and - * {@link #convertToModel(String, Locale)}. - * - * @param locale - * The locale to use - * @return A NumberFormat instance - */ - protected NumberFormat getFormat(Locale locale) { - if (locale == null) { - locale = Locale.getDefault(); - } - return NumberFormat.getIntegerInstance(locale); - } - - @Override - public Integer convertToModel(String value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - // Remove leading and trailing white space - value = value.trim(); - - // Parse and detect errors. If the full string was not used, it is - // an error. - ParsePosition parsePosition = new ParsePosition(0); - Number parsedValue = getFormat(locale).parse(value, parsePosition); - if (parsePosition.getIndex() != value.length()) { - throw new ConversionException("Could not convert '" + value - + "' to " + getModelType().getName()); - } - - if (parsedValue == null) { - // Convert "" to null - return null; - } - return parsedValue.intValue(); - } - - @Override - public String convertToPresentation(Integer value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - return getFormat(locale).format(value); - } - - @Override - public Class<Integer> getModelType() { - return Integer.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - -} diff --git a/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/src/com/vaadin/data/util/converter/StringToNumberConverter.java deleted file mode 100644 index 42699a326a..0000000000 --- a/src/com/vaadin/data/util/converter/StringToNumberConverter.java +++ /dev/null @@ -1,111 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.util.converter; - -import java.text.NumberFormat; -import java.text.ParsePosition; -import java.util.Locale; - -/** - * A converter that converts from {@link Number} to {@link String} and back. - * Uses the given locale and {@link NumberFormat} for formatting and parsing. - * <p> - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - * </p> - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToNumberConverter implements Converter<String, Number> { - - /** - * Returns the format used by {@link #convertToPresentation(Number, Locale)} - * and {@link #convertToModel(String, Locale)}. - * - * @param locale - * The locale to use - * @return A NumberFormat instance - */ - protected NumberFormat getFormat(Locale locale) { - if (locale == null) { - locale = Locale.getDefault(); - } - - return NumberFormat.getNumberInstance(locale); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, - * java.util.Locale) - */ - @Override - public Number convertToModel(String value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - // Remove leading and trailing white space - value = value.trim(); - - // Parse and detect errors. If the full string was not used, it is - // an error. - ParsePosition parsePosition = new ParsePosition(0); - Number parsedValue = getFormat(locale).parse(value, parsePosition); - if (parsePosition.getIndex() != value.length()) { - throw new ConversionException("Could not convert '" + value - + "' to " + getModelType().getName()); - } - - if (parsedValue == null) { - // Convert "" to null - return null; - } - return parsedValue; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang - * .Object, java.util.Locale) - */ - @Override - public String convertToPresentation(Number value, Locale locale) - throws ConversionException { - if (value == null) { - return null; - } - - return getFormat(locale).format(value); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getModelType() - */ - @Override - public Class<Number> getModelType() { - return Number.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class<String> getPresentationType() { - return String.class; - } - -} diff --git a/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java b/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java deleted file mode 100644 index 482b10120c..0000000000 --- a/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - -import com.vaadin.data.Container.Filter; - -/** - * Abstract base class for filters that are composed of multiple sub-filters. - * - * The method {@link #appliesToProperty(Object)} is provided to help - * implementing {@link Filter} for in-memory filters. - * - * @since 6.6 - */ -public abstract class AbstractJunctionFilter implements Filter { - - protected final Collection<Filter> filters; - - public AbstractJunctionFilter(Filter... filters) { - this.filters = Collections.unmodifiableCollection(Arrays - .asList(filters)); - } - - /** - * Returns an unmodifiable collection of the sub-filters of this composite - * filter. - * - * @return - */ - public Collection<Filter> getFilters() { - return filters; - } - - /** - * Returns true if a change in the named property may affect the filtering - * result. If some of the sub-filters are not in-memory filters, true is - * returned. - * - * By default, all sub-filters are iterated to check if any of them applies. - * If there are no sub-filters, false is returned - override in subclasses - * to change this behavior. - */ - @Override - public boolean appliesToProperty(Object propertyId) { - for (Filter filter : getFilters()) { - if (filter.appliesToProperty(propertyId)) { - return true; - } - } - return false; - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !getClass().equals(obj.getClass())) { - return false; - } - AbstractJunctionFilter other = (AbstractJunctionFilter) obj; - // contents comparison with equals() - return Arrays.equals(filters.toArray(), other.filters.toArray()); - } - - @Override - public int hashCode() { - int hash = getFilters().size(); - for (Filter filter : filters) { - hash = (hash << 1) ^ filter.hashCode(); - } - return hash; - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/filter/And.java b/src/com/vaadin/data/util/filter/And.java deleted file mode 100644 index ca6c35aba7..0000000000 --- a/src/com/vaadin/data/util/filter/And.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; - -/** - * A compound {@link Filter} that accepts an item if all of its filters accept - * the item. - * - * If no filters are given, the filter should accept all items. - * - * This filter also directly supports in-memory filtering when all sub-filters - * do so. - * - * @see Or - * - * @since 6.6 - */ -public final class And extends AbstractJunctionFilter { - - /** - * - * @param filters - * filters of which the And filter will be composed - */ - public And(Filter... filters) { - super(filters); - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedFilterException { - for (Filter filter : getFilters()) { - if (!filter.passesFilter(itemId, item)) { - return false; - } - } - return true; - } - -} diff --git a/src/com/vaadin/data/util/filter/Between.java b/src/com/vaadin/data/util/filter/Between.java deleted file mode 100644 index b00a74d13d..0000000000 --- a/src/com/vaadin/data/util/filter/Between.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; - -public class Between implements Filter { - - private final Object propertyId; - private final Comparable startValue; - private final Comparable endValue; - - public Between(Object propertyId, Comparable startValue, Comparable endValue) { - this.propertyId = propertyId; - this.startValue = startValue; - this.endValue = endValue; - } - - public Object getPropertyId() { - return propertyId; - } - - public Comparable<?> getStartValue() { - return startValue; - } - - public Comparable<?> getEndValue() { - return endValue; - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException { - Object value = item.getItemProperty(getPropertyId()).getValue(); - if (value instanceof Comparable) { - Comparable cval = (Comparable) value; - return cval.compareTo(getStartValue()) >= 0 - && cval.compareTo(getEndValue()) <= 0; - } - return false; - } - - @Override - public boolean appliesToProperty(Object propertyId) { - return getPropertyId() != null && getPropertyId().equals(propertyId); - } - - @Override - public int hashCode() { - return getPropertyId().hashCode() + getStartValue().hashCode() - + getEndValue().hashCode(); - } - - @Override - public boolean equals(Object obj) { - // Only objects of the same class can be equal - if (!getClass().equals(obj.getClass())) { - return false; - } - final Between o = (Between) obj; - - // Checks the properties one by one - boolean propertyIdEqual = (null != getPropertyId()) ? getPropertyId() - .equals(o.getPropertyId()) : null == o.getPropertyId(); - boolean startValueEqual = (null != getStartValue()) ? getStartValue() - .equals(o.getStartValue()) : null == o.getStartValue(); - boolean endValueEqual = (null != getEndValue()) ? getEndValue().equals( - o.getEndValue()) : null == o.getEndValue(); - return propertyIdEqual && startValueEqual && endValueEqual; - - } -} diff --git a/src/com/vaadin/data/util/filter/Compare.java b/src/com/vaadin/data/util/filter/Compare.java deleted file mode 100644 index 4091f5b922..0000000000 --- a/src/com/vaadin/data/util/filter/Compare.java +++ /dev/null @@ -1,327 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * Simple container filter comparing an item property value against a given - * constant value. Use the nested classes {@link Equal}, {@link Greater}, - * {@link Less}, {@link GreaterOrEqual} and {@link LessOrEqual} instead of this - * class directly. - * - * This filter also directly supports in-memory filtering. - * - * The reference and actual values must implement {@link Comparable} and the - * class of the actual property value must be assignable from the class of the - * reference value. - * - * @since 6.6 - */ -public abstract class Compare implements Filter { - - public enum Operation { - EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL - }; - - private final Object propertyId; - private final Operation operation; - private final Object value; - - /** - * A {@link Compare} filter that accepts items for which the identified - * property value is equal to <code>value</code>. - * - * For in-memory filters, equals() is used for the comparison. For other - * containers, the comparison implementation is container dependent and may - * use e.g. database comparison operations. - * - * @since 6.6 - */ - public static final class Equal extends Compare { - /** - * Construct a filter that accepts items for which the identified - * property value is equal to <code>value</code>. - * - * For in-memory filters, equals() is used for the comparison. For other - * containers, the comparison implementation is container dependent and - * may use e.g. database comparison operations. - * - * @param propertyId - * the identifier of the property whose value to compare - * against value, not null - * @param value - * the value to compare against - null values may or may not - * be supported depending on the container - */ - public Equal(Object propertyId, Object value) { - super(propertyId, value, Operation.EQUAL); - } - } - - /** - * A {@link Compare} filter that accepts items for which the identified - * property value is greater than <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} and - * {@link Comparable#compareTo(Object)} is used for the comparison. For - * other containers, the comparison implementation is container dependent - * and may use e.g. database comparison operations. - * - * @since 6.6 - */ - public static final class Greater extends Compare { - /** - * Construct a filter that accepts items for which the identified - * property value is greater than <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} - * and {@link Comparable#compareTo(Object)} is used for the comparison. - * For other containers, the comparison implementation is container - * dependent and may use e.g. database comparison operations. - * - * @param propertyId - * the identifier of the property whose value to compare - * against value, not null - * @param value - * the value to compare against - null values may or may not - * be supported depending on the container - */ - public Greater(Object propertyId, Object value) { - super(propertyId, value, Operation.GREATER); - } - } - - /** - * A {@link Compare} filter that accepts items for which the identified - * property value is less than <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} and - * {@link Comparable#compareTo(Object)} is used for the comparison. For - * other containers, the comparison implementation is container dependent - * and may use e.g. database comparison operations. - * - * @since 6.6 - */ - public static final class Less extends Compare { - /** - * Construct a filter that accepts items for which the identified - * property value is less than <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} - * and {@link Comparable#compareTo(Object)} is used for the comparison. - * For other containers, the comparison implementation is container - * dependent and may use e.g. database comparison operations. - * - * @param propertyId - * the identifier of the property whose value to compare - * against value, not null - * @param value - * the value to compare against - null values may or may not - * be supported depending on the container - */ - public Less(Object propertyId, Object value) { - super(propertyId, value, Operation.LESS); - } - } - - /** - * A {@link Compare} filter that accepts items for which the identified - * property value is greater than or equal to <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} and - * {@link Comparable#compareTo(Object)} is used for the comparison. For - * other containers, the comparison implementation is container dependent - * and may use e.g. database comparison operations. - * - * @since 6.6 - */ - public static final class GreaterOrEqual extends Compare { - /** - * Construct a filter that accepts items for which the identified - * property value is greater than or equal to <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} - * and {@link Comparable#compareTo(Object)} is used for the comparison. - * For other containers, the comparison implementation is container - * dependent and may use e.g. database comparison operations. - * - * @param propertyId - * the identifier of the property whose value to compare - * against value, not null - * @param value - * the value to compare against - null values may or may not - * be supported depending on the container - */ - public GreaterOrEqual(Object propertyId, Object value) { - super(propertyId, value, Operation.GREATER_OR_EQUAL); - } - } - - /** - * A {@link Compare} filter that accepts items for which the identified - * property value is less than or equal to <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} and - * {@link Comparable#compareTo(Object)} is used for the comparison. For - * other containers, the comparison implementation is container dependent - * and may use e.g. database comparison operations. - * - * @since 6.6 - */ - public static final class LessOrEqual extends Compare { - /** - * Construct a filter that accepts items for which the identified - * property value is less than or equal to <code>value</code>. - * - * For in-memory filters, the values must implement {@link Comparable} - * and {@link Comparable#compareTo(Object)} is used for the comparison. - * For other containers, the comparison implementation is container - * dependent and may use e.g. database comparison operations. - * - * @param propertyId - * the identifier of the property whose value to compare - * against value, not null - * @param value - * the value to compare against - null values may or may not - * be supported depending on the container - */ - public LessOrEqual(Object propertyId, Object value) { - super(propertyId, value, Operation.LESS_OR_EQUAL); - } - } - - /** - * Constructor for a {@link Compare} filter that compares the value of an - * item property with the given constant <code>value</code>. - * - * This constructor is intended to be used by the nested static classes only - * ({@link Equal}, {@link Greater}, {@link Less}, {@link GreaterOrEqual}, - * {@link LessOrEqual}). - * - * For in-memory filtering, comparisons except EQUAL require that the values - * implement {@link Comparable} and {@link Comparable#compareTo(Object)} is - * used for the comparison. The equality comparison is performed using - * {@link Object#equals(Object)}. - * - * For other containers, the comparison implementation is container - * dependent and may use e.g. database comparison operations. Therefore, the - * behavior of comparisons might differ in some cases between in-memory and - * other containers. - * - * @param propertyId - * the identifier of the property whose value to compare against - * value, not null - * @param value - * the value to compare against - null values may or may not be - * supported depending on the container - * @param operation - * the comparison {@link Operation} to use - */ - Compare(Object propertyId, Object value, Operation operation) { - this.propertyId = propertyId; - this.value = value; - this.operation = operation; - } - - @Override - public boolean passesFilter(Object itemId, Item item) { - final Property<?> p = item.getItemProperty(getPropertyId()); - if (null == p) { - return false; - } - Object value = p.getValue(); - switch (getOperation()) { - case EQUAL: - return (null == this.value) ? (null == value) : this.value - .equals(value); - case GREATER: - return compareValue(value) > 0; - case LESS: - return compareValue(value) < 0; - case GREATER_OR_EQUAL: - return compareValue(value) >= 0; - case LESS_OR_EQUAL: - return compareValue(value) <= 0; - } - // all cases should have been processed above - return false; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected int compareValue(Object value1) { - if (null == value) { - return null == value1 ? 0 : -1; - } else if (null == value1) { - return 1; - } else if (getValue() instanceof Comparable - && value1.getClass().isAssignableFrom(getValue().getClass())) { - return -((Comparable) getValue()).compareTo(value1); - } - throw new IllegalArgumentException("Could not compare the arguments: " - + value1 + ", " + getValue()); - } - - @Override - public boolean appliesToProperty(Object propertyId) { - return getPropertyId().equals(propertyId); - } - - @Override - public boolean equals(Object obj) { - - // Only objects of the same class can be equal - if (!getClass().equals(obj.getClass())) { - return false; - } - final Compare o = (Compare) obj; - - // Checks the properties one by one - if (getPropertyId() != o.getPropertyId() && null != o.getPropertyId() - && !o.getPropertyId().equals(getPropertyId())) { - return false; - } - if (getOperation() != o.getOperation()) { - return false; - } - return (null == getValue()) ? null == o.getValue() : getValue().equals( - o.getValue()); - } - - @Override - public int hashCode() { - return (null != getPropertyId() ? getPropertyId().hashCode() : 0) - ^ (null != getValue() ? getValue().hashCode() : 0); - } - - /** - * Returns the property id of the property to compare against the fixed - * value. - * - * @return property id (not null) - */ - public Object getPropertyId() { - return propertyId; - } - - /** - * Returns the comparison operation. - * - * @return {@link Operation} - */ - public Operation getOperation() { - return operation; - } - - /** - * Returns the value to compare the property against. - * - * @return comparison reference value - */ - public Object getValue() { - return value; - } -} diff --git a/src/com/vaadin/data/util/filter/IsNull.java b/src/com/vaadin/data/util/filter/IsNull.java deleted file mode 100644 index 3faf4153ee..0000000000 --- a/src/com/vaadin/data/util/filter/IsNull.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * Simple container filter checking whether an item property value is null. - * - * This filter also directly supports in-memory filtering. - * - * @since 6.6 - */ -public final class IsNull implements Filter { - - private final Object propertyId; - - /** - * Constructor for a filter that compares the value of an item property with - * null. - * - * For in-memory filtering, a simple == check is performed. For other - * containers, the comparison implementation is container dependent but - * should correspond to the in-memory null check. - * - * @param propertyId - * the identifier (not null) of the property whose value to check - */ - public IsNull(Object propertyId) { - this.propertyId = propertyId; - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException { - final Property<?> p = item.getItemProperty(getPropertyId()); - if (null == p) { - return false; - } - return null == p.getValue(); - } - - @Override - public boolean appliesToProperty(Object propertyId) { - return getPropertyId().equals(propertyId); - } - - @Override - public boolean equals(Object obj) { - // Only objects of the same class can be equal - if (!getClass().equals(obj.getClass())) { - return false; - } - final IsNull o = (IsNull) obj; - - // Checks the properties one by one - return (null != getPropertyId()) ? getPropertyId().equals( - o.getPropertyId()) : null == o.getPropertyId(); - } - - @Override - public int hashCode() { - return (null != getPropertyId() ? getPropertyId().hashCode() : 0); - } - - /** - * Returns the property id of the property tested by the filter, not null - * for valid filters. - * - * @return property id (not null) - */ - public Object getPropertyId() { - return propertyId; - } - -} diff --git a/src/com/vaadin/data/util/filter/Like.java b/src/com/vaadin/data/util/filter/Like.java deleted file mode 100644 index 3dcc48e809..0000000000 --- a/src/com/vaadin/data/util/filter/Like.java +++ /dev/null @@ -1,83 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; - -public class Like implements Filter { - private final Object propertyId; - private final String value; - private boolean caseSensitive; - - public Like(String propertyId, String value) { - this(propertyId, value, true); - } - - public Like(String propertyId, String value, boolean caseSensitive) { - this.propertyId = propertyId; - this.value = value; - setCaseSensitive(caseSensitive); - } - - public Object getPropertyId() { - return propertyId; - } - - public String getValue() { - return value; - } - - public void setCaseSensitive(boolean caseSensitive) { - this.caseSensitive = caseSensitive; - } - - public boolean isCaseSensitive() { - return caseSensitive; - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException { - if (!item.getItemProperty(getPropertyId()).getType() - .isAssignableFrom(String.class)) { - // We can only handle strings - return false; - } - String colValue = (String) item.getItemProperty(getPropertyId()) - .getValue(); - - String pattern = getValue().replace("%", ".*"); - if (isCaseSensitive()) { - return colValue.matches(pattern); - } - return colValue.toUpperCase().matches(pattern.toUpperCase()); - } - - @Override - public boolean appliesToProperty(Object propertyId) { - return getPropertyId() != null && getPropertyId().equals(propertyId); - } - - @Override - public int hashCode() { - return getPropertyId().hashCode() + getValue().hashCode(); - } - - @Override - public boolean equals(Object obj) { - // Only objects of the same class can be equal - if (!getClass().equals(obj.getClass())) { - return false; - } - final Like o = (Like) obj; - - // Checks the properties one by one - boolean propertyIdEqual = (null != getPropertyId()) ? getPropertyId() - .equals(o.getPropertyId()) : null == o.getPropertyId(); - boolean valueEqual = (null != getValue()) ? getValue().equals( - o.getValue()) : null == o.getValue(); - return propertyIdEqual && valueEqual; - } -} diff --git a/src/com/vaadin/data/util/filter/Not.java b/src/com/vaadin/data/util/filter/Not.java deleted file mode 100644 index bbfc9ca86a..0000000000 --- a/src/com/vaadin/data/util/filter/Not.java +++ /dev/null @@ -1,70 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; - -/** - * Negating filter that accepts the items rejected by another filter. - * - * This filter directly supports in-memory filtering when the negated filter - * does so. - * - * @since 6.6 - */ -public final class Not implements Filter { - private final Filter filter; - - /** - * Constructs a filter that negates a filter. - * - * @param filter - * {@link Filter} to negate, not-null - */ - public Not(Filter filter) { - this.filter = filter; - } - - /** - * Returns the negated filter. - * - * @return Filter - */ - public Filter getFilter() { - return filter; - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException { - return !filter.passesFilter(itemId, item); - } - - /** - * Returns true if a change in the named property may affect the filtering - * result. Return value is the same as {@link #appliesToProperty(Object)} - * for the negated filter. - * - * @return boolean - */ - @Override - public boolean appliesToProperty(Object propertyId) { - return filter.appliesToProperty(propertyId); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !getClass().equals(obj.getClass())) { - return false; - } - return filter.equals(((Not) obj).getFilter()); - } - - @Override - public int hashCode() { - return filter.hashCode(); - } - -} diff --git a/src/com/vaadin/data/util/filter/Or.java b/src/com/vaadin/data/util/filter/Or.java deleted file mode 100644 index b60074f7e3..0000000000 --- a/src/com/vaadin/data/util/filter/Or.java +++ /dev/null @@ -1,63 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; - -/** - * A compound {@link Filter} that accepts an item if any of its filters accept - * the item. - * - * If no filters are given, the filter should reject all items. - * - * This filter also directly supports in-memory filtering when all sub-filters - * do so. - * - * @see And - * - * @since 6.6 - */ -public final class Or extends AbstractJunctionFilter { - - /** - * - * @param filters - * filters of which the Or filter will be composed - */ - public Or(Filter... filters) { - super(filters); - } - - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedFilterException { - for (Filter filter : getFilters()) { - if (filter.passesFilter(itemId, item)) { - return true; - } - } - return false; - } - - /** - * Returns true if a change in the named property may affect the filtering - * result. If some of the sub-filters are not in-memory filters, true is - * returned. - * - * By default, all sub-filters are iterated to check if any of them applies. - * If there are no sub-filters, true is returned as an empty Or rejects all - * items. - */ - @Override - public boolean appliesToProperty(Object propertyId) { - if (getFilters().isEmpty()) { - // empty Or filters out everything - return true; - } else { - return super.appliesToProperty(propertyId); - } - } - -} diff --git a/src/com/vaadin/data/util/filter/SimpleStringFilter.java b/src/com/vaadin/data/util/filter/SimpleStringFilter.java deleted file mode 100644 index f98b2c02b4..0000000000 --- a/src/com/vaadin/data/util/filter/SimpleStringFilter.java +++ /dev/null @@ -1,152 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * Simple string filter for matching items that start with or contain a - * specified string. The matching can be case-sensitive or case-insensitive. - * - * This filter also directly supports in-memory filtering. When performing - * in-memory filtering, values of other types are converted using toString(), - * but other (lazy container) implementations do not need to perform such - * conversions and might not support values of different types. - * - * Note that this filter is modeled after the pre-6.6 filtering mechanisms, and - * might not be very efficient e.g. for database filtering. - * - * TODO this might still change - * - * @since 6.6 - */ -public final class SimpleStringFilter implements Filter { - - final Object propertyId; - final String filterString; - final boolean ignoreCase; - final boolean onlyMatchPrefix; - - public SimpleStringFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - this.propertyId = propertyId; - this.filterString = ignoreCase ? filterString.toLowerCase() - : filterString; - this.ignoreCase = ignoreCase; - this.onlyMatchPrefix = onlyMatchPrefix; - } - - @Override - public boolean passesFilter(Object itemId, Item item) { - final Property<?> p = item.getItemProperty(propertyId); - if (p == null) { - return false; - } - Object propertyValue = p.getValue(); - if (propertyValue == null) { - return false; - } - final String value = ignoreCase ? propertyValue.toString() - .toLowerCase() : propertyValue.toString(); - if (onlyMatchPrefix) { - if (!value.startsWith(filterString)) { - return false; - } - } else { - if (!value.contains(filterString)) { - return false; - } - } - return true; - } - - @Override - public boolean appliesToProperty(Object propertyId) { - return this.propertyId.equals(propertyId); - } - - @Override - public boolean equals(Object obj) { - - // Only ones of the objects of the same class can be equal - if (!(obj instanceof SimpleStringFilter)) { - return false; - } - final SimpleStringFilter o = (SimpleStringFilter) obj; - - // Checks the properties one by one - if (propertyId != o.propertyId && o.propertyId != null - && !o.propertyId.equals(propertyId)) { - return false; - } - if (filterString != o.filterString && o.filterString != null - && !o.filterString.equals(filterString)) { - return false; - } - if (ignoreCase != o.ignoreCase) { - return false; - } - if (onlyMatchPrefix != o.onlyMatchPrefix) { - return false; - } - - return true; - } - - @Override - public int hashCode() { - return (propertyId != null ? propertyId.hashCode() : 0) - ^ (filterString != null ? filterString.hashCode() : 0); - } - - /** - * Returns the property identifier to which this filter applies. - * - * @return property id - */ - public Object getPropertyId() { - return propertyId; - } - - /** - * Returns the filter string. - * - * Note: this method is intended only for implementations of lazy string - * filters and may change in the future. - * - * @return filter string given to the constructor - */ - public String getFilterString() { - return filterString; - } - - /** - * Returns whether the filter is case-insensitive or case-sensitive. - * - * Note: this method is intended only for implementations of lazy string - * filters and may change in the future. - * - * @return true if performing case-insensitive filtering, false for - * case-sensitive - */ - public boolean isIgnoreCase() { - return ignoreCase; - } - - /** - * Returns true if the filter only applies to the beginning of the value - * string, false for any location in the value. - * - * Note: this method is intended only for implementations of lazy string - * filters and may change in the future. - * - * @return true if checking for matches at the beginning of the value only, - * false if matching any part of value - */ - public boolean isOnlyMatchPrefix() { - return onlyMatchPrefix; - } -} diff --git a/src/com/vaadin/data/util/filter/UnsupportedFilterException.java b/src/com/vaadin/data/util/filter/UnsupportedFilterException.java deleted file mode 100644 index c09cc474e9..0000000000 --- a/src/com/vaadin/data/util/filter/UnsupportedFilterException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.filter; - -import java.io.Serializable; - -/** - * Exception for cases where a container does not support a specific type of - * filters. - * - * If possible, this should be thrown already when adding a filter to a - * container. If a problem is not detected at that point, an - * {@link UnsupportedOperationException} can be throws when attempting to - * perform filtering. - * - * @since 6.6 - */ -public class UnsupportedFilterException extends RuntimeException implements - Serializable { - public UnsupportedFilterException() { - } - - public UnsupportedFilterException(String message) { - super(message); - } - - public UnsupportedFilterException(Exception cause) { - super(cause); - } - - public UnsupportedFilterException(String message, Exception cause) { - super(message, cause); - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/package.html b/src/com/vaadin/data/util/package.html deleted file mode 100644 index 07e3acde9e..0000000000 --- a/src/com/vaadin/data/util/package.html +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> - -</head> - -<body bgcolor="white"> - -<p>Provides implementations of Property, Item and Container -interfaces, and utilities for the data layer.</p> - -<p>Various Property, Item and Container implementations are provided -in this package. Each implementation can have its own sets of -constraints on the data it encapsulates and on how the implementation -can be used. See the class javadocs for more information.</p> - -</body> -</html> diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java deleted file mode 100644 index 788966048d..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java +++ /dev/null @@ -1,92 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; - -import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; - -/** - * CacheFlushNotifier is a simple static notification mechanism to inform other - * SQLContainers that the contents of their caches may have become stale. - */ -class CacheFlushNotifier implements Serializable { - /* - * SQLContainer instance reference list and dead reference queue. Used for - * the cache flush notification feature. - */ - private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>(); - private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>(); - - /** - * Adds the given SQLContainer to the cache flush notification receiver list - * - * @param c - * Container to add - */ - public static void addInstance(SQLContainer c) { - removeDeadReferences(); - if (c != null) { - allInstances.add(new WeakReference<SQLContainer>(c, deadInstances)); - } - } - - /** - * Removes dead references from instance list - */ - private static void removeDeadReferences() { - java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances - .poll(); - while (dead != null) { - allInstances.remove(dead); - dead = deadInstances.poll(); - } - } - - /** - * Iterates through the instances and notifies containers which are - * connected to the same table or are using the same query string. - * - * @param c - * SQLContainer that issued the cache flush notification - */ - public static void notifyOfCacheFlush(SQLContainer c) { - removeDeadReferences(); - for (WeakReference<SQLContainer> wr : allInstances) { - if (wr.get() != null) { - SQLContainer wrc = wr.get(); - if (wrc == null) { - continue; - } - /* - * If the reference points to the container sending the - * notification, do nothing. - */ - if (wrc.equals(c)) { - continue; - } - /* Compare QueryDelegate types and tableName/queryString */ - QueryDelegate wrQd = wrc.getQueryDelegate(); - QueryDelegate qd = c.getQueryDelegate(); - if (wrQd instanceof TableQuery - && qd instanceof TableQuery - && ((TableQuery) wrQd).getTableName().equals( - ((TableQuery) qd).getTableName())) { - wrc.refresh(); - } else if (wrQd instanceof FreeformQuery - && qd instanceof FreeformQuery - && ((FreeformQuery) wrQd).getQueryString().equals( - ((FreeformQuery) qd).getQueryString())) { - wrc.refresh(); - } - } - } - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java deleted file mode 100644 index 839fceb3c2..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java +++ /dev/null @@ -1,31 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum - * number of items. In SQLContainer this is used for RowItem -cache. Cache size - * will be two times the page length parameter of the container. - */ -class CacheMap<K, V> extends LinkedHashMap<K, V> { - private static final long serialVersionUID = 679999766473555231L; - private int cacheLimit = SQLContainer.CACHE_RATIO - * SQLContainer.DEFAULT_PAGE_LENGTH; - - @Override - protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { - return size() > cacheLimit; - } - - void setCacheLimit(int limit) { - cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH; - } - - int getCacheLimit() { - return cacheLimit; - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java b/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java deleted file mode 100644 index 168bce1880..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java +++ /dev/null @@ -1,248 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; - -import com.vaadin.data.Property; - -/** - * ColumnProperty represents the value of one column in a RowItem. In addition - * to the value, ColumnProperty also contains some basic column attributes such - * as nullability status, read-only status and data type. - * - * Note that depending on the QueryDelegate in use this does not necessarily map - * into an actual column in a database table. - */ -final public class ColumnProperty implements Property { - private static final long serialVersionUID = -3694463129581802457L; - - private RowItem owner; - - private String propertyId; - - private boolean readOnly; - private boolean allowReadOnlyChange = true; - private boolean nullable = true; - - private Object value; - private Object changedValue; - private Class<?> type; - - private boolean modified; - - private boolean versionColumn; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private ColumnProperty() { - } - - public ColumnProperty(String propertyId, boolean readOnly, - boolean allowReadOnlyChange, boolean nullable, Object value, - Class<?> type) { - if (propertyId == null) { - throw new IllegalArgumentException("Properties must be named."); - } - if (type == null) { - throw new IllegalArgumentException("Property type must be set."); - } - this.propertyId = propertyId; - this.type = type; - this.value = value; - - this.allowReadOnlyChange = allowReadOnlyChange; - this.nullable = nullable; - this.readOnly = readOnly; - } - - @Override - public Object getValue() { - if (isModified()) { - return changedValue; - } - return value; - } - - @Override - public void setValue(Object newValue) throws ReadOnlyException { - if (newValue == null && !nullable) { - throw new NotNullableException( - "Null values are not allowed for this property."); - } - if (readOnly) { - throw new ReadOnlyException( - "Cannot set value for read-only property."); - } - - /* Check if this property is a date property. */ - boolean isDateProperty = Time.class.equals(getType()) - || Date.class.equals(getType()) - || Timestamp.class.equals(getType()); - - if (newValue != null) { - /* Handle SQL dates, times and Timestamps given as java.util.Date */ - if (isDateProperty) { - /* - * Try to get the millisecond value from the new value of this - * property. Possible type to convert from is java.util.Date. - */ - long millis = 0; - if (newValue instanceof java.util.Date) { - millis = ((java.util.Date) newValue).getTime(); - /* - * Create the new object based on the millisecond value, - * according to the type of this property. - */ - if (Time.class.equals(getType())) { - newValue = new Time(millis); - } else if (Date.class.equals(getType())) { - newValue = new Date(millis); - } else if (Timestamp.class.equals(getType())) { - newValue = new Timestamp(millis); - } - } - } - - if (!getType().isAssignableFrom(newValue.getClass())) { - throw new IllegalArgumentException( - "Illegal value type for ColumnProperty"); - } - - /* - * If the value to be set is the same that has already been set, do - * not set it again. - */ - if (isValueAlreadySet(newValue)) { - return; - } - } - - /* Set the new value and notify container of the change. */ - changedValue = newValue; - modified = true; - owner.getContainer().itemChangeNotification(owner); - } - - private boolean isValueAlreadySet(Object newValue) { - Object referenceValue = isModified() ? changedValue : value; - - return (isNullable() && newValue == null && referenceValue == null) - || newValue.equals(referenceValue); - } - - @Override - public Class<?> getType() { - return type; - } - - @Override - public boolean isReadOnly() { - return readOnly; - } - - public boolean isReadOnlyChangeAllowed() { - return allowReadOnlyChange; - } - - @Override - public void setReadOnly(boolean newStatus) { - if (allowReadOnlyChange) { - readOnly = newStatus; - } - } - - public String getPropertyId() { - return propertyId; - } - - /** - * Returns the value of the Property in human readable textual format. - * - * @see java.lang.Object#toString() - * @deprecated get the string representation from the value - */ - @Deprecated - @Override - public String toString() { - throw new UnsupportedOperationException( - "Use ColumnProperty.getValue() instead of ColumnProperty.toString()"); - } - - public void setOwner(RowItem owner) { - if (owner == null) { - throw new IllegalArgumentException("Owner can not be set to null."); - } - if (this.owner != null) { - throw new IllegalStateException( - "ColumnProperties can only be bound once."); - } - this.owner = owner; - } - - public boolean isModified() { - return modified; - } - - public boolean isVersionColumn() { - return versionColumn; - } - - public void setVersionColumn(boolean versionColumn) { - this.versionColumn = versionColumn; - } - - public boolean isNullable() { - return nullable; - } - - /** - * An exception that signals that a <code>null</code> value was passed to - * the <code>setValue</code> method, but the value of this property can not - * be set to <code>null</code>. - */ - @SuppressWarnings("serial") - public class NotNullableException extends RuntimeException { - - /** - * Constructs a new <code>NotNullableException</code> without a detail - * message. - */ - public NotNullableException() { - } - - /** - * Constructs a new <code>NotNullableException</code> with the specified - * detail message. - * - * @param msg - * the detail message - */ - public NotNullableException(String msg) { - super(msg); - } - - /** - * Constructs a new <code>NotNullableException</code> from another - * exception. - * - * @param cause - * The cause of the failure - */ - public NotNullableException(Throwable cause) { - super(cause); - } - } - - public void commit() { - if (isModified()) { - modified = false; - value = changedValue; - } - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java b/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java deleted file mode 100644 index adfd439ac8..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import com.vaadin.data.util.sqlcontainer.query.TableQuery; - -/** - * An OptimisticLockException is thrown when trying to update or delete a row - * that has been changed since last read from the database. - * - * OptimisticLockException is a runtime exception because optimistic locking is - * turned off by default, and as such will never be thrown in a default - * configuration. In order to turn on optimistic locking, you need to specify - * the version column in your TableQuery instance. - * - * @see TableQuery#setVersionColumn(String) - * - * @author Jonatan Kronqvist / Vaadin Ltd - */ -public class OptimisticLockException extends RuntimeException { - - private final RowId rowId; - - public OptimisticLockException(RowId rowId) { - super(); - this.rowId = rowId; - } - - public OptimisticLockException(String msg, RowId rowId) { - super(msg); - this.rowId = rowId; - } - - public RowId getRowId() { - return rowId; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java b/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java deleted file mode 100644 index c73ffce63a..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java +++ /dev/null @@ -1,31 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -public class ReadOnlyRowId extends RowId { - private static final long serialVersionUID = -2626764781642012467L; - private final Integer rowNum; - - public ReadOnlyRowId(int rowNum) { - super(); - this.rowNum = rowNum; - } - - @Override - public int hashCode() { - return rowNum.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof ReadOnlyRowId)) { - return false; - } - return rowNum.equals(((ReadOnlyRowId) obj).rowNum); - } - - public int getRowNum() { - return rowNum; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/Reference.java b/src/com/vaadin/data/util/sqlcontainer/Reference.java deleted file mode 100644 index dea1aa87c0..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/Reference.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; - -/** - * The reference class represents a simple [usually foreign key] reference to - * another SQLContainer. Actual foreign key reference in the database is not - * required, but it is recommended to make sure that certain constraints are - * followed. - */ -@SuppressWarnings("serial") -class Reference implements Serializable { - - /** - * The SQLContainer that this reference points to. - */ - private SQLContainer referencedContainer; - - /** - * The column ID/name in the referencing SQLContainer that contains the key - * used for the reference. - */ - private String referencingColumn; - - /** - * The column ID/name in the referenced SQLContainer that contains the key - * used for the reference. - */ - private String referencedColumn; - - /** - * Constructs a new reference to be used within the SQLContainer to - * reference another SQLContainer. - */ - Reference(SQLContainer referencedContainer, String referencingColumn, - String referencedColumn) { - this.referencedContainer = referencedContainer; - this.referencingColumn = referencingColumn; - this.referencedColumn = referencedColumn; - } - - SQLContainer getReferencedContainer() { - return referencedContainer; - } - - String getReferencingColumn() { - return referencingColumn; - } - - String getReferencedColumn() { - return referencedColumn; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/RowId.java b/src/com/vaadin/data/util/sqlcontainer/RowId.java deleted file mode 100644 index 925325134a..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/RowId.java +++ /dev/null @@ -1,81 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; - -/** - * RowId represents identifiers of a single database result set row. - * - * The data structure of a RowId is an Object array which contains the values of - * the primary key columns of the identified row. This allows easy equals() - * -comparison of RowItems. - */ -public class RowId implements Serializable { - private static final long serialVersionUID = -3161778404698901258L; - protected Object[] id; - - /** - * Prevent instantiation without required parameters. - */ - protected RowId() { - } - - public RowId(Object[] id) { - if (id == null) { - throw new IllegalArgumentException("id parameter must not be null!"); - } - this.id = id; - } - - public Object[] getId() { - return id; - } - - @Override - public int hashCode() { - int result = 31; - if (id != null) { - for (Object o : id) { - if (o != null) { - result += o.hashCode(); - } - } - } - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof RowId)) { - return false; - } - Object[] compId = ((RowId) obj).getId(); - if (id == null && compId == null) { - return true; - } - if (id.length != compId.length) { - return false; - } - for (int i = 0; i < id.length; i++) { - if ((id[i] == null && compId[i] != null) - || (id[i] != null && !id[i].equals(compId[i]))) { - return false; - } - } - return true; - } - - @Override - public String toString() { - StringBuffer s = new StringBuffer(); - for (int i = 0; i < id.length; i++) { - s.append(id[i]); - if (i < id.length - 1) { - s.append("/"); - } - } - return s.toString(); - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/RowItem.java b/src/com/vaadin/data/util/sqlcontainer/RowItem.java deleted file mode 100644 index d613a06b63..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/RowItem.java +++ /dev/null @@ -1,133 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; - -import com.vaadin.data.Item; -import com.vaadin.data.Property; - -/** - * RowItem represents one row of a result set obtained from a QueryDelegate. - * - * Note that depending on the QueryDelegate in use this does not necessarily map - * into an actual row in a database table. - */ -public final class RowItem implements Item { - private static final long serialVersionUID = -6228966439127951408L; - private SQLContainer container; - private RowId id; - private Collection<ColumnProperty> properties; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private RowItem() { - } - - public RowItem(SQLContainer container, RowId id, - Collection<ColumnProperty> properties) { - if (container == null) { - throw new IllegalArgumentException("Container cannot be null."); - } - if (id == null) { - throw new IllegalArgumentException("Row ID cannot be null."); - } - this.container = container; - this.properties = properties; - /* Set this RowItem as owner to the properties */ - if (properties != null) { - for (ColumnProperty p : properties) { - p.setOwner(this); - } - } - this.id = id; - } - - @Override - public Property<?> getItemProperty(Object id) { - if (id instanceof String && id != null) { - for (ColumnProperty cp : properties) { - if (id.equals(cp.getPropertyId())) { - return cp; - } - } - } - return null; - } - - @Override - public Collection<?> getItemPropertyIds() { - Collection<String> ids = new ArrayList<String>(properties.size()); - for (ColumnProperty cp : properties) { - ids.add(cp.getPropertyId()); - } - return Collections.unmodifiableCollection(ids); - } - - /** - * Adding properties is not supported. Properties are generated by - * SQLContainer. - */ - @Override - public boolean addItemProperty(Object id, Property property) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /** - * Removing properties is not supported. Properties are generated by - * SQLContainer. - */ - @Override - public boolean removeItemProperty(Object id) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - public RowId getId() { - return id; - } - - public SQLContainer getContainer() { - return container; - } - - public boolean isModified() { - if (properties != null) { - for (ColumnProperty p : properties) { - if (p.isModified()) { - return true; - } - } - } - return false; - } - - @Override - public String toString() { - StringBuffer s = new StringBuffer(); - s.append("ID:"); - s.append(getId().toString()); - for (Object propId : getItemPropertyIds()) { - s.append("|"); - s.append(propId.toString()); - s.append(":"); - Object value = getItemProperty(propId).getValue(); - s.append((null != value) ? value.toString() : null); - } - return s.toString(); - } - - public void commit() { - if (properties != null) { - for (ColumnProperty p : properties) { - p.commit(); - } - } - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java deleted file mode 100644 index 5827390723..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java +++ /dev/null @@ -1,1716 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.io.IOException; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Date; -import java.util.EventObject; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.filter.UnsupportedFilterException; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate.RowIdChangeListener; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; -import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; - -public class SQLContainer implements Container, Container.Filterable, - Container.Indexed, Container.Sortable, Container.ItemSetChangeNotifier { - - /** Query delegate */ - private QueryDelegate delegate; - /** Auto commit mode, default = false */ - private boolean autoCommit = false; - - /** Page length = number of items contained in one page */ - private int pageLength = DEFAULT_PAGE_LENGTH; - public static final int DEFAULT_PAGE_LENGTH = 100; - - /** Number of items to cache = CACHE_RATIO x pageLength */ - public static final int CACHE_RATIO = 2; - - /** Item and index caches */ - private final Map<Integer, RowId> itemIndexes = new HashMap<Integer, RowId>(); - private final CacheMap<RowId, RowItem> cachedItems = new CacheMap<RowId, RowItem>(); - - /** Container properties = column names, data types and statuses */ - private final List<String> propertyIds = new ArrayList<String>(); - private final Map<String, Class<?>> propertyTypes = new HashMap<String, Class<?>>(); - private final Map<String, Boolean> propertyReadOnly = new HashMap<String, Boolean>(); - private final Map<String, Boolean> propertyNullable = new HashMap<String, Boolean>(); - - /** Filters (WHERE) and sorters (ORDER BY) */ - private final List<Filter> filters = new ArrayList<Filter>(); - private final List<OrderBy> sorters = new ArrayList<OrderBy>(); - - /** - * Total number of items available in the data source using the current - * query, filters and sorters. - */ - private int size; - - /** - * Size updating logic. Do not update size from data source if it has been - * updated in the last sizeValidMilliSeconds milliseconds. - */ - private final int sizeValidMilliSeconds = 10000; - private boolean sizeDirty = true; - private Date sizeUpdated = new Date(); - - /** Starting row number of the currently fetched page */ - private int currentOffset; - - /** ItemSetChangeListeners */ - private LinkedList<Container.ItemSetChangeListener> itemSetChangeListeners; - - /** Temporary storage for modified items and items to be removed and added */ - private final Map<RowId, RowItem> removedItems = new HashMap<RowId, RowItem>(); - private final List<RowItem> addedItems = new ArrayList<RowItem>(); - private final List<RowItem> modifiedItems = new ArrayList<RowItem>(); - - /** List of references to other SQLContainers */ - private final Map<SQLContainer, Reference> references = new HashMap<SQLContainer, Reference>(); - - /** Cache flush notification system enabled. Disabled by default. */ - private boolean notificationsEnabled; - - /** - * Prevent instantiation without a QueryDelegate. - */ - @SuppressWarnings("unused") - private SQLContainer() { - } - - /** - * Creates and initializes SQLContainer using the given QueryDelegate - * - * @param delegate - * QueryDelegate implementation - * @throws SQLException - */ - public SQLContainer(QueryDelegate delegate) throws SQLException { - if (delegate == null) { - throw new IllegalArgumentException( - "QueryDelegate must not be null."); - } - this.delegate = delegate; - getPropertyIds(); - cachedItems.setCacheLimit(CACHE_RATIO * getPageLength()); - } - - /**************************************/ - /** Methods from interface Container **/ - /**************************************/ - - /** - * Note! If auto commit mode is enabled, this method will still return the - * temporary row ID assigned for the item. Implement - * QueryDelegate.RowIdChangeListener to receive the actual Row ID value - * after the addition has been committed. - * - * {@inheritDoc} - */ - - @Override - public Object addItem() throws UnsupportedOperationException { - Object emptyKey[] = new Object[delegate.getPrimaryKeyColumns().size()]; - RowId itemId = new TemporaryRowId(emptyKey); - // Create new empty column properties for the row item. - List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>(); - for (String propertyId : propertyIds) { - /* Default settings for new item properties. */ - itemProperties - .add(new ColumnProperty(propertyId, propertyReadOnly - .get(propertyId), - !propertyReadOnly.get(propertyId), propertyNullable - .get(propertyId), null, getType(propertyId))); - } - RowItem newRowItem = new RowItem(this, itemId, itemProperties); - - if (autoCommit) { - /* Add and commit instantly */ - try { - if (delegate instanceof TableQuery) { - itemId = ((TableQuery) delegate) - .storeRowImmediately(newRowItem); - } else { - delegate.beginTransaction(); - delegate.storeRow(newRowItem); - delegate.commit(); - } - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - getLogger().log(Level.FINER, "Row added to DB..."); - return itemId; - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to add row to DB. Rolling back.", e); - try { - delegate.rollback(); - } catch (SQLException ee) { - getLogger().log(Level.SEVERE, - "Failed to roll back row addition", e); - } - return null; - } - } else { - addedItems.add(newRowItem); - fireContentsChange(); - return itemId; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#containsId(java.lang.Object) - */ - - @Override - public boolean containsId(Object itemId) { - if (itemId == null) { - return false; - } - - if (cachedItems.containsKey(itemId)) { - return true; - } else { - for (RowItem item : addedItems) { - if (item.getId().equals(itemId)) { - return itemPassesFilters(item); - } - } - } - if (removedItems.containsKey(itemId)) { - return false; - } - - if (itemId instanceof ReadOnlyRowId) { - int rowNum = ((ReadOnlyRowId) itemId).getRowNum(); - return rowNum >= 0 && rowNum < size; - } - - if (itemId instanceof RowId && !(itemId instanceof TemporaryRowId)) { - try { - return delegate.containsRowWithKey(((RowId) itemId).getId()); - } catch (Exception e) { - /* Query failed, just return false. */ - getLogger().log(Level.WARNING, "containsId query failed", e); - } - } - return false; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, - * java.lang.Object) - */ - - @Override - public Property<?> getContainerProperty(Object itemId, Object propertyId) { - Item item = getItem(itemId); - if (item == null) { - return null; - } - return item.getItemProperty(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - - @Override - public Collection<?> getContainerPropertyIds() { - return Collections.unmodifiableCollection(propertyIds); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItem(java.lang.Object) - */ - - @Override - public Item getItem(Object itemId) { - if (!cachedItems.containsKey(itemId)) { - int index = indexOfId(itemId); - if (index >= size) { - // The index is in the added items - int offset = index - size; - RowItem item = addedItems.get(offset); - if (itemPassesFilters(item)) { - return item; - } else { - return null; - } - } else { - // load the item into cache - updateOffsetAndCache(index); - } - } - return cachedItems.get(itemId); - } - - /** - * Bypasses in-memory filtering to return items that are cached in memory. - * <em>NOTE</em>: This does not bypass database-level filtering. - * - * @param itemId - * the id of the item to retrieve. - * @return the item represented by itemId. - */ - public Item getItemUnfiltered(Object itemId) { - if (!cachedItems.containsKey(itemId)) { - for (RowItem item : addedItems) { - if (item.getId().equals(itemId)) { - return item; - } - } - } - return cachedItems.get(itemId); - } - - /** - * NOTE! Do not use this method if in any way avoidable. This method doesn't - * (and cannot) use lazy loading, which means that all rows in the database - * will be loaded into memory. - * - * {@inheritDoc} - */ - - @Override - public Collection<?> getItemIds() { - updateCount(); - ArrayList<RowId> ids = new ArrayList<RowId>(); - ResultSet rs = null; - try { - // Load ALL rows :( - delegate.beginTransaction(); - rs = delegate.getResults(0, 0); - List<String> pKeys = delegate.getPrimaryKeyColumns(); - while (rs.next()) { - RowId id = null; - if (pKeys.isEmpty()) { - /* Create a read only itemId */ - id = new ReadOnlyRowId(rs.getRow()); - } else { - /* Generate itemId for the row based on primary key(s) */ - Object[] itemId = new Object[pKeys.size()]; - for (int i = 0; i < pKeys.size(); i++) { - itemId[i] = rs.getObject(pKeys.get(i)); - } - id = new RowId(itemId); - } - if (id != null && !removedItems.containsKey(id)) { - ids.add(id); - } - } - rs.getStatement().close(); - rs.close(); - delegate.commit(); - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "getItemIds() failed, rolling back.", e); - try { - delegate.rollback(); - } catch (SQLException e1) { - getLogger().log(Level.SEVERE, "Failed to roll back state", e1); - } - try { - rs.getStatement().close(); - rs.close(); - } catch (SQLException e1) { - getLogger().log(Level.WARNING, "Closing session failed", e1); - } - throw new RuntimeException("Failed to fetch item indexes.", e); - } - for (RowItem item : getFilteredAddedItems()) { - ids.add(item.getId()); - } - return Collections.unmodifiableCollection(ids); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getType(java.lang.Object) - */ - - @Override - public Class<?> getType(Object propertyId) { - if (!propertyIds.contains(propertyId)) { - return null; - } - return propertyTypes.get(propertyId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#size() - */ - - @Override - public int size() { - updateCount(); - return size + sizeOfAddedItems() - removedItems.size(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - if (!containsId(itemId)) { - return false; - } - for (RowItem item : addedItems) { - if (item.getId().equals(itemId)) { - addedItems.remove(item); - fireContentsChange(); - return true; - } - } - - if (autoCommit) { - /* Remove and commit instantly. */ - Item i = getItem(itemId); - if (i == null) { - return false; - } - try { - delegate.beginTransaction(); - boolean success = delegate.removeRow((RowItem) i); - delegate.commit(); - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - if (success) { - getLogger().log(Level.FINER, "Row removed from DB..."); - } - return success; - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to remove row, rolling back", e); - try { - delegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, - "Failed to rollback row removal", ee); - } - return false; - } catch (OptimisticLockException e) { - getLogger().log(Level.WARNING, - "Failed to remove row, rolling back", e); - try { - delegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, - "Failed to rollback row removal", ee); - } - throw e; - } - } else { - removedItems.put((RowId) itemId, (RowItem) getItem(itemId)); - cachedItems.remove(itemId); - refresh(); - return true; - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeAllItems() - */ - - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - if (autoCommit) { - /* Remove and commit instantly. */ - try { - delegate.beginTransaction(); - boolean success = true; - for (Object id : getItemIds()) { - if (!delegate.removeRow((RowItem) getItem(id))) { - success = false; - } - } - if (success) { - delegate.commit(); - getLogger().log(Level.FINER, "All rows removed from DB..."); - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - } else { - delegate.rollback(); - } - return success; - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "removeAllItems() failed, rolling back", e); - try { - delegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, "Failed to roll back", ee); - } - return false; - } catch (OptimisticLockException e) { - getLogger().log(Level.WARNING, - "removeAllItems() failed, rolling back", e); - try { - delegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, "Failed to roll back", ee); - } - throw e; - } - } else { - for (Object id : getItemIds()) { - removedItems.put((RowId) id, (RowItem) getItem(id)); - cachedItems.remove(id); - } - refresh(); - return true; - } - } - - /*************************************************/ - /** Methods from interface Container.Filterable **/ - /*************************************************/ - - /** - * {@inheritDoc} - */ - - @Override - public void addContainerFilter(Filter filter) - throws UnsupportedFilterException { - // filter.setCaseSensitive(!ignoreCase); - - filters.add(filter); - refresh(); - } - - /** - * {@inheritDoc} - */ - - @Override - public void removeContainerFilter(Filter filter) { - filters.remove(filter); - refresh(); - } - - /** - * {@inheritDoc} - */ - public void addContainerFilter(Object propertyId, String filterString, - boolean ignoreCase, boolean onlyMatchPrefix) { - if (propertyId == null || !propertyIds.contains(propertyId)) { - return; - } - - /* Generate Filter -object */ - String likeStr = onlyMatchPrefix ? filterString + "%" : "%" - + filterString + "%"; - Like like = new Like(propertyId.toString(), likeStr); - like.setCaseSensitive(!ignoreCase); - filters.add(like); - refresh(); - } - - /** - * {@inheritDoc} - */ - public void removeContainerFilters(Object propertyId) { - ArrayList<Filter> toRemove = new ArrayList<Filter>(); - for (Filter f : filters) { - if (f.appliesToProperty(propertyId)) { - toRemove.add(f); - } - } - filters.removeAll(toRemove); - refresh(); - } - - /** - * {@inheritDoc} - */ - - @Override - public void removeAllContainerFilters() { - filters.clear(); - refresh(); - } - - /**********************************************/ - /** Methods from interface Container.Indexed **/ - /**********************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#indexOfId(java.lang.Object) - */ - - @Override - public int indexOfId(Object itemId) { - // First check if the id is in the added items - for (int ix = 0; ix < addedItems.size(); ix++) { - RowItem item = addedItems.get(ix); - if (item.getId().equals(itemId)) { - if (itemPassesFilters(item)) { - updateCount(); - return size + ix; - } else { - return -1; - } - } - } - - if (!containsId(itemId)) { - return -1; - } - if (cachedItems.isEmpty()) { - getPage(); - } - int size = size(); - boolean wrappedAround = false; - while (!wrappedAround) { - for (Integer i : itemIndexes.keySet()) { - if (itemIndexes.get(i).equals(itemId)) { - return i; - } - } - // load in the next page. - int nextIndex = (currentOffset / (pageLength * CACHE_RATIO) + 1) - * (pageLength * CACHE_RATIO); - if (nextIndex >= size) { - // Container wrapped around, start from index 0. - wrappedAround = true; - nextIndex = 0; - } - updateOffsetAndCache(nextIndex); - } - return -1; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#getIdByIndex(int) - */ - - @Override - public Object getIdByIndex(int index) { - if (index < 0 || index > size() - 1) { - return null; - } - if (index < size) { - if (itemIndexes.keySet().contains(index)) { - return itemIndexes.get(index); - } - updateOffsetAndCache(index); - return itemIndexes.get(index); - } else { - // The index is in the added items - int offset = index - size; - return addedItems.get(offset).getId(); - } - } - - /**********************************************/ - /** Methods from interface Container.Ordered **/ - /**********************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) - */ - - @Override - public Object nextItemId(Object itemId) { - return getIdByIndex(indexOfId(itemId) + 1); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) - */ - - @Override - public Object prevItemId(Object itemId) { - return getIdByIndex(indexOfId(itemId) - 1); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#firstItemId() - */ - - @Override - public Object firstItemId() { - updateCount(); - if (size == 0) { - if (addedItems.isEmpty()) { - return null; - } else { - int ix = -1; - do { - ix++; - } while (!itemPassesFilters(addedItems.get(ix)) - && ix < addedItems.size()); - if (ix < addedItems.size()) { - return addedItems.get(ix).getId(); - } - } - } - if (!itemIndexes.containsKey(0)) { - updateOffsetAndCache(0); - } - return itemIndexes.get(0); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#lastItemId() - */ - - @Override - public Object lastItemId() { - if (addedItems.isEmpty()) { - int lastIx = size() - 1; - if (!itemIndexes.containsKey(lastIx)) { - updateOffsetAndCache(size - 1); - } - return itemIndexes.get(lastIx); - } else { - int ix = addedItems.size(); - do { - ix--; - } while (!itemPassesFilters(addedItems.get(ix)) && ix >= 0); - if (ix >= 0) { - return addedItems.get(ix).getId(); - } else { - return null; - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) - */ - - @Override - public boolean isFirstId(Object itemId) { - return firstItemId().equals(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) - */ - - @Override - public boolean isLastId(Object itemId) { - return lastItemId().equals(itemId); - } - - /***********************************************/ - /** Methods from interface Container.Sortable **/ - /***********************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - */ - - @Override - public void sort(Object[] propertyId, boolean[] ascending) { - sorters.clear(); - if (propertyId == null || propertyId.length == 0) { - refresh(); - return; - } - /* Generate OrderBy -objects */ - boolean asc = true; - for (int i = 0; i < propertyId.length; i++) { - /* Check that the property id is valid */ - if (propertyId[i] instanceof String - && propertyIds.contains(propertyId[i])) { - try { - asc = ascending[i]; - } catch (Exception e) { - getLogger().log(Level.WARNING, "", e); - } - sorters.add(new OrderBy((String) propertyId[i], asc)); - } - } - refresh(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() - */ - - @Override - public Collection<?> getSortableContainerPropertyIds() { - return getContainerPropertyIds(); - } - - /**************************************/ - /** Methods specific to SQLContainer **/ - /**************************************/ - - /** - * Refreshes the container - clears all caches and resets size and offset. - * Does NOT remove sorting or filtering rules! - */ - public void refresh() { - sizeDirty = true; - currentOffset = 0; - cachedItems.clear(); - itemIndexes.clear(); - fireContentsChange(); - } - - /** - * Returns modify state of the container. - * - * @return true if contents of this container have been modified - */ - public boolean isModified() { - return !removedItems.isEmpty() || !addedItems.isEmpty() - || !modifiedItems.isEmpty(); - } - - /** - * Set auto commit mode enabled or disabled. Auto commit mode means that all - * changes made to items of this container will be immediately written to - * the underlying data source. - * - * @param autoCommitEnabled - * true to enable auto commit mode - */ - public void setAutoCommit(boolean autoCommitEnabled) { - autoCommit = autoCommitEnabled; - } - - /** - * Returns status of the auto commit mode. - * - * @return true if auto commit mode is enabled - */ - public boolean isAutoCommit() { - return autoCommit; - } - - /** - * Returns the currently set page length. - * - * @return current page length - */ - public int getPageLength() { - return pageLength; - } - - /** - * Sets the page length used in lazy fetching of items from the data source. - * Also resets the cache size to match the new page length. - * - * As a side effect the container will be refreshed. - * - * @param pageLength - * new page length - */ - public void setPageLength(int pageLength) { - setPageLengthInternal(pageLength); - refresh(); - } - - /** - * Sets the page length internally, without refreshing the container. - * - * @param pageLength - * the new page length - */ - private void setPageLengthInternal(int pageLength) { - this.pageLength = pageLength > 0 ? pageLength : DEFAULT_PAGE_LENGTH; - cachedItems.setCacheLimit(CACHE_RATIO * getPageLength()); - } - - /** - * Adds the given OrderBy to this container and refreshes the container - * contents with the new sorting rules. - * - * Note that orderBy.getColumn() must return a column name that exists in - * this container. - * - * @param orderBy - * OrderBy to be added to the container sorting rules - */ - public void addOrderBy(OrderBy orderBy) { - if (orderBy == null) { - return; - } - if (!propertyIds.contains(orderBy.getColumn())) { - throw new IllegalArgumentException( - "The column given for sorting does not exist in this container."); - } - sorters.add(orderBy); - refresh(); - } - - /** - * Commits all the changes, additions and removals made to the items of this - * container. - * - * @throws UnsupportedOperationException - * @throws SQLException - */ - public void commit() throws UnsupportedOperationException, SQLException { - try { - getLogger().log(Level.FINER, - "Commiting changes through delegate..."); - delegate.beginTransaction(); - /* Perform buffered deletions */ - for (RowItem item : removedItems.values()) { - if (!delegate.removeRow(item)) { - throw new SQLException("Removal failed for row with ID: " - + item.getId()); - } - } - /* Perform buffered modifications */ - for (RowItem item : modifiedItems) { - if (delegate.storeRow(item) > 0) { - /* - * Also reset the modified state in the item in case it is - * reused e.g. in a form. - */ - item.commit(); - } else { - delegate.rollback(); - refresh(); - throw new ConcurrentModificationException( - "Item with the ID '" + item.getId() - + "' has been externally modified."); - } - } - /* Perform buffered additions */ - for (RowItem item : addedItems) { - delegate.storeRow(item); - } - delegate.commit(); - removedItems.clear(); - addedItems.clear(); - modifiedItems.clear(); - refresh(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - } catch (SQLException e) { - delegate.rollback(); - throw e; - } catch (OptimisticLockException e) { - delegate.rollback(); - throw e; - } - } - - /** - * Rolls back all the changes, additions and removals made to the items of - * this container. - * - * @throws UnsupportedOperationException - * @throws SQLException - */ - public void rollback() throws UnsupportedOperationException, SQLException { - getLogger().log(Level.FINE, "Rolling back changes..."); - removedItems.clear(); - addedItems.clear(); - modifiedItems.clear(); - refresh(); - } - - /** - * Notifies this container that a property in the given item has been - * modified. The change will be buffered or made instantaneously depending - * on auto commit mode. - * - * @param changedItem - * item that has a modified property - */ - void itemChangeNotification(RowItem changedItem) { - if (autoCommit) { - try { - delegate.beginTransaction(); - if (delegate.storeRow(changedItem) == 0) { - delegate.rollback(); - refresh(); - throw new ConcurrentModificationException( - "Item with the ID '" + changedItem.getId() - + "' has been externally modified."); - } - delegate.commit(); - if (notificationsEnabled) { - CacheFlushNotifier.notifyOfCacheFlush(this); - } - getLogger().log(Level.FINER, "Row updated to DB..."); - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "itemChangeNotification failed, rolling back...", e); - try { - delegate.rollback(); - } catch (SQLException ee) { - /* Nothing can be done here */ - getLogger().log(Level.SEVERE, "Rollback failed", e); - } - throw new RuntimeException(e); - } - } else { - if (!(changedItem.getId() instanceof TemporaryRowId) - && !modifiedItems.contains(changedItem)) { - modifiedItems.add(changedItem); - } - } - } - - /** - * Determines a new offset for updating the row cache. The offset is - * calculated from the given index, and will be fixed to match the start of - * a page, based on the value of pageLength. - * - * @param index - * Index of the item that was requested, but not found in cache - */ - private void updateOffsetAndCache(int index) { - if (itemIndexes.containsKey(index)) { - return; - } - currentOffset = (index / (pageLength * CACHE_RATIO)) - * (pageLength * CACHE_RATIO); - if (currentOffset < 0) { - currentOffset = 0; - } - getPage(); - } - - /** - * Fetches new count of rows from the data source, if needed. - */ - private void updateCount() { - if (!sizeDirty - && new Date().getTime() < sizeUpdated.getTime() - + sizeValidMilliSeconds) { - return; - } - try { - try { - delegate.setFilters(filters); - } catch (UnsupportedOperationException e) { - getLogger().log(Level.FINE, - "The query delegate doesn't support filtering", e); - } - try { - delegate.setOrderBy(sorters); - } catch (UnsupportedOperationException e) { - getLogger().log(Level.FINE, - "The query delegate doesn't support filtering", e); - } - int newSize = delegate.getCount(); - if (newSize != size) { - size = newSize; - refresh(); - } - sizeUpdated = new Date(); - sizeDirty = false; - getLogger().log(Level.FINER, - "Updated row count. New count is: " + size); - } catch (SQLException e) { - throw new RuntimeException("Failed to update item set size.", e); - } - } - - /** - * Fetches property id's (column names and their types) from the data - * source. - * - * @throws SQLException - */ - private void getPropertyIds() throws SQLException { - propertyIds.clear(); - propertyTypes.clear(); - delegate.setFilters(null); - delegate.setOrderBy(null); - ResultSet rs = null; - ResultSetMetaData rsmd = null; - try { - delegate.beginTransaction(); - rs = delegate.getResults(0, 1); - boolean resultExists = rs.next(); - rsmd = rs.getMetaData(); - Class<?> type = null; - for (int i = 1; i <= rsmd.getColumnCount(); i++) { - if (!isColumnIdentifierValid(rsmd.getColumnLabel(i))) { - continue; - } - String colName = rsmd.getColumnLabel(i); - /* - * Make sure not to add the same colName twice. This can easily - * happen if the SQL query joins many tables with an ID column. - */ - if (!propertyIds.contains(colName)) { - propertyIds.add(colName); - } - /* Try to determine the column's JDBC class by all means. */ - if (resultExists && rs.getObject(i) != null) { - type = rs.getObject(i).getClass(); - } else { - try { - type = Class.forName(rsmd.getColumnClassName(i)); - } catch (Exception e) { - getLogger().log(Level.WARNING, "Class not found", e); - /* On failure revert to Object and hope for the best. */ - type = Object.class; - } - } - /* - * Determine read only and nullability status of the column. A - * column is read only if it is reported as either read only or - * auto increment by the database, and also it is set as the - * version column in a TableQuery delegate. - */ - boolean readOnly = rsmd.isAutoIncrement(i) - || rsmd.isReadOnly(i); - if (delegate instanceof TableQuery - && rsmd.getColumnLabel(i).equals( - ((TableQuery) delegate).getVersionColumn())) { - readOnly = true; - } - propertyReadOnly.put(colName, readOnly); - propertyNullable.put(colName, - rsmd.isNullable(i) == ResultSetMetaData.columnNullable); - propertyTypes.put(colName, type); - } - rs.getStatement().close(); - rs.close(); - delegate.commit(); - getLogger().log(Level.FINER, "Property IDs fetched."); - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to fetch property ids, rolling back", e); - try { - delegate.rollback(); - } catch (SQLException e1) { - getLogger().log(Level.SEVERE, "Failed to roll back", e1); - } - try { - if (rs != null) { - if (rs.getStatement() != null) { - rs.getStatement().close(); - } - rs.close(); - } - } catch (SQLException e1) { - getLogger().log(Level.WARNING, "Failed to close session", e1); - } - throw e; - } - } - - /** - * Fetches a page from the data source based on the values of pageLenght and - * currentOffset. Also updates the set of primary keys, used in - * identification of RowItems. - */ - private void getPage() { - updateCount(); - ResultSet rs = null; - ResultSetMetaData rsmd = null; - cachedItems.clear(); - itemIndexes.clear(); - try { - try { - delegate.setOrderBy(sorters); - } catch (UnsupportedOperationException e) { - /* The query delegate doesn't support sorting. */ - /* No need to do anything. */ - getLogger().log(Level.FINE, - "The query delegate doesn't support sorting", e); - } - delegate.beginTransaction(); - rs = delegate.getResults(currentOffset, pageLength * CACHE_RATIO); - rsmd = rs.getMetaData(); - List<String> pKeys = delegate.getPrimaryKeyColumns(); - // } - /* Create new items and column properties */ - ColumnProperty cp = null; - int rowCount = currentOffset; - if (!delegate.implementationRespectsPagingLimits()) { - rowCount = currentOffset = 0; - setPageLengthInternal(size); - } - while (rs.next()) { - List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>(); - /* Generate row itemId based on primary key(s) */ - Object[] itemId = new Object[pKeys.size()]; - for (int i = 0; i < pKeys.size(); i++) { - itemId[i] = rs.getObject(pKeys.get(i)); - } - RowId id = null; - if (pKeys.isEmpty()) { - id = new ReadOnlyRowId(rs.getRow()); - } else { - id = new RowId(itemId); - } - List<String> propertiesToAdd = new ArrayList<String>( - propertyIds); - if (!removedItems.containsKey(id)) { - for (int i = 1; i <= rsmd.getColumnCount(); i++) { - if (!isColumnIdentifierValid(rsmd.getColumnLabel(i))) { - continue; - } - String colName = rsmd.getColumnLabel(i); - Object value = rs.getObject(i); - Class<?> type = value != null ? value.getClass() - : Object.class; - if (value == null) { - for (String propName : propertyTypes.keySet()) { - if (propName.equals(rsmd.getColumnLabel(i))) { - type = propertyTypes.get(propName); - break; - } - } - } - /* - * In case there are more than one column with the same - * name, add only the first one. This can easily happen - * if you join many tables where each table has an ID - * column. - */ - if (propertiesToAdd.contains(colName)) { - cp = new ColumnProperty(colName, - propertyReadOnly.get(colName), - !propertyReadOnly.get(colName), - propertyNullable.get(colName), value, type); - itemProperties.add(cp); - propertiesToAdd.remove(colName); - } - } - /* Cache item */ - itemIndexes.put(rowCount, id); - - // if an item with the id is contained in the modified - // cache, then use this record and add it to the cached - // items. Otherwise create a new item - int modifiedIndex = indexInModifiedCache(id); - if (modifiedIndex != -1) { - cachedItems.put(id, modifiedItems.get(modifiedIndex)); - } else { - cachedItems.put(id, new RowItem(this, id, - itemProperties)); - } - - rowCount++; - } - } - rs.getStatement().close(); - rs.close(); - delegate.commit(); - getLogger().log( - Level.FINER, - "Fetched " + pageLength * CACHE_RATIO - + " rows starting from " + currentOffset); - } catch (SQLException e) { - getLogger().log(Level.WARNING, - "Failed to fetch rows, rolling back", e); - try { - delegate.rollback(); - } catch (SQLException e1) { - getLogger().log(Level.SEVERE, "Failed to roll back", e1); - } - try { - if (rs != null) { - if (rs.getStatement() != null) { - rs.getStatement().close(); - rs.close(); - } - } - } catch (SQLException e1) { - getLogger().log(Level.WARNING, "Failed to close session", e1); - } - throw new RuntimeException("Failed to fetch page.", e); - } - } - - /** - * Returns the index of the item with the given itemId for the modified - * cache. - * - * @param itemId - * @return the index of the item with the itemId in the modified cache. Or - * -1 if not found. - */ - private int indexInModifiedCache(Object itemId) { - for (int ix = 0; ix < modifiedItems.size(); ix++) { - RowItem item = modifiedItems.get(ix); - if (item.getId().equals(itemId)) { - return ix; - } - } - return -1; - } - - private int sizeOfAddedItems() { - return getFilteredAddedItems().size(); - } - - private List<RowItem> getFilteredAddedItems() { - ArrayList<RowItem> filtered = new ArrayList<RowItem>(addedItems); - if (filters != null && !filters.isEmpty()) { - for (RowItem item : addedItems) { - if (!itemPassesFilters(item)) { - filtered.remove(item); - } - } - } - return filtered; - } - - private boolean itemPassesFilters(RowItem item) { - for (Filter filter : filters) { - if (!filter.passesFilter(item.getId(), item)) { - return false; - } - } - return true; - } - - /** - * Checks is the given column identifier valid to be used with SQLContainer. - * Currently the only non-valid identifier is "rownum" when MSSQL or Oracle - * is used. This is due to the way the SELECT queries are constructed in - * order to implement paging in these databases. - * - * @param identifier - * Column identifier - * @return true if the identifier is valid - */ - private boolean isColumnIdentifierValid(String identifier) { - if (identifier.equalsIgnoreCase("rownum") - && delegate instanceof TableQuery) { - TableQuery tq = (TableQuery) delegate; - if (tq.getSqlGenerator() instanceof MSSQLGenerator - || tq.getSqlGenerator() instanceof OracleGenerator) { - return false; - } - } - return true; - } - - /** - * Returns the QueryDelegate set for this SQLContainer. - * - * @return current querydelegate - */ - protected QueryDelegate getQueryDelegate() { - return delegate; - } - - /************************************/ - /** UNSUPPORTED CONTAINER FEATURES **/ - /************************************/ - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object) - */ - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, - * java.lang.Object) - */ - - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object) - */ - - @Override - public Item addItemAt(int index, Object newItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Indexed#addItemAt(int) - */ - - @Override - public Object addItemAt(int index) throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) - */ - - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - /******************************************/ - /** ITEMSETCHANGENOTIFIER IMPLEMENTATION **/ - /******************************************/ - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin - * .data.Container.ItemSetChangeListener) - */ - - @Override - public void addListener(Container.ItemSetChangeListener listener) { - if (itemSetChangeListeners == null) { - itemSetChangeListeners = new LinkedList<Container.ItemSetChangeListener>(); - } - itemSetChangeListeners.add(listener); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin - * .data.Container.ItemSetChangeListener) - */ - - @Override - public void removeListener(Container.ItemSetChangeListener listener) { - if (itemSetChangeListeners != null) { - itemSetChangeListeners.remove(listener); - } - } - - protected void fireContentsChange() { - if (itemSetChangeListeners != null) { - final Object[] l = itemSetChangeListeners.toArray(); - final Container.ItemSetChangeEvent event = new SQLContainer.ItemSetChangeEvent( - this); - for (int i = 0; i < l.length; i++) { - ((Container.ItemSetChangeListener) l[i]) - .containerItemSetChange(event); - } - } - } - - /** - * Simple ItemSetChangeEvent implementation. - */ - @SuppressWarnings("serial") - public static class ItemSetChangeEvent extends EventObject implements - Container.ItemSetChangeEvent { - - private ItemSetChangeEvent(SQLContainer source) { - super(source); - } - - @Override - public Container getContainer() { - return (Container) getSource(); - } - } - - /**************************************************/ - /** ROWIDCHANGELISTENER PASSING TO QUERYDELEGATE **/ - /**************************************************/ - - /** - * Adds a RowIdChangeListener to the QueryDelegate - * - * @param listener - */ - public void addListener(RowIdChangeListener listener) { - if (delegate instanceof QueryDelegate.RowIdChangeNotifier) { - ((QueryDelegate.RowIdChangeNotifier) delegate) - .addListener(listener); - } - } - - /** - * Removes a RowIdChangeListener from the QueryDelegate - * - * @param listener - */ - public void removeListener(RowIdChangeListener listener) { - if (delegate instanceof QueryDelegate.RowIdChangeNotifier) { - ((QueryDelegate.RowIdChangeNotifier) delegate) - .removeListener(listener); - } - } - - /** - * Calling this will enable this SQLContainer to send and receive cache - * flush notifications for its lifetime. - */ - public void enableCacheFlushNotifications() { - if (!notificationsEnabled) { - notificationsEnabled = true; - CacheFlushNotifier.addInstance(this); - } - } - - /******************************************/ - /** Referencing mechanism implementation **/ - /******************************************/ - - /** - * Adds a new reference to the given SQLContainer. In addition to the - * container you must provide the column (property) names used for the - * reference in both this and the referenced SQLContainer. - * - * Note that multiple references pointing to the same SQLContainer are not - * supported. - * - * @param refdCont - * Target SQLContainer of the new reference - * @param refingCol - * Column (property) name in this container storing the (foreign - * key) reference - * @param refdCol - * Column (property) name in the referenced container storing the - * referenced key - */ - public void addReference(SQLContainer refdCont, String refingCol, - String refdCol) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - if (!getContainerPropertyIds().contains(refingCol)) { - throw new IllegalArgumentException( - "Given referencing column name is invalid." - + " Please ensure that this container" - + " contains a property ID named: " + refingCol); - } - if (!refdCont.getContainerPropertyIds().contains(refdCol)) { - throw new IllegalArgumentException( - "Given referenced column name is invalid." - + " Please ensure that the referenced container" - + " contains a property ID named: " + refdCol); - } - if (references.keySet().contains(refdCont)) { - throw new IllegalArgumentException( - "An SQLContainer instance can only be referenced once."); - } - references.put(refdCont, new Reference(refdCont, refingCol, refdCol)); - } - - /** - * Removes the reference pointing to the given SQLContainer. - * - * @param refdCont - * Target SQLContainer of the reference - * @return true if successful, false if the reference did not exist - */ - public boolean removeReference(SQLContainer refdCont) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - return references.remove(refdCont) == null ? false : true; - } - - /** - * Sets the referenced item. The referencing column of the item in this - * container is updated accordingly. - * - * @param itemId - * Item Id of the reference source (from this container) - * @param refdItemId - * Item Id of the reference target (from referenced container) - * @param refdCont - * Target SQLContainer of the reference - * @return true if the referenced item was successfully set, false on - * failure - */ - public boolean setReferencedItem(Object itemId, Object refdItemId, - SQLContainer refdCont) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - Reference r = references.get(refdCont); - if (r == null) { - throw new IllegalArgumentException( - "Reference to the given SQLContainer not defined."); - } - try { - getContainerProperty(itemId, r.getReferencingColumn()).setValue( - refdCont.getContainerProperty(refdItemId, - r.getReferencedColumn())); - return true; - } catch (Exception e) { - getLogger() - .log(Level.WARNING, "Setting referenced item failed.", e); - return false; - } - } - - /** - * Fetches the Item Id of the referenced item from the target SQLContainer. - * - * @param itemId - * Item Id of the reference source (from this container) - * @param refdCont - * Target SQLContainer of the reference - * @return Item Id of the referenced item, or null if not found - */ - public Object getReferencedItemId(Object itemId, SQLContainer refdCont) { - if (refdCont == null) { - throw new IllegalArgumentException( - "Referenced SQLContainer can not be null."); - } - Reference r = references.get(refdCont); - if (r == null) { - throw new IllegalArgumentException( - "Reference to the given SQLContainer not defined."); - } - Object refKey = getContainerProperty(itemId, r.getReferencingColumn()) - .getValue(); - - refdCont.removeAllContainerFilters(); - refdCont.addContainerFilter(new Equal(r.getReferencedColumn(), refKey)); - Object toReturn = refdCont.firstItemId(); - refdCont.removeAllContainerFilters(); - return toReturn; - } - - /** - * Fetches the referenced item from the target SQLContainer. - * - * @param itemId - * Item Id of the reference source (from this container) - * @param refdCont - * Target SQLContainer of the reference - * @return The referenced item, or null if not found - */ - public Item getReferencedItem(Object itemId, SQLContainer refdCont) { - return refdCont.getItem(getReferencedItemId(itemId, refdCont)); - } - - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - } - - private void readObject(java.io.ObjectInputStream in) throws IOException, - ClassNotFoundException { - in.defaultReadObject(); - if (notificationsEnabled) { - /* - * Register instance with CacheFlushNotifier after de-serialization - * if notifications are enabled - */ - CacheFlushNotifier.addInstance(this); - } - } - - private static final Logger getLogger() { - return Logger.getLogger(SQLContainer.class.getName()); - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java b/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java deleted file mode 100644 index 4a48dbf499..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -import java.io.Serializable; - -public class SQLUtil implements Serializable { - /** - * Escapes different special characters in strings that are passed to SQL. - * Replaces the following: - * - * <list> <li>' is replaced with ''</li> <li>\x00 is removed</li> <li>\ is - * replaced with \\</li> <li>" is replaced with \"</li> <li> - * \x1a is removed</li> </list> - * - * Also note! The escaping done here may or may not be enough to prevent any - * and all SQL injections so it is recommended to check user input before - * giving it to the SQLContainer/TableQuery. - * - * @param constant - * @return \\\'\' - */ - public static String escapeSQL(String constant) { - if (constant == null) { - return null; - } - String fixedConstant = constant; - fixedConstant = fixedConstant.replaceAll("\\\\x00", ""); - fixedConstant = fixedConstant.replaceAll("\\\\x1a", ""); - fixedConstant = fixedConstant.replaceAll("'", "''"); - fixedConstant = fixedConstant.replaceAll("\\\\", "\\\\\\\\"); - fixedConstant = fixedConstant.replaceAll("\\\"", "\\\\\""); - return fixedConstant; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java b/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java deleted file mode 100644 index b4bca75a2a..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java +++ /dev/null @@ -1,32 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer; - -public class TemporaryRowId extends RowId { - private static final long serialVersionUID = -641983830469018329L; - - public TemporaryRowId(Object[] id) { - super(id); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof TemporaryRowId)) { - return false; - } - Object[] compId = ((TemporaryRowId) obj).getId(); - return id.equals(compId); - } - - @Override - public String toString() { - return "Temporary row id"; - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java deleted file mode 100644 index 9aa4f7c4be..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java +++ /dev/null @@ -1,72 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.connection; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.sql.DataSource; - -public class J2EEConnectionPool implements JDBCConnectionPool { - - private String dataSourceJndiName; - - private DataSource dataSource = null; - - public J2EEConnectionPool(DataSource dataSource) { - this.dataSource = dataSource; - } - - public J2EEConnectionPool(String dataSourceJndiName) { - this.dataSourceJndiName = dataSourceJndiName; - } - - @Override - public Connection reserveConnection() throws SQLException { - Connection conn = getDataSource().getConnection(); - conn.setAutoCommit(false); - - return conn; - } - - private DataSource getDataSource() throws SQLException { - if (dataSource == null) { - dataSource = lookupDataSource(); - } - return dataSource; - } - - private DataSource lookupDataSource() throws SQLException { - try { - InitialContext ic = new InitialContext(); - return (DataSource) ic.lookup(dataSourceJndiName); - } catch (NamingException e) { - throw new SQLException( - "NamingException - Cannot connect to the database. Cause: " - + e.getMessage()); - } - } - - @Override - public void releaseConnection(Connection conn) { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - Logger.getLogger(J2EEConnectionPool.class.getName()).log( - Level.FINE, "Could not release SQL connection", e); - } - } - } - - @Override - public void destroy() { - dataSource = null; - } - -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java deleted file mode 100644 index cf12461588..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java +++ /dev/null @@ -1,41 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.connection; - -import java.io.Serializable; -import java.sql.Connection; -import java.sql.SQLException; - -/** - * Interface for implementing connection pools to be used with SQLContainer. - */ -public interface JDBCConnectionPool extends Serializable { - /** - * Retrieves a connection. - * - * @return a usable connection to the database - * @throws SQLException - */ - public Connection reserveConnection() throws SQLException; - - /** - * Releases a connection that was retrieved earlier. - * - * Note that depending on implementation, the transaction possibly open in - * the connection may or may not be rolled back. - * - * @param conn - * Connection to be released - */ - public void releaseConnection(Connection conn); - - /** - * Destroys the connection pool: close() is called an all the connections in - * the pool, whether available or reserved. - * - * This method was added to fix PostgreSQL -related issues with connections - * that were left hanging 'idle'. - */ - public void destroy(); -} diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java deleted file mode 100644 index 21760014b9..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java +++ /dev/null @@ -1,168 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.connection; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashSet; -import java.util.Set; - -/** - * Simple implementation of the JDBCConnectionPool interface. Handles loading - * the JDBC driver, setting up the connections and ensuring they are still - * usable upon release. - */ -@SuppressWarnings("serial") -public class SimpleJDBCConnectionPool implements JDBCConnectionPool { - - private int initialConnections = 5; - private int maxConnections = 20; - - private String driverName; - private String connectionUri; - private String userName; - private String password; - - private transient Set<Connection> availableConnections; - private transient Set<Connection> reservedConnections; - - private boolean initialized; - - public SimpleJDBCConnectionPool(String driverName, String connectionUri, - String userName, String password) throws SQLException { - if (driverName == null) { - throw new IllegalArgumentException( - "JDBC driver class name must be given."); - } - if (connectionUri == null) { - throw new IllegalArgumentException( - "Database connection URI must be given."); - } - if (userName == null) { - throw new IllegalArgumentException( - "Database username must be given."); - } - if (password == null) { - throw new IllegalArgumentException( - "Database password must be given."); - } - this.driverName = driverName; - this.connectionUri = connectionUri; - this.userName = userName; - this.password = password; - - /* Initialize JDBC driver */ - try { - Class.forName(driverName).newInstance(); - } catch (Exception ex) { - throw new RuntimeException("Specified JDBC Driver: " + driverName - + " - initialization failed.", ex); - } - } - - public SimpleJDBCConnectionPool(String driverName, String connectionUri, - String userName, String password, int initialConnections, - int maxConnections) throws SQLException { - this(driverName, connectionUri, userName, password); - this.initialConnections = initialConnections; - this.maxConnections = maxConnections; - } - - private void initializeConnections() throws SQLException { - availableConnections = new HashSet<Connection>(initialConnections); - reservedConnections = new HashSet<Connection>(initialConnections); - for (int i = 0; i < initialConnections; i++) { - availableConnections.add(createConnection()); - } - initialized = true; - } - - @Override - public synchronized Connection reserveConnection() throws SQLException { - if (!initialized) { - initializeConnections(); - } - if (availableConnections.isEmpty()) { - if (reservedConnections.size() < maxConnections) { - availableConnections.add(createConnection()); - } else { - throw new SQLException("Connection limit has been reached."); - } - } - - Connection c = availableConnections.iterator().next(); - availableConnections.remove(c); - reservedConnections.add(c); - - return c; - } - - @Override - public synchronized void releaseConnection(Connection conn) { - if (conn == null || !initialized) { - return; - } - /* Try to roll back if necessary */ - try { - if (!conn.getAutoCommit()) { - conn.rollback(); - } - } catch (SQLException e) { - /* Roll back failed, close and discard connection */ - try { - conn.close(); - } catch (SQLException e1) { - /* Nothing needs to be done */ - } - reservedConnections.remove(conn); - return; - } - reservedConnections.remove(conn); - availableConnections.add(conn); - } - - private Connection createConnection() throws SQLException { - Connection c = DriverManager.getConnection(connectionUri, userName, - password); - c.setAutoCommit(false); - if (driverName.toLowerCase().contains("mysql")) { - try { - Statement s = c.createStatement(); - s.execute("SET SESSION sql_mode = 'ANSI'"); - s.close(); - } catch (Exception e) { - // Failed to set ansi mode; continue - } - } - return c; - } - - @Override - public void destroy() { - for (Connection c : availableConnections) { - try { - c.close(); - } catch (SQLException e) { - // No need to do anything - } - } - for (Connection c : reservedConnections) { - try { - c.close(); - } catch (SQLException e) { - // No need to do anything - } - } - - } - - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - initialized = false; - out.defaultWriteObject(); - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java deleted file mode 100644 index ec986fab95..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java +++ /dev/null @@ -1,507 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLContainer; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -@SuppressWarnings("serial") -public class FreeformQuery implements QueryDelegate { - - FreeformQueryDelegate delegate = null; - private String queryString; - private List<String> primaryKeyColumns; - private JDBCConnectionPool connectionPool; - private transient Connection activeConnection = null; - - /** - * Prevent no-parameters instantiation of FreeformQuery - */ - @SuppressWarnings("unused") - private FreeformQuery() { - } - - /** - * Creates a new freeform query delegate to be used with the - * {@link SQLContainer}. - * - * @param queryString - * The actual query to perform. - * @param primaryKeyColumns - * The primary key columns. Read-only mode is forced if this - * parameter is null or empty. - * @param connectionPool - * the JDBCConnectionPool to use to open connections to the SQL - * database. - * @deprecated @see - * {@link FreeformQuery#FreeformQuery(String, JDBCConnectionPool, String...)} - */ - @Deprecated - public FreeformQuery(String queryString, List<String> primaryKeyColumns, - JDBCConnectionPool connectionPool) { - if (primaryKeyColumns == null) { - primaryKeyColumns = new ArrayList<String>(); - } - if (primaryKeyColumns.contains("")) { - throw new IllegalArgumentException( - "The primary key columns contain an empty string!"); - } else if (queryString == null || "".equals(queryString)) { - throw new IllegalArgumentException( - "The query string may not be empty or null!"); - } else if (connectionPool == null) { - throw new IllegalArgumentException( - "The connectionPool may not be null!"); - } - this.queryString = queryString; - this.primaryKeyColumns = Collections - .unmodifiableList(primaryKeyColumns); - this.connectionPool = connectionPool; - } - - /** - * Creates a new freeform query delegate to be used with the - * {@link SQLContainer}. - * - * @param queryString - * The actual query to perform. - * @param connectionPool - * the JDBCConnectionPool to use to open connections to the SQL - * database. - * @param primaryKeyColumns - * The primary key columns. Read-only mode is forced if none are - * provided. (optional) - */ - public FreeformQuery(String queryString, JDBCConnectionPool connectionPool, - String... primaryKeyColumns) { - this(queryString, Arrays.asList(primaryKeyColumns), connectionPool); - } - - /** - * This implementation of getCount() actually fetches all records from the - * database, which might be a performance issue. Override this method with a - * SELECT COUNT(*) ... query if this is too slow for your needs. - * - * {@inheritDoc} - */ - @Override - public int getCount() throws SQLException { - // First try the delegate - int count = countByDelegate(); - if (count < 0) { - // Couldn't use the delegate, use the bad way. - Connection conn = getConnection(); - Statement statement = conn.createStatement( - ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_READ_ONLY); - - ResultSet rs = statement.executeQuery(queryString); - if (rs.last()) { - count = rs.getRow(); - } else { - count = 0; - } - rs.close(); - statement.close(); - releaseConnection(conn); - } - return count; - } - - @SuppressWarnings("deprecation") - private int countByDelegate() throws SQLException { - int count = -1; - if (delegate == null) { - return count; - } - /* First try using prepared statement */ - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getCountStatement(); - Connection c = getConnection(); - PreparedStatement pstmt = c.prepareStatement(sh - .getQueryString()); - sh.setParameterValuesToStatement(pstmt); - ResultSet rs = pstmt.executeQuery(); - rs.next(); - count = rs.getInt(1); - rs.close(); - pstmt.clearParameters(); - pstmt.close(); - releaseConnection(c); - return count; - } catch (UnsupportedOperationException e) { - // Count statement generation not supported - } - } - /* Try using regular statement */ - try { - String countQuery = delegate.getCountQuery(); - if (countQuery != null) { - Connection conn = getConnection(); - Statement statement = conn.createStatement(); - ResultSet rs = statement.executeQuery(countQuery); - rs.next(); - count = rs.getInt(1); - rs.close(); - statement.close(); - releaseConnection(conn); - return count; - } - } catch (UnsupportedOperationException e) { - // Count query generation not supported - } - return count; - } - - private Connection getConnection() throws SQLException { - if (activeConnection != null) { - return activeConnection; - } - return connectionPool.reserveConnection(); - } - - /** - * Fetches the results for the query. This implementation always fetches the - * entire record set, ignoring the offset and page length parameters. In - * order to support lazy loading of records, you must supply a - * FreeformQueryDelegate that implements the - * FreeformQueryDelegate.getQueryString(int,int) method. - * - * @throws SQLException - * - * @see FreeformQueryDelegate#getQueryString(int, int) - */ - @Override - @SuppressWarnings("deprecation") - public ResultSet getResults(int offset, int pagelength) throws SQLException { - if (activeConnection == null) { - throw new SQLException("No active transaction!"); - } - String query = queryString; - if (delegate != null) { - /* First try using prepared statement */ - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getQueryStatement(offset, pagelength); - PreparedStatement pstmt = activeConnection - .prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - return pstmt.executeQuery(); - } catch (UnsupportedOperationException e) { - // Statement generation not supported, continue... - } - } - try { - query = delegate.getQueryString(offset, pagelength); - } catch (UnsupportedOperationException e) { - // This is fine, we'll just use the default queryString. - } - } - Statement statement = activeConnection.createStatement(); - ResultSet rs = statement.executeQuery(query); - return rs; - } - - @Override - @SuppressWarnings("deprecation") - public boolean implementationRespectsPagingLimits() { - if (delegate == null) { - return false; - } - /* First try using prepared statement */ - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getCountStatement(); - if (sh != null && sh.getQueryString() != null - && sh.getQueryString().length() > 0) { - return true; - } - } catch (UnsupportedOperationException e) { - // Statement generation not supported, continue... - } - } - try { - String queryString = delegate.getQueryString(0, 50); - return queryString != null && queryString.length() > 0; - } catch (UnsupportedOperationException e) { - return false; - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setFilters(java - * .util.List) - */ - @Override - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException { - if (delegate != null) { - delegate.setFilters(filters); - } else if (filters != null) { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setOrderBy(java - * .util.List) - */ - @Override - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException { - if (delegate != null) { - delegate.setOrderBy(orderBys); - } else if (orderBys != null) { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin - * .data.util.sqlcontainer.RowItem) - */ - @Override - public int storeRow(RowItem row) throws SQLException { - if (activeConnection == null) { - throw new IllegalStateException("No transaction is active!"); - } else if (primaryKeyColumns.isEmpty()) { - throw new UnsupportedOperationException( - "Cannot store items fetched with a read-only freeform query!"); - } - if (delegate != null) { - return delegate.storeRow(activeConnection, row); - } else { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#removeRow(com.vaadin - * .data.util.sqlcontainer.RowItem) - */ - @Override - public boolean removeRow(RowItem row) throws SQLException { - if (activeConnection == null) { - throw new IllegalStateException("No transaction is active!"); - } else if (primaryKeyColumns.isEmpty()) { - throw new UnsupportedOperationException( - "Cannot remove items fetched with a read-only freeform query!"); - } - if (delegate != null) { - return delegate.removeRow(activeConnection, row); - } else { - throw new UnsupportedOperationException( - "FreeFormQueryDelegate not set!"); - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#beginTransaction() - */ - @Override - public synchronized void beginTransaction() - throws UnsupportedOperationException, SQLException { - if (activeConnection != null) { - throw new IllegalStateException("A transaction is already active!"); - } - activeConnection = connectionPool.reserveConnection(); - activeConnection.setAutoCommit(false); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#commit() - */ - @Override - public synchronized void commit() throws UnsupportedOperationException, - SQLException { - if (activeConnection == null) { - throw new SQLException("No active transaction"); - } - if (!activeConnection.getAutoCommit()) { - activeConnection.commit(); - } - connectionPool.releaseConnection(activeConnection); - activeConnection = null; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#rollback() - */ - @Override - public synchronized void rollback() throws UnsupportedOperationException, - SQLException { - if (activeConnection == null) { - throw new SQLException("No active transaction"); - } - activeConnection.rollback(); - connectionPool.releaseConnection(activeConnection); - activeConnection = null; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#getPrimaryKeyColumns - * () - */ - @Override - public List<String> getPrimaryKeyColumns() { - return primaryKeyColumns; - } - - public String getQueryString() { - return queryString; - } - - public FreeformQueryDelegate getDelegate() { - return delegate; - } - - public void setDelegate(FreeformQueryDelegate delegate) { - this.delegate = delegate; - } - - /** - * This implementation of the containsRowWithKey method rewrites existing - * WHERE clauses in the query string. The logic is, however, not very - * complex and some times can do the Wrong Thing<sup>TM</sup>. For the - * situations where this logic is not enough, you can implement the - * getContainsRowQueryString method in FreeformQueryDelegate and this will - * be used instead of the logic. - * - * @see FreeformQueryDelegate#getContainsRowQueryString(Object...) - * - */ - @Override - @SuppressWarnings("deprecation") - public boolean containsRowWithKey(Object... keys) throws SQLException { - String query = null; - boolean contains = false; - if (delegate != null) { - if (delegate instanceof FreeformStatementDelegate) { - try { - StatementHelper sh = ((FreeformStatementDelegate) delegate) - .getContainsRowQueryStatement(keys); - Connection c = getConnection(); - PreparedStatement pstmt = c.prepareStatement(sh - .getQueryString()); - sh.setParameterValuesToStatement(pstmt); - ResultSet rs = pstmt.executeQuery(); - contains = rs.next(); - rs.close(); - pstmt.clearParameters(); - pstmt.close(); - releaseConnection(c); - return contains; - } catch (UnsupportedOperationException e) { - // Statement generation not supported, continue... - } - } - try { - query = delegate.getContainsRowQueryString(keys); - } catch (UnsupportedOperationException e) { - query = modifyWhereClause(keys); - } - } else { - query = modifyWhereClause(keys); - } - Connection conn = getConnection(); - try { - Statement statement = conn.createStatement(); - ResultSet rs = statement.executeQuery(query); - contains = rs.next(); - rs.close(); - statement.close(); - } finally { - releaseConnection(conn); - } - return contains; - } - - /** - * Releases the connection if it is not part of an active transaction. - * - * @param conn - * the connection to release - */ - private void releaseConnection(Connection conn) { - if (conn != activeConnection) { - connectionPool.releaseConnection(conn); - } - } - - private String modifyWhereClause(Object... keys) { - // Build the where rules for the provided keys - StringBuffer where = new StringBuffer(); - for (int ix = 0; ix < primaryKeyColumns.size(); ix++) { - where.append(QueryBuilder.quote(primaryKeyColumns.get(ix))); - if (keys[ix] == null) { - where.append(" IS NULL"); - } else { - where.append(" = '").append(keys[ix]).append("'"); - } - if (ix < primaryKeyColumns.size() - 1) { - where.append(" AND "); - } - } - // Is there already a WHERE clause in the query string? - int index = queryString.toLowerCase().indexOf("where "); - if (index > -1) { - // Rewrite the where clause - return queryString.substring(0, index) + "WHERE " + where + " AND " - + queryString.substring(index + 6); - } - // Append a where clause - return queryString + " WHERE " + where; - } - - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - try { - rollback(); - } catch (SQLException ignored) { - } - out.defaultWriteObject(); - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java deleted file mode 100644 index 433d742be8..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java +++ /dev/null @@ -1,118 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowItem; - -public interface FreeformQueryDelegate extends Serializable { - /** - * Should return the SQL query string to be performed. This method is - * responsible for gluing together the select query from the filters and the - * order by conditions if these are supported. - * - * @param offset - * the first record (row) to fetch. - * @param pagelength - * the number of records (rows) to fetch. 0 means all records - * starting from offset. - * @deprecated Implement {@link FreeformStatementDelegate} instead of - * {@link FreeformQueryDelegate} - */ - @Deprecated - public String getQueryString(int offset, int limit) - throws UnsupportedOperationException; - - /** - * Generates and executes a query to determine the current row count from - * the DB. Row count will be fetched using filters that are currently set to - * the QueryDelegate. - * - * @return row count - * @throws SQLException - * @deprecated Implement {@link FreeformStatementDelegate} instead of - * {@link FreeformQueryDelegate} - */ - @Deprecated - public String getCountQuery() throws UnsupportedOperationException; - - /** - * Sets the filters to apply when performing the SQL query. These are - * translated into a WHERE clause. Default filtering mode will be used. - * - * @param filters - * The filters to apply. - * @throws UnsupportedOperationException - * if the implementation doesn't support filtering. - */ - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException; - - /** - * Sets the order in which to retrieve rows from the database. The result - * can be ordered by zero or more columns and each column can be in - * ascending or descending order. These are translated into an ORDER BY - * clause in the SQL query. - * - * @param orderBys - * A list of the OrderBy conditions. - * @throws UnsupportedOperationException - * if the implementation doesn't support ordering. - */ - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException; - - /** - * Stores a row in the database. The implementation of this interface - * decides how to identify whether to store a new row or update an existing - * one. - * - * @param conn - * the JDBC connection to use - * @param row - * RowItem to be stored or updated. - * @throws UnsupportedOperationException - * if the implementation is read only. - * @throws SQLException - */ - public int storeRow(Connection conn, RowItem row) - throws UnsupportedOperationException, SQLException; - - /** - * Removes the given RowItem from the database. - * - * @param conn - * the JDBC connection to use - * @param row - * RowItem to be removed - * @return true on success - * @throws UnsupportedOperationException - * @throws SQLException - */ - public boolean removeRow(Connection conn, RowItem row) - throws UnsupportedOperationException, SQLException; - - /** - * Generates an SQL Query string that allows the user of the FreeformQuery - * class to customize the query string used by the - * FreeformQuery.containsRowWithKeys() method. This is useful for cases when - * the logic in the containsRowWithKeys method is not enough to support more - * complex free form queries. - * - * @param keys - * the values of the primary keys - * @throws UnsupportedOperationException - * to use the default logic in FreeformQuery - * @deprecated Implement {@link FreeformStatementDelegate} instead of - * {@link FreeformQueryDelegate} - */ - @Deprecated - public String getContainsRowQueryString(Object... keys) - throws UnsupportedOperationException; -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java deleted file mode 100644 index 95521c5019..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query; - -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -/** - * FreeformStatementDelegate is an extension to FreeformQueryDelegate that - * provides definitions for methods that produce StatementHelper objects instead - * of basic query strings. This allows the FreeformQuery query delegate to use - * PreparedStatements instead of regular Statement when accessing the database. - * - * Due to the injection protection and other benefits of prepared statements, it - * is advisable to implement this interface instead of the FreeformQueryDelegate - * whenever possible. - */ -public interface FreeformStatementDelegate extends FreeformQueryDelegate { - /** - * Should return a new instance of StatementHelper that contains the query - * string and parameter values required to create a PreparedStatement. This - * method is responsible for gluing together the select query from the - * filters and the order by conditions if these are supported. - * - * @param offset - * the first record (row) to fetch. - * @param pagelength - * the number of records (rows) to fetch. 0 means all records - * starting from offset. - */ - public StatementHelper getQueryStatement(int offset, int limit) - throws UnsupportedOperationException; - - /** - * Should return a new instance of StatementHelper that contains the query - * string and parameter values required to create a PreparedStatement that - * will fetch the row count from the DB. Row count should be fetched using - * filters that are currently set to the QueryDelegate. - */ - public StatementHelper getCountStatement() - throws UnsupportedOperationException; - - /** - * Should return a new instance of StatementHelper that contains the query - * string and parameter values required to create a PreparedStatement used - * by the FreeformQuery.containsRowWithKeys() method. This is useful for - * cases when the default logic in said method is not enough to support more - * complex free form queries. - * - * @param keys - * the values of the primary keys - * @throws UnsupportedOperationException - * to use the default logic in FreeformQuery - */ - public StatementHelper getContainsRowQueryStatement(Object... keys) - throws UnsupportedOperationException; -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java b/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java deleted file mode 100644 index 8ebe10067e..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java +++ /dev/null @@ -1,46 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; - -/** - * OrderBy represents a sorting rule to be applied to a query made by the - * SQLContainer's QueryDelegate. - * - * The sorting rule is simple and contains only the affected column's name and - * the direction of the sort. - */ -public class OrderBy implements Serializable { - private String column; - private boolean isAscending; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private OrderBy() { - } - - public OrderBy(String column, boolean isAscending) { - setColumn(column); - setAscending(isAscending); - } - - public void setColumn(String column) { - this.column = column; - } - - public String getColumn() { - return column; - } - - public void setAscending(boolean isAscending) { - this.isAscending = isAscending; - } - - public boolean isAscending() { - return isAscending; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java deleted file mode 100644 index 6e4396fad1..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java +++ /dev/null @@ -1,211 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query; - -import java.io.Serializable; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowId; -import com.vaadin.data.util.sqlcontainer.RowItem; - -public interface QueryDelegate extends Serializable { - /** - * Generates and executes a query to determine the current row count from - * the DB. Row count will be fetched using filters that are currently set to - * the QueryDelegate. - * - * @return row count - * @throws SQLException - */ - public int getCount() throws SQLException; - - /** - * Executes a paged SQL query and returns the ResultSet. The query is - * defined through implementations of this QueryDelegate interface. - * - * @param offset - * the first item of the page to load - * @param pagelength - * the length of the page to load - * @return a ResultSet containing the rows of the page - * @throws SQLException - * if the database access fails. - */ - public ResultSet getResults(int offset, int pagelength) throws SQLException; - - /** - * Allows the SQLContainer implementation to check whether the QueryDelegate - * implementation implements paging in the getResults method. - * - * @see QueryDelegate#getResults(int, int) - * - * @return true if the delegate implements paging - */ - public boolean implementationRespectsPagingLimits(); - - /** - * Sets the filters to apply when performing the SQL query. These are - * translated into a WHERE clause. Default filtering mode will be used. - * - * @param filters - * The filters to apply. - * @throws UnsupportedOperationException - * if the implementation doesn't support filtering. - */ - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException; - - /** - * Sets the order in which to retrieve rows from the database. The result - * can be ordered by zero or more columns and each column can be in - * ascending or descending order. These are translated into an ORDER BY - * clause in the SQL query. - * - * @param orderBys - * A list of the OrderBy conditions. - * @throws UnsupportedOperationException - * if the implementation doesn't support ordering. - */ - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException; - - /** - * Stores a row in the database. The implementation of this interface - * decides how to identify whether to store a new row or update an existing - * one. - * - * @param columnToValueMap - * A map containing the values for all columns to be stored or - * updated. - * @return the number of affected rows in the database table - * @throws UnsupportedOperationException - * if the implementation is read only. - */ - public int storeRow(RowItem row) throws UnsupportedOperationException, - SQLException; - - /** - * Removes the given RowItem from the database. - * - * @param row - * RowItem to be removed - * @return true on success - * @throws UnsupportedOperationException - * @throws SQLException - */ - public boolean removeRow(RowItem row) throws UnsupportedOperationException, - SQLException; - - /** - * Starts a new database transaction. Used when storing multiple changes. - * - * Note that if a transaction is already open, it will be rolled back when a - * new transaction is started. - * - * @throws SQLException - * if the database access fails. - */ - public void beginTransaction() throws SQLException; - - /** - * Commits a transaction. If a transaction is not open nothing should - * happen. - * - * @throws SQLException - * if the database access fails. - */ - public void commit() throws SQLException; - - /** - * Rolls a transaction back. If a transaction is not open nothing should - * happen. - * - * @throws SQLException - * if the database access fails. - */ - public void rollback() throws SQLException; - - /** - * Returns a list of primary key column names. The list is either fetched - * from the database (TableQuery) or given as an argument depending on - * implementation. - * - * @return - */ - public List<String> getPrimaryKeyColumns(); - - /** - * Performs a query to find out whether the SQL table contains a row with - * the given set of primary keys. - * - * @param keys - * the primary keys - * @return true if the SQL table contains a row with the provided keys - * @throws SQLException - */ - public boolean containsRowWithKey(Object... keys) throws SQLException; - - /************************/ - /** ROWID CHANGE EVENT **/ - /************************/ - - /** - * An <code>Event</code> object specifying the old and new RowId of an added - * item after the addition has been successfully committed. - */ - public interface RowIdChangeEvent extends Serializable { - /** - * Gets the old (temporary) RowId of the added row that raised this - * event. - * - * @return old RowId - */ - public RowId getOldRowId(); - - /** - * Gets the new, possibly database assigned RowId of the added row that - * raised this event. - * - * @return new RowId - */ - public RowId getNewRowId(); - } - - /** RowId change listener interface. */ - public interface RowIdChangeListener extends Serializable { - /** - * Lets the listener know that a RowId has been changed. - * - * @param event - */ - public void rowIdChange(QueryDelegate.RowIdChangeEvent event); - } - - /** - * The interface for adding and removing <code>RowIdChangeEvent</code> - * listeners. By implementing this interface a class explicitly announces - * that it will generate a <code>RowIdChangeEvent</code> when it performs a - * database commit that may change the RowId. - */ - public interface RowIdChangeNotifier extends Serializable { - /** - * Adds a RowIdChangeListener for the object. - * - * @param listener - * listener to be added - */ - public void addListener(QueryDelegate.RowIdChangeListener listener); - - /** - * Removes the specified RowIdChangeListener from the object. - * - * @param listener - * listener to be removed - */ - public void removeListener(QueryDelegate.RowIdChangeListener listener); - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java deleted file mode 100644 index d0606704f7..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java +++ /dev/null @@ -1,715 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EventObject; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.sqlcontainer.ColumnProperty; -import com.vaadin.data.util.sqlcontainer.OptimisticLockException; -import com.vaadin.data.util.sqlcontainer.RowId; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLUtil; -import com.vaadin.data.util.sqlcontainer.TemporaryRowId; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -@SuppressWarnings("serial") -public class TableQuery implements QueryDelegate, - QueryDelegate.RowIdChangeNotifier { - - /** Table name, primary key column name(s) and version column name */ - private String tableName; - private List<String> primaryKeyColumns; - private String versionColumn; - - /** Currently set Filters and OrderBys */ - private List<Filter> filters; - private List<OrderBy> orderBys; - - /** SQLGenerator instance to use for generating queries */ - private SQLGenerator sqlGenerator; - - /** Fields related to Connection and Transaction handling */ - private JDBCConnectionPool connectionPool; - private transient Connection activeConnection; - private boolean transactionOpen; - - /** Row ID change listeners */ - private LinkedList<RowIdChangeListener> rowIdChangeListeners; - /** Row ID change events, stored until commit() is called */ - private final List<RowIdChangeEvent> bufferedEvents = new ArrayList<RowIdChangeEvent>(); - - /** Set to true to output generated SQL Queries to System.out */ - private boolean debug = false; - - /** Prevent no-parameters instantiation of TableQuery */ - @SuppressWarnings("unused") - private TableQuery() { - } - - /** - * Creates a new TableQuery using the given connection pool, SQL generator - * and table name to fetch the data from. All parameters must be non-null. - * - * @param tableName - * Name of the database table to connect to - * @param connectionPool - * Connection pool for accessing the database - * @param sqlGenerator - * SQL query generator implementation - */ - public TableQuery(String tableName, JDBCConnectionPool connectionPool, - SQLGenerator sqlGenerator) { - if (tableName == null || tableName.trim().length() < 1 - || connectionPool == null || sqlGenerator == null) { - throw new IllegalArgumentException( - "All parameters must be non-null and a table name must be given."); - } - this.tableName = tableName; - this.sqlGenerator = sqlGenerator; - this.connectionPool = connectionPool; - fetchMetaData(); - } - - /** - * Creates a new TableQuery using the given connection pool and table name - * to fetch the data from. All parameters must be non-null. The default SQL - * generator will be used for queries. - * - * @param tableName - * Name of the database table to connect to - * @param connectionPool - * Connection pool for accessing the database - */ - public TableQuery(String tableName, JDBCConnectionPool connectionPool) { - this(tableName, connectionPool, new DefaultSQLGenerator()); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getCount() - */ - @Override - public int getCount() throws SQLException { - getLogger().log(Level.FINE, "Fetching count..."); - StatementHelper sh = sqlGenerator.generateSelectQuery(tableName, - filters, null, 0, 0, "COUNT(*)"); - boolean shouldCloseTransaction = false; - if (!transactionOpen) { - shouldCloseTransaction = true; - beginTransaction(); - } - ResultSet r = executeQuery(sh); - r.next(); - int count = r.getInt(1); - r.getStatement().close(); - r.close(); - if (shouldCloseTransaction) { - commit(); - } - return count; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getResults(int, - * int) - */ - @Override - public ResultSet getResults(int offset, int pagelength) throws SQLException { - StatementHelper sh; - /* - * If no ordering is explicitly set, results will be ordered by the - * first primary key column. - */ - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy(primaryKeyColumns.get(0), true)); - sh = sqlGenerator.generateSelectQuery(tableName, filters, ob, - offset, pagelength, null); - } else { - sh = sqlGenerator.generateSelectQuery(tableName, filters, orderBys, - offset, pagelength, null); - } - return executeQuery(sh); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate# - * implementationRespectsPagingLimits() - */ - @Override - public boolean implementationRespectsPagingLimits() { - return true; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin - * .addon.sqlcontainer.RowItem) - */ - @Override - public int storeRow(RowItem row) throws UnsupportedOperationException, - SQLException { - if (row == null) { - throw new IllegalArgumentException("Row argument must be non-null."); - } - StatementHelper sh; - int result = 0; - if (row.getId() instanceof TemporaryRowId) { - setVersionColumnFlagInProperty(row); - sh = sqlGenerator.generateInsertQuery(tableName, row); - result = executeUpdateReturnKeys(sh, row); - } else { - setVersionColumnFlagInProperty(row); - sh = sqlGenerator.generateUpdateQuery(tableName, row); - result = executeUpdate(sh); - } - if (versionColumn != null && result == 0) { - throw new OptimisticLockException( - "Someone else changed the row that was being updated.", - row.getId()); - } - return result; - } - - private void setVersionColumnFlagInProperty(RowItem row) { - ColumnProperty versionProperty = (ColumnProperty) row - .getItemProperty(versionColumn); - if (versionProperty != null) { - versionProperty.setVersionColumn(true); - } - } - - /** - * Inserts the given row in the database table immediately. Begins and - * commits the transaction needed. This method was added specifically to - * solve the problem of returning the final RowId immediately on the - * SQLContainer.addItem() call when auto commit mode is enabled in the - * SQLContainer. - * - * @param row - * RowItem to add to the database - * @return Final RowId of the added row - * @throws SQLException - */ - public RowId storeRowImmediately(RowItem row) throws SQLException { - beginTransaction(); - /* Set version column, if one is provided */ - setVersionColumnFlagInProperty(row); - /* Generate query */ - StatementHelper sh = sqlGenerator.generateInsertQuery(tableName, row); - PreparedStatement pstmt = activeConnection.prepareStatement( - sh.getQueryString(), primaryKeyColumns.toArray(new String[0])); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); - int result = pstmt.executeUpdate(); - if (result > 0) { - /* - * If affected rows exist, we'll get the new RowId, commit the - * transaction and return the new RowId. - */ - ResultSet generatedKeys = pstmt.getGeneratedKeys(); - RowId newId = getNewRowId(row, generatedKeys); - generatedKeys.close(); - pstmt.clearParameters(); - pstmt.close(); - commit(); - return newId; - } else { - pstmt.clearParameters(); - pstmt.close(); - /* On failure return null */ - return null; - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#setFilters(java.util - * .List) - */ - @Override - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException { - if (filters == null) { - this.filters = null; - return; - } - this.filters = Collections.unmodifiableList(filters); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#setOrderBy(java.util - * .List) - */ - @Override - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException { - if (orderBys == null) { - this.orderBys = null; - return; - } - this.orderBys = Collections.unmodifiableList(orderBys); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#beginTransaction() - */ - @Override - public void beginTransaction() throws UnsupportedOperationException, - SQLException { - if (transactionOpen && activeConnection != null) { - throw new IllegalStateException(); - } - - getLogger().log(Level.FINE, "DB -> begin transaction"); - activeConnection = connectionPool.reserveConnection(); - activeConnection.setAutoCommit(false); - transactionOpen = true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#commit() - */ - @Override - public void commit() throws UnsupportedOperationException, SQLException { - if (transactionOpen && activeConnection != null) { - getLogger().log(Level.FINE, "DB -> commit"); - activeConnection.commit(); - connectionPool.releaseConnection(activeConnection); - } else { - throw new SQLException("No active transaction"); - } - transactionOpen = false; - - /* Handle firing row ID change events */ - RowIdChangeEvent[] unFiredEvents = bufferedEvents - .toArray(new RowIdChangeEvent[] {}); - bufferedEvents.clear(); - if (rowIdChangeListeners != null && !rowIdChangeListeners.isEmpty()) { - for (RowIdChangeListener r : rowIdChangeListeners) { - for (RowIdChangeEvent e : unFiredEvents) { - r.rowIdChange(e); - } - } - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#rollback() - */ - @Override - public void rollback() throws UnsupportedOperationException, SQLException { - if (transactionOpen && activeConnection != null) { - getLogger().log(Level.FINE, "DB -> rollback"); - activeConnection.rollback(); - connectionPool.releaseConnection(activeConnection); - } else { - throw new SQLException("No active transaction"); - } - transactionOpen = false; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#getPrimaryKeyColumns() - */ - @Override - public List<String> getPrimaryKeyColumns() { - return Collections.unmodifiableList(primaryKeyColumns); - } - - public String getVersionColumn() { - return versionColumn; - } - - public void setVersionColumn(String column) { - versionColumn = column; - } - - public String getTableName() { - return tableName; - } - - public SQLGenerator getSqlGenerator() { - return sqlGenerator; - } - - /** - * Executes the given query string using either the active connection if a - * transaction is already open, or a new connection from this query's - * connection pool. - * - * @param sh - * an instance of StatementHelper, containing the query string - * and parameter values. - * @return ResultSet of the query - * @throws SQLException - */ - private ResultSet executeQuery(StatementHelper sh) throws SQLException { - Connection c = null; - if (transactionOpen && activeConnection != null) { - c = activeConnection; - } else { - throw new SQLException("No active transaction!"); - } - PreparedStatement pstmt = c.prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); - return pstmt.executeQuery(); - } - - /** - * Executes the given update query string using either the active connection - * if a transaction is already open, or a new connection from this query's - * connection pool. - * - * @param sh - * an instance of StatementHelper, containing the query string - * and parameter values. - * @return Number of affected rows - * @throws SQLException - */ - private int executeUpdate(StatementHelper sh) throws SQLException { - Connection c = null; - PreparedStatement pstmt = null; - try { - if (transactionOpen && activeConnection != null) { - c = activeConnection; - } else { - c = connectionPool.reserveConnection(); - } - pstmt = c.prepareStatement(sh.getQueryString()); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); - int retval = pstmt.executeUpdate(); - return retval; - } finally { - if (pstmt != null) { - pstmt.clearParameters(); - pstmt.close(); - } - if (!transactionOpen) { - connectionPool.releaseConnection(c); - } - } - } - - /** - * Executes the given update query string using either the active connection - * if a transaction is already open, or a new connection from this query's - * connection pool. - * - * Additionally adds a new RowIdChangeEvent to the event buffer. - * - * @param sh - * an instance of StatementHelper, containing the query string - * and parameter values. - * @param row - * the row item to update - * @return Number of affected rows - * @throws SQLException - */ - private int executeUpdateReturnKeys(StatementHelper sh, RowItem row) - throws SQLException { - Connection c = null; - PreparedStatement pstmt = null; - ResultSet genKeys = null; - try { - if (transactionOpen && activeConnection != null) { - c = activeConnection; - } else { - c = connectionPool.reserveConnection(); - } - pstmt = c.prepareStatement(sh.getQueryString(), - primaryKeyColumns.toArray(new String[0])); - sh.setParameterValuesToStatement(pstmt); - getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); - int result = pstmt.executeUpdate(); - genKeys = pstmt.getGeneratedKeys(); - RowId newId = getNewRowId(row, genKeys); - bufferedEvents.add(new RowIdChangeEvent(row.getId(), newId)); - return result; - } finally { - if (genKeys != null) { - genKeys.close(); - } - if (pstmt != null) { - pstmt.clearParameters(); - pstmt.close(); - } - if (!transactionOpen) { - connectionPool.releaseConnection(c); - } - } - } - - /** - * Fetches name(s) of primary key column(s) from DB metadata. - * - * Also tries to get the escape string to be used in search strings. - */ - private void fetchMetaData() { - Connection c = null; - try { - c = connectionPool.reserveConnection(); - DatabaseMetaData dbmd = c.getMetaData(); - if (dbmd != null) { - tableName = SQLUtil.escapeSQL(tableName); - ResultSet tables = dbmd.getTables(null, null, tableName, null); - if (!tables.next()) { - tables = dbmd.getTables(null, null, - tableName.toUpperCase(), null); - if (!tables.next()) { - throw new IllegalArgumentException( - "Table with the name \"" - + tableName - + "\" was not found. Check your database contents."); - } else { - tableName = tableName.toUpperCase(); - } - } - tables.close(); - ResultSet rs = dbmd.getPrimaryKeys(null, null, tableName); - List<String> names = new ArrayList<String>(); - while (rs.next()) { - names.add(rs.getString("COLUMN_NAME")); - } - rs.close(); - if (!names.isEmpty()) { - primaryKeyColumns = names; - } - if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) { - throw new IllegalArgumentException( - "Primary key constraints have not been defined for the table \"" - + tableName - + "\". Use FreeFormQuery to access this table."); - } - for (String colName : primaryKeyColumns) { - if (colName.equalsIgnoreCase("rownum")) { - if (getSqlGenerator() instanceof MSSQLGenerator - || getSqlGenerator() instanceof MSSQLGenerator) { - throw new IllegalArgumentException( - "When using Oracle or MSSQL, a primary key column" - + " named \'rownum\' is not allowed!"); - } - } - } - } - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - connectionPool.releaseConnection(c); - } - } - - private RowId getNewRowId(RowItem row, ResultSet genKeys) { - try { - /* Fetch primary key values and generate a map out of them. */ - Map<String, Object> values = new HashMap<String, Object>(); - ResultSetMetaData rsmd = genKeys.getMetaData(); - int colCount = rsmd.getColumnCount(); - if (genKeys.next()) { - for (int i = 1; i <= colCount; i++) { - values.put(rsmd.getColumnName(i), genKeys.getObject(i)); - } - } - /* Generate new RowId */ - List<Object> newRowId = new ArrayList<Object>(); - if (values.size() == 1) { - if (primaryKeyColumns.size() == 1) { - newRowId.add(values.get(values.keySet().iterator().next())); - } else { - for (String s : primaryKeyColumns) { - if (!((ColumnProperty) row.getItemProperty(s)) - .isReadOnlyChangeAllowed()) { - newRowId.add(values.get(values.keySet().iterator() - .next())); - } else { - newRowId.add(values.get(s)); - } - } - } - } else { - for (String s : primaryKeyColumns) { - newRowId.add(values.get(s)); - } - } - return new RowId(newRowId.toArray()); - } catch (Exception e) { - getLogger().log(Level.FINE, - "Failed to fetch key values on insert: " + e.getMessage()); - return null; - } - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#removeRow(com.vaadin - * .addon.sqlcontainer.RowItem) - */ - @Override - public boolean removeRow(RowItem row) throws UnsupportedOperationException, - SQLException { - getLogger().log(Level.FINE, - "Removing row with id: " + row.getId().getId()[0].toString()); - if (executeUpdate(sqlGenerator.generateDeleteQuery(getTableName(), - primaryKeyColumns, versionColumn, row)) == 1) { - return true; - } - if (versionColumn != null) { - throw new OptimisticLockException( - "Someone else changed the row that was being deleted.", - row.getId()); - } - return false; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.addon.sqlcontainer.query.QueryDelegate#containsRowWithKey( - * java.lang.Object[]) - */ - @Override - public boolean containsRowWithKey(Object... keys) throws SQLException { - ArrayList<Filter> filtersAndKeys = new ArrayList<Filter>(); - if (filters != null) { - filtersAndKeys.addAll(filters); - } - int ix = 0; - for (String colName : primaryKeyColumns) { - filtersAndKeys.add(new Equal(colName, keys[ix])); - ix++; - } - StatementHelper sh = sqlGenerator.generateSelectQuery(tableName, - filtersAndKeys, orderBys, 0, 0, "*"); - - boolean shouldCloseTransaction = false; - if (!transactionOpen) { - shouldCloseTransaction = true; - beginTransaction(); - } - ResultSet rs = null; - try { - rs = executeQuery(sh); - boolean contains = rs.next(); - return contains; - } finally { - if (rs != null) { - if (rs.getStatement() != null) { - rs.getStatement().close(); - } - rs.close(); - } - if (shouldCloseTransaction) { - commit(); - } - } - } - - /** - * Custom writeObject to call rollback() if object is serialized. - */ - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - try { - rollback(); - } catch (SQLException ignored) { - } - out.defaultWriteObject(); - } - - /** - * Simple RowIdChangeEvent implementation. - */ - public class RowIdChangeEvent extends EventObject implements - QueryDelegate.RowIdChangeEvent { - private final RowId oldId; - private final RowId newId; - - private RowIdChangeEvent(RowId oldId, RowId newId) { - super(oldId); - this.oldId = oldId; - this.newId = newId; - } - - @Override - public RowId getNewRowId() { - return newId; - } - - @Override - public RowId getOldRowId() { - return oldId; - } - } - - /** - * Adds RowIdChangeListener to this query - */ - @Override - public void addListener(RowIdChangeListener listener) { - if (rowIdChangeListeners == null) { - rowIdChangeListeners = new LinkedList<QueryDelegate.RowIdChangeListener>(); - } - rowIdChangeListeners.add(listener); - } - - /** - * Removes the given RowIdChangeListener from this query - */ - @Override - public void removeListener(RowIdChangeListener listener) { - if (rowIdChangeListeners != null) { - rowIdChangeListeners.remove(listener); - } - } - - private static final Logger getLogger() { - return Logger.getLogger(TableQuery.class.getName()); - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java deleted file mode 100644 index 6485330541..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java +++ /dev/null @@ -1,367 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.ColumnProperty; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLUtil; -import com.vaadin.data.util.sqlcontainer.TemporaryRowId; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.StringDecorator; - -/** - * Generates generic SQL that is supported by HSQLDB, MySQL and PostgreSQL. - * - * @author Jonatan Kronqvist / Vaadin Ltd - */ -@SuppressWarnings("serial") -public class DefaultSQLGenerator implements SQLGenerator { - - private Class<? extends StatementHelper> statementHelperClass = null; - - public DefaultSQLGenerator() { - - } - - /** - * Create a new DefaultSqlGenerator instance that uses the given - * implementation of {@link StatementHelper} - * - * @param statementHelper - */ - public DefaultSQLGenerator( - Class<? extends StatementHelper> statementHelperClazz) { - this(); - statementHelperClass = statementHelperClazz; - } - - /** - * Construct a DefaultSQLGenerator with the specified identifiers for start - * and end of quoted strings. The identifiers may be different depending on - * the database engine and it's settings. - * - * @param quoteStart - * the identifier (character) denoting the start of a quoted - * string - * @param quoteEnd - * the identifier (character) denoting the end of a quoted string - */ - public DefaultSQLGenerator(String quoteStart, String quoteEnd) { - QueryBuilder.setStringDecorator(new StringDecorator(quoteStart, - quoteEnd)); - } - - /** - * Same as {@link #DefaultSQLGenerator(String, String)} but with support for - * custom {@link StatementHelper} implementation. - * - * @param quoteStart - * @param quoteEnd - * @param statementHelperClazz - */ - public DefaultSQLGenerator(String quoteStart, String quoteEnd, - Class<? extends StatementHelper> statementHelperClazz) { - this(quoteStart, quoteEnd); - statementHelperClass = statementHelperClazz; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateSelectQuery(java.lang.String, java.util.List, java.util.List, - * int, int, java.lang.String) - */ - @Override - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - toSelect = toSelect == null ? "*" : toSelect; - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("SELECT " + toSelect + " FROM ").append( - SQLUtil.escapeSQL(tableName)); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - if (pagelength != 0) { - generateLimits(query, offset, pagelength); - } - sh.setQueryString(query.toString()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateUpdateQuery(java.lang.String, - * com.vaadin.addon.sqlcontainer.RowItem) - */ - @Override - public StatementHelper generateUpdateQuery(String tableName, RowItem item) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - if (item == null) { - throw new IllegalArgumentException("Updated item must be given."); - } - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("UPDATE ").append(tableName).append(" SET"); - - /* Generate column<->value and rowidentifiers map */ - Map<String, Object> columnToValueMap = generateColumnToValueMap(item); - Map<String, Object> rowIdentifiers = generateRowIdentifiers(item); - /* Generate columns and values to update */ - boolean first = true; - for (String column : columnToValueMap.keySet()) { - if (first) { - query.append(" " + QueryBuilder.quote(column) + " = ?"); - } else { - query.append(", " + QueryBuilder.quote(column) + " = ?"); - } - sh.addParameterValue(columnToValueMap.get(column), item - .getItemProperty(column).getType()); - first = false; - } - /* Generate identifiers for the row to be updated */ - first = true; - for (String column : rowIdentifiers.keySet()) { - if (first) { - query.append(" WHERE " + QueryBuilder.quote(column) + " = ?"); - } else { - query.append(" AND " + QueryBuilder.quote(column) + " = ?"); - } - sh.addParameterValue(rowIdentifiers.get(column), item - .getItemProperty(column).getType()); - first = false; - } - sh.setQueryString(query.toString()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateInsertQuery(java.lang.String, - * com.vaadin.addon.sqlcontainer.RowItem) - */ - @Override - public StatementHelper generateInsertQuery(String tableName, RowItem item) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - if (item == null) { - throw new IllegalArgumentException("New item must be given."); - } - if (!(item.getId() instanceof TemporaryRowId)) { - throw new IllegalArgumentException( - "Cannot generate an insert query for item already in database."); - } - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("INSERT INTO ").append(tableName).append(" ("); - - /* Generate column<->value map */ - Map<String, Object> columnToValueMap = generateColumnToValueMap(item); - /* Generate column names for insert query */ - boolean first = true; - for (String column : columnToValueMap.keySet()) { - if (!first) { - query.append(", "); - } - query.append(QueryBuilder.quote(column)); - first = false; - } - - /* Generate values for insert query */ - query.append(") VALUES ("); - first = true; - for (String column : columnToValueMap.keySet()) { - if (!first) { - query.append(", "); - } - query.append("?"); - sh.addParameterValue(columnToValueMap.get(column), item - .getItemProperty(column).getType()); - first = false; - } - query.append(")"); - sh.setQueryString(query.toString()); - return sh; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator# - * generateDeleteQuery(java.lang.String, - * com.vaadin.addon.sqlcontainer.RowItem) - */ - @Override - public StatementHelper generateDeleteQuery(String tableName, - List<String> primaryKeyColumns, String versionColumn, RowItem item) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - if (item == null) { - throw new IllegalArgumentException( - "Item to be deleted must be given."); - } - if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) { - throw new IllegalArgumentException( - "Valid keyColumnNames must be provided."); - } - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - query.append("DELETE FROM ").append(tableName).append(" WHERE "); - int count = 1; - for (String keyColName : primaryKeyColumns) { - if ((this instanceof MSSQLGenerator || this instanceof OracleGenerator) - && keyColName.equalsIgnoreCase("rownum")) { - count++; - continue; - } - if (count > 1) { - query.append(" AND "); - } - if (item.getItemProperty(keyColName).getValue() != null) { - query.append(QueryBuilder.quote(keyColName) + " = ?"); - sh.addParameterValue(item.getItemProperty(keyColName) - .getValue(), item.getItemProperty(keyColName).getType()); - } - count++; - } - if (versionColumn != null) { - query.append(String.format(" AND %s = ?", - QueryBuilder.quote(versionColumn))); - sh.addParameterValue( - item.getItemProperty(versionColumn).getValue(), item - .getItemProperty(versionColumn).getType()); - } - - sh.setQueryString(query.toString()); - return sh; - } - - /** - * Generates sorting rules as an ORDER BY -clause - * - * @param sb - * StringBuffer to which the clause is appended. - * @param o - * OrderBy object to be added into the sb. - * @param firstOrderBy - * If true, this is the first OrderBy. - * @return - */ - protected StringBuffer generateOrderBy(StringBuffer sb, OrderBy o, - boolean firstOrderBy) { - if (firstOrderBy) { - sb.append(" ORDER BY "); - } else { - sb.append(", "); - } - sb.append(QueryBuilder.quote(o.getColumn())); - if (o.isAscending()) { - sb.append(" ASC"); - } else { - sb.append(" DESC"); - } - return sb; - } - - /** - * Generates the LIMIT and OFFSET clause. - * - * @param sb - * StringBuffer to which the clause is appended. - * @param offset - * Value for offset. - * @param pagelength - * Value for pagelength. - * @return StringBuffer with LIMIT and OFFSET clause added. - */ - protected StringBuffer generateLimits(StringBuffer sb, int offset, - int pagelength) { - sb.append(" LIMIT ").append(pagelength).append(" OFFSET ") - .append(offset); - return sb; - } - - protected Map<String, Object> generateColumnToValueMap(RowItem item) { - Map<String, Object> columnToValueMap = new HashMap<String, Object>(); - for (Object id : item.getItemPropertyIds()) { - ColumnProperty cp = (ColumnProperty) item.getItemProperty(id); - /* Prevent "rownum" usage as a column name if MSSQL or ORACLE */ - if ((this instanceof MSSQLGenerator || this instanceof OracleGenerator) - && cp.getPropertyId().equalsIgnoreCase("rownum")) { - continue; - } - Object value = cp.getValue() == null ? null : cp.getValue(); - /* Only include properties whose read-only status can be altered */ - if (cp.isReadOnlyChangeAllowed() && !cp.isVersionColumn()) { - columnToValueMap.put(cp.getPropertyId(), value); - } - } - return columnToValueMap; - } - - protected Map<String, Object> generateRowIdentifiers(RowItem item) { - Map<String, Object> rowIdentifiers = new HashMap<String, Object>(); - for (Object id : item.getItemPropertyIds()) { - ColumnProperty cp = (ColumnProperty) item.getItemProperty(id); - /* Prevent "rownum" usage as a column name if MSSQL or ORACLE */ - if ((this instanceof MSSQLGenerator || this instanceof OracleGenerator) - && cp.getPropertyId().equalsIgnoreCase("rownum")) { - continue; - } - Object value = cp.getValue() == null ? null : cp.getValue(); - if (!cp.isReadOnlyChangeAllowed() || cp.isVersionColumn()) { - rowIdentifiers.put(cp.getPropertyId(), value); - } - } - return rowIdentifiers; - } - - /** - * Returns the statement helper for the generator. Override this to handle - * platform specific data types. - * - * @see http://dev.vaadin.com/ticket/9148 - * @return a new instance of the statement helper - */ - protected StatementHelper getStatementHelper() { - if (statementHelperClass == null) { - return new StatementHelper(); - } - - try { - return statementHelperClass.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException( - "Unable to instantiate custom StatementHelper", e); - } catch (IllegalAccessException e) { - throw new RuntimeException( - "Unable to instantiate custom StatementHelper", e); - } - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java deleted file mode 100644 index 13ef1d0090..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java +++ /dev/null @@ -1,101 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator; - -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -@SuppressWarnings("serial") -public class MSSQLGenerator extends DefaultSQLGenerator { - - public MSSQLGenerator() { - - } - - /** - * Construct a MSSQLGenerator with the specified identifiers for start and - * end of quoted strings. The identifiers may be different depending on the - * database engine and it's settings. - * - * @param quoteStart - * the identifier (character) denoting the start of a quoted - * string - * @param quoteEnd - * the identifier (character) denoting the end of a quoted string - */ - public MSSQLGenerator(String quoteStart, String quoteEnd) { - super(quoteStart, quoteEnd); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.DefaultSQLGenerator# - * generateSelectQuery(java.lang.String, java.util.List, - * com.vaadin.addon.sqlcontainer.query.FilteringMode, java.util.List, int, - * int, java.lang.String) - */ - @Override - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - /* Adjust offset and page length parameters to match "row numbers" */ - offset = pagelength > 1 ? ++offset : offset; - pagelength = pagelength > 1 ? --pagelength : pagelength; - toSelect = toSelect == null ? "*" : toSelect; - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - - /* Row count request is handled here */ - if ("COUNT(*)".equalsIgnoreCase(toSelect)) { - query.append(String.format( - "SELECT COUNT(*) AS %s FROM (SELECT * FROM %s", - QueryBuilder.quote("rowcount"), tableName)); - if (filters != null && !filters.isEmpty()) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(") AS t"); - sh.setQueryString(query.toString()); - return sh; - } - - /* SELECT without row number constraints */ - if (offset == 0 && pagelength == 0) { - query.append("SELECT ").append(toSelect).append(" FROM ") - .append(tableName); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - sh.setQueryString(query.toString()); - return sh; - } - - /* Remaining SELECT cases are handled here */ - query.append("SELECT * FROM (SELECT row_number() OVER ("); - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - query.append(") AS rownum, " + toSelect + " FROM ").append(tableName); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(") AS a WHERE a.rownum BETWEEN ").append(offset) - .append(" AND ").append(Integer.toString(offset + pagelength)); - sh.setQueryString(query.toString()); - return sh; - } -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java deleted file mode 100644 index 43a562d3a8..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java +++ /dev/null @@ -1,112 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator; - -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -@SuppressWarnings("serial") -public class OracleGenerator extends DefaultSQLGenerator { - - public OracleGenerator() { - - } - - public OracleGenerator(Class<? extends StatementHelper> statementHelperClazz) { - super(statementHelperClazz); - } - - /** - * Construct an OracleSQLGenerator with the specified identifiers for start - * and end of quoted strings. The identifiers may be different depending on - * the database engine and it's settings. - * - * @param quoteStart - * the identifier (character) denoting the start of a quoted - * string - * @param quoteEnd - * the identifier (character) denoting the end of a quoted string - */ - public OracleGenerator(String quoteStart, String quoteEnd) { - super(quoteStart, quoteEnd); - } - - public OracleGenerator(String quoteStart, String quoteEnd, - Class<? extends StatementHelper> statementHelperClazz) { - super(quoteStart, quoteEnd, statementHelperClazz); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.addon.sqlcontainer.query.generator.DefaultSQLGenerator# - * generateSelectQuery(java.lang.String, java.util.List, - * com.vaadin.addon.sqlcontainer.query.FilteringMode, java.util.List, int, - * int, java.lang.String) - */ - @Override - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect) { - if (tableName == null || tableName.trim().equals("")) { - throw new IllegalArgumentException("Table name must be given."); - } - /* Adjust offset and page length parameters to match "row numbers" */ - offset = pagelength > 1 ? ++offset : offset; - pagelength = pagelength > 1 ? --pagelength : pagelength; - toSelect = toSelect == null ? "*" : toSelect; - StatementHelper sh = getStatementHelper(); - StringBuffer query = new StringBuffer(); - - /* Row count request is handled here */ - if ("COUNT(*)".equalsIgnoreCase(toSelect)) { - query.append(String.format( - "SELECT COUNT(*) AS %s FROM (SELECT * FROM %s", - QueryBuilder.quote("rowcount"), tableName)); - if (filters != null && !filters.isEmpty()) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(")"); - sh.setQueryString(query.toString()); - return sh; - } - - /* SELECT without row number constraints */ - if (offset == 0 && pagelength == 0) { - query.append("SELECT ").append(toSelect).append(" FROM ") - .append(tableName); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - sh.setQueryString(query.toString()); - return sh; - } - - /* Remaining SELECT cases are handled here */ - query.append(String - .format("SELECT * FROM (SELECT x.*, ROWNUM AS %s FROM (SELECT %s FROM %s", - QueryBuilder.quote("rownum"), toSelect, tableName)); - if (filters != null) { - query.append(QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (orderBys != null) { - for (OrderBy o : orderBys) { - generateOrderBy(query, o, orderBys.indexOf(o) == 0); - } - } - query.append(String.format(") x) WHERE %s BETWEEN %d AND %d", - QueryBuilder.quote("rownum"), offset, offset + pagelength)); - sh.setQueryString(query.toString()); - return sh; - } - -}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java deleted file mode 100644 index dde7077eee..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java +++ /dev/null @@ -1,88 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator; - -import java.io.Serializable; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; - -/** - * The SQLGenerator interface is meant to be implemented for each different SQL - * syntax that is to be supported. By default there are implementations for - * HSQLDB, MySQL, PostgreSQL, MSSQL and Oracle syntaxes. - * - * @author Jonatan Kronqvist / Vaadin Ltd - */ -public interface SQLGenerator extends Serializable { - /** - * Generates a SELECT query with the provided parameters. Uses default - * filtering mode (INCLUSIVE). - * - * @param tableName - * Name of the table queried - * @param filters - * The filters, converted into a WHERE clause - * @param orderBys - * The the ordering conditions, converted into an ORDER BY clause - * @param offset - * The offset of the first row to be included - * @param pagelength - * The number of rows to be returned when the query executes - * @param toSelect - * String containing what to select, e.g. "*", "COUNT(*)" - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateSelectQuery(String tableName, - List<Filter> filters, List<OrderBy> orderBys, int offset, - int pagelength, String toSelect); - - /** - * Generates an UPDATE query with the provided parameters. - * - * @param tableName - * Name of the table queried - * @param item - * RowItem containing the updated values update. - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateUpdateQuery(String tableName, RowItem item); - - /** - * Generates an INSERT query for inserting a new row with the provided - * values. - * - * @param tableName - * Name of the table queried - * @param item - * New RowItem to be inserted into the database. - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateInsertQuery(String tableName, RowItem item); - - /** - * Generates a DELETE query for deleting data related to the given RowItem - * from the database. - * - * @param tableName - * Name of the table queried - * @param primaryKeyColumns - * the names of the columns holding the primary key. Usually just - * one column, but might be several. - * @param versionColumn - * the column containing the version number of the row, null if - * versioning (optimistic locking) not enabled. - * @param item - * Item to be deleted from the database - * @return StatementHelper instance containing the query string for a - * PreparedStatement and the values required for the parameters - */ - public StatementHelper generateDeleteQuery(String tableName, - List<String> primaryKeyColumns, String versionColumn, RowItem item); -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java deleted file mode 100644 index b012ce7685..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java +++ /dev/null @@ -1,163 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * StatementHelper is a simple helper class that assists TableQuery and the - * query generators in filling a PreparedStatement. The actual statement is - * generated by the query generator methods, but the resulting statement and all - * the parameter values are stored in an instance of StatementHelper. - * - * This class will also fill the values with correct setters into the - * PreparedStatement on request. - */ -public class StatementHelper implements Serializable { - - private String queryString; - - private List<Object> parameters = new ArrayList<Object>(); - private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>(); - - public StatementHelper() { - } - - public void setQueryString(String queryString) { - this.queryString = queryString; - } - - public String getQueryString() { - return queryString; - } - - public void addParameterValue(Object parameter) { - if (parameter != null) { - parameters.add(parameter); - dataTypes.put(parameters.size() - 1, parameter.getClass()); - } else { - throw new IllegalArgumentException( - "You cannot add null parameters using addParamaters(Object). " - + "Use addParameters(Object,Class) instead"); - } - } - - public void addParameterValue(Object parameter, Class<?> type) { - parameters.add(parameter); - dataTypes.put(parameters.size() - 1, type); - } - - public void setParameterValuesToStatement(PreparedStatement pstmt) - throws SQLException { - for (int i = 0; i < parameters.size(); i++) { - if (parameters.get(i) == null) { - handleNullValue(i, pstmt); - } else { - pstmt.setObject(i + 1, parameters.get(i)); - } - } - - /* - * The following list contains the data types supported by - * PreparedStatement but not supported by SQLContainer: - * - * [The list is provided as PreparedStatement method signatures] - * - * setNCharacterStream(int parameterIndex, Reader value) - * - * setNClob(int parameterIndex, NClob value) - * - * setNString(int parameterIndex, String value) - * - * setRef(int parameterIndex, Ref x) - * - * setRowId(int parameterIndex, RowId x) - * - * setSQLXML(int parameterIndex, SQLXML xmlObject) - * - * setBytes(int parameterIndex, byte[] x) - * - * setCharacterStream(int parameterIndex, Reader reader) - * - * setClob(int parameterIndex, Clob x) - * - * setURL(int parameterIndex, URL x) - * - * setArray(int parameterIndex, Array x) - * - * setAsciiStream(int parameterIndex, InputStream x) - * - * setBinaryStream(int parameterIndex, InputStream x) - * - * setBlob(int parameterIndex, Blob x) - */ - } - - private void handleNullValue(int i, PreparedStatement pstmt) - throws SQLException { - if (BigDecimal.class.equals(dataTypes.get(i))) { - pstmt.setBigDecimal(i + 1, null); - } else if (Boolean.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.BOOLEAN); - } else if (Byte.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.SMALLINT); - } else if (Date.class.equals(dataTypes.get(i))) { - pstmt.setDate(i + 1, null); - } else if (Double.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.DOUBLE); - } else if (Float.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.FLOAT); - } else if (Integer.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.INTEGER); - } else if (Long.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.BIGINT); - } else if (Short.class.equals(dataTypes.get(i))) { - pstmt.setNull(i + 1, Types.SMALLINT); - } else if (String.class.equals(dataTypes.get(i))) { - pstmt.setString(i + 1, null); - } else if (Time.class.equals(dataTypes.get(i))) { - pstmt.setTime(i + 1, null); - } else if (Timestamp.class.equals(dataTypes.get(i))) { - pstmt.setTimestamp(i + 1, null); - } else { - - if (handleUnrecognizedTypeNullValue(i, pstmt, dataTypes)) { - return; - } - - throw new SQLException("Data type not supported by SQLContainer: " - + parameters.get(i).getClass().toString()); - } - } - - /** - * Handle unrecognized null values. Override this to handle null values for - * platform specific data types that are not handled by the default - * implementation of the {@link StatementHelper}. - * - * @param i - * @param pstmt - * @param dataTypes2 - * - * @return true if handled, false otherwise - * - * @see {@link http://dev.vaadin.com/ticket/9148} - */ - protected boolean handleUnrecognizedTypeNullValue(int i, - PreparedStatement pstmt, Map<Integer, Class<?>> dataTypes) - throws SQLException { - return false; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java deleted file mode 100644 index 251a543a8a..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java +++ /dev/null @@ -1,23 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.And; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class AndTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof And; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - return QueryBuilder.group(QueryBuilder.getJoinedFilterString( - ((And) filter).getFilters(), "AND", sh)); - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java deleted file mode 100644 index 4fcaf759ea..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java +++ /dev/null @@ -1,25 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Between; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class BetweenTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Between; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Between between = (Between) filter; - sh.addParameterValue(between.getStartValue()); - sh.addParameterValue(between.getEndValue()); - return QueryBuilder.quote(between.getPropertyId()) + " BETWEEN ? AND ?"; - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java deleted file mode 100644 index 4293e1d630..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Compare; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class CompareTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Compare; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Compare compare = (Compare) filter; - sh.addParameterValue(compare.getValue()); - String prop = QueryBuilder.quote(compare.getPropertyId()); - switch (compare.getOperation()) { - case EQUAL: - return prop + " = ?"; - case GREATER: - return prop + " > ?"; - case GREATER_OR_EQUAL: - return prop + " >= ?"; - case LESS: - return prop + " < ?"; - case LESS_OR_EQUAL: - return prop + " <= ?"; - default: - return ""; - } - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java deleted file mode 100644 index 84af9d5c97..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java +++ /dev/null @@ -1,16 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import java.io.Serializable; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public interface FilterTranslator extends Serializable { - public boolean translatesFilter(Filter filter); - - public String getWhereStringForFilter(Filter filter, StatementHelper sh); - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java deleted file mode 100644 index a2a6cd2c09..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java +++ /dev/null @@ -1,22 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.IsNull; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class IsNullTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof IsNull; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - IsNull in = (IsNull) filter; - return QueryBuilder.quote(in.getPropertyId()) + " IS NULL"; - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java deleted file mode 100644 index 25a85caec0..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class LikeTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Like; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Like like = (Like) filter; - if (like.isCaseSensitive()) { - sh.addParameterValue(like.getValue()); - return QueryBuilder.quote(like.getPropertyId()) + " LIKE ?"; - } else { - sh.addParameterValue(like.getValue().toUpperCase()); - return "UPPER(" + QueryBuilder.quote(like.getPropertyId()) - + ") LIKE ?"; - } - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java deleted file mode 100644 index 5dfbe240e7..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.IsNull; -import com.vaadin.data.util.filter.Not; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class NotTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Not; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - Not not = (Not) filter; - if (not.getFilter() instanceof IsNull) { - IsNull in = (IsNull) not.getFilter(); - return QueryBuilder.quote(in.getPropertyId()) + " IS NOT NULL"; - } - return "NOT " - + QueryBuilder.getWhereStringForFilter(not.getFilter(), sh); - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java deleted file mode 100644 index 2f0ed814e0..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java +++ /dev/null @@ -1,23 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Or; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class OrTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof Or; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - return QueryBuilder.group(QueryBuilder.getJoinedFilterString( - ((Or) filter).getFilters(), "OR", sh)); - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java deleted file mode 100644 index 24be8963e0..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class QueryBuilder implements Serializable { - - private static ArrayList<FilterTranslator> filterTranslators = new ArrayList<FilterTranslator>(); - private static StringDecorator stringDecorator = new StringDecorator("\"", - "\""); - - static { - /* Register all default filter translators */ - addFilterTranslator(new AndTranslator()); - addFilterTranslator(new OrTranslator()); - addFilterTranslator(new LikeTranslator()); - addFilterTranslator(new BetweenTranslator()); - addFilterTranslator(new CompareTranslator()); - addFilterTranslator(new NotTranslator()); - addFilterTranslator(new IsNullTranslator()); - addFilterTranslator(new SimpleStringTranslator()); - } - - public synchronized static void addFilterTranslator( - FilterTranslator translator) { - filterTranslators.add(translator); - } - - /** - * Allows specification of a custom ColumnQuoter instance that handles - * quoting of column names for the current DB dialect. - * - * @param decorator - * the ColumnQuoter instance to use. - */ - public static void setStringDecorator(StringDecorator decorator) { - stringDecorator = decorator; - } - - public static String quote(Object str) { - return stringDecorator.quote(str); - } - - public static String group(String str) { - return stringDecorator.group(str); - } - - /** - * Constructs and returns a string representing the filter that can be used - * in a WHERE clause. - * - * @param filter - * the filter to translate - * @param sh - * the statement helper to update with the value(s) of the filter - * @return a string representing the filter. - */ - public synchronized static String getWhereStringForFilter(Filter filter, - StatementHelper sh) { - for (FilterTranslator ft : filterTranslators) { - if (ft.translatesFilter(filter)) { - return ft.getWhereStringForFilter(filter, sh); - } - } - return ""; - } - - public static String getJoinedFilterString(Collection<Filter> filters, - String joinString, StatementHelper sh) { - StringBuilder result = new StringBuilder(); - for (Filter f : filters) { - result.append(getWhereStringForFilter(f, sh)); - result.append(" ").append(joinString).append(" "); - } - // Remove the last instance of joinString - result.delete(result.length() - joinString.length() - 2, - result.length()); - return result.toString(); - } - - public static String getWhereStringForFilters(List<Filter> filters, - StatementHelper sh) { - if (filters == null || filters.isEmpty()) { - return ""; - } - StringBuilder where = new StringBuilder(" WHERE "); - where.append(getJoinedFilterString(filters, "AND", sh)); - return where.toString(); - } -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java deleted file mode 100644 index f108003535..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class SimpleStringTranslator implements FilterTranslator { - - @Override - public boolean translatesFilter(Filter filter) { - return filter instanceof SimpleStringFilter; - } - - @Override - public String getWhereStringForFilter(Filter filter, StatementHelper sh) { - SimpleStringFilter ssf = (SimpleStringFilter) filter; - // Create a Like filter based on the SimpleStringFilter and execute the - // LikeTranslator - String likeStr = ssf.isOnlyMatchPrefix() ? ssf.getFilterString() + "%" - : "%" + ssf.getFilterString() + "%"; - Like like = new Like(ssf.getPropertyId().toString(), likeStr); - like.setCaseSensitive(!ssf.isIgnoreCase()); - return new LikeTranslator().getWhereStringForFilter(like, sh); - } - -} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java deleted file mode 100644 index 8d2eabb5bc..0000000000 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java +++ /dev/null @@ -1,58 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.util.sqlcontainer.query.generator.filter; - -import java.io.Serializable; - -/** - * The StringDecorator knows how to produce a quoted string using the specified - * quote start and quote end characters. It also handles grouping of a string - * (surrounding it in parenthesis). - * - * Extend this class if you need to support special characters for grouping - * (parenthesis). - * - * @author Vaadin Ltd - */ -public class StringDecorator implements Serializable { - - private final String quoteStart; - private final String quoteEnd; - - /** - * Constructs a StringDecorator that uses the quoteStart and quoteEnd - * characters to create quoted strings. - * - * @param quoteStart - * the character denoting the start of a quote. - * @param quoteEnd - * the character denoting the end of a quote. - */ - public StringDecorator(String quoteStart, String quoteEnd) { - this.quoteStart = quoteStart; - this.quoteEnd = quoteEnd; - } - - /** - * Surround a string with quote characters. - * - * @param str - * the string to quote - * @return the quoted string - */ - public String quote(Object str) { - return quoteStart + str + quoteEnd; - } - - /** - * Groups a string by surrounding it in parenthesis - * - * @param str - * the string to group - * @return the grouped string - */ - public String group(String str) { - return "(" + str + ")"; - } -} diff --git a/src/com/vaadin/data/validator/AbstractStringValidator.java b/src/com/vaadin/data/validator/AbstractStringValidator.java deleted file mode 100644 index 5267cc7b7b..0000000000 --- a/src/com/vaadin/data/validator/AbstractStringValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * Validator base class for validating strings. - * <p> - * To include the value that failed validation in the exception message you can - * use "{0}" in the error message. This will be replaced with the failed value - * (converted to string using {@link #toString()}) or "null" if the value is - * null. - * </p> - * - * @author Vaadin Ltd. - * @version @VERSION@ - * @since 5.4 - */ -@SuppressWarnings("serial") -public abstract class AbstractStringValidator extends AbstractValidator<String> { - - /** - * Constructs a validator for strings. - * - * <p> - * Null and empty string values are always accepted. To reject empty values, - * set the field being validated as required. - * </p> - * - * @param errorMessage - * the message to be included in an {@link InvalidValueException} - * (with "{0}" replaced by the value that failed validation). - * */ - public AbstractStringValidator(String errorMessage) { - super(errorMessage); - } - - @Override - public Class<String> getType() { - return String.class; - } -} diff --git a/src/com/vaadin/data/validator/AbstractValidator.java b/src/com/vaadin/data/validator/AbstractValidator.java deleted file mode 100644 index 8febe5338a..0000000000 --- a/src/com/vaadin/data/validator/AbstractValidator.java +++ /dev/null @@ -1,139 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -import com.vaadin.data.Validator; - -/** - * Abstract {@link com.vaadin.data.Validator Validator} implementation that - * provides a basic Validator implementation except the - * {@link #isValidValue(Object)} method. - * <p> - * To include the value that failed validation in the exception message you can - * use "{0}" in the error message. This will be replaced with the failed value - * (converted to string using {@link #toString()}) or "null" if the value is - * null. - * </p> - * <p> - * The default implementation of AbstractValidator does not support HTML in - * error messages. To enable HTML support, override - * {@link InvalidValueException#getHtmlMessage()} and throw such exceptions from - * {@link #validate(Object)}. - * </p> - * <p> - * Since Vaadin 7, subclasses can either implement {@link #validate(Object)} - * directly or implement {@link #isValidValue(Object)} when migrating legacy - * applications. To check validity, {@link #validate(Object)} should be used. - * </p> - * - * @param <T> - * The type - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - */ -public abstract class AbstractValidator<T> implements Validator { - - /** - * Error message that is included in an {@link InvalidValueException} if - * such is thrown. - */ - private String errorMessage; - - /** - * Constructs a validator with the given error message. - * - * @param errorMessage - * the message to be included in an {@link InvalidValueException} - * (with "{0}" replaced by the value that failed validation). - */ - public AbstractValidator(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * Since Vaadin 7, subclasses of AbstractValidator should override - * {@link #isValidValue(Object)} or {@link #validate(Object)} instead of - * {@link #isValid(Object)}. {@link #validate(Object)} should normally be - * used to check values. - * - * @param value - * @return true if the value is valid - */ - public boolean isValid(Object value) { - try { - validate(value); - return true; - } catch (InvalidValueException e) { - return false; - } - } - - /** - * Internally check the validity of a value. This method can be used to - * perform validation in subclasses if customization of the error message is - * not needed. Otherwise, subclasses should override - * {@link #validate(Object)} and the return value of this method is ignored. - * - * This method should not be called from outside the validator class itself. - * - * @param value - * @return - */ - protected abstract boolean isValidValue(T value); - - @Override - public void validate(Object value) throws InvalidValueException { - // isValidType ensures that value can safely be cast to TYPE - if (!isValidType(value) || !isValidValue((T) value)) { - String message = getErrorMessage().replace("{0}", - String.valueOf(value)); - throw new InvalidValueException(message); - } - } - - /** - * Checks the type of the value to validate to ensure it conforms with - * getType. Enables sub classes to handle the specific type instead of - * Object. - * - * @param value - * The value to check - * @return true if the value can safely be cast to the type specified by - * {@link #getType()} - */ - protected boolean isValidType(Object value) { - if (value == null) { - return true; - } - - return getType().isAssignableFrom(value.getClass()); - } - - /** - * Returns the message to be included in the exception in case the value - * does not validate. - * - * @return the error message provided in the constructor or using - * {@link #setErrorMessage(String)}. - */ - public String getErrorMessage() { - return errorMessage; - } - - /** - * Sets the message to be included in the exception in case the value does - * not validate. The exception message is typically shown to the end user. - * - * @param errorMessage - * the error message. "{0}" is automatically replaced by the - * value that did not validate. - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - public abstract Class<T> getType(); -} diff --git a/src/com/vaadin/data/validator/BeanValidator.java b/src/com/vaadin/data/validator/BeanValidator.java deleted file mode 100644 index 816ff79b83..0000000000 --- a/src/com/vaadin/data/validator/BeanValidator.java +++ /dev/null @@ -1,176 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.validator; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import javax.validation.ConstraintViolation; -import javax.validation.MessageInterpolator.Context; -import javax.validation.Validation; -import javax.validation.ValidatorFactory; -import javax.validation.metadata.ConstraintDescriptor; - -import com.vaadin.data.Validator; - -/** - * Vaadin {@link Validator} using the JSR-303 (javax.validation) - * annotation-based bean validation. - * - * The annotations of the fields of the beans are used to determine the - * validation to perform. - * - * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean - * Validation - formerly agimatec validation) must be present on the project - * classpath when using bean validation. - * - * @since 7.0 - * - * @author Petri Hakala - * @author Henri Sara - */ -public class BeanValidator implements Validator { - - private static final long serialVersionUID = 1L; - private static ValidatorFactory factory; - - private transient javax.validation.Validator javaxBeanValidator; - private String propertyName; - private Class<?> beanClass; - private Locale locale; - - /** - * Simple implementation of a message interpolator context that returns - * fixed values. - */ - protected static class SimpleContext implements Context, Serializable { - - private final Object value; - private final ConstraintDescriptor<?> descriptor; - - /** - * Create a simple immutable message interpolator context. - * - * @param value - * value being validated - * @param descriptor - * ConstraintDescriptor corresponding to the constraint being - * validated - */ - public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) { - this.value = value; - this.descriptor = descriptor; - } - - @Override - public ConstraintDescriptor<?> getConstraintDescriptor() { - return descriptor; - } - - @Override - public Object getValidatedValue() { - return value; - } - - } - - /** - * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation. - * - * @param beanClass - * bean class based on which the validation should be performed - * @param propertyName - * property to validate - */ - public BeanValidator(Class<?> beanClass, String propertyName) { - this.beanClass = beanClass; - this.propertyName = propertyName; - locale = Locale.getDefault(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Validator#validate(java.lang.Object) - */ - @Override - public void validate(final Object value) throws InvalidValueException { - Set<?> violations = getJavaxBeanValidator().validateValue(beanClass, - propertyName, value); - if (violations.size() > 0) { - List<String> exceptions = new ArrayList<String>(); - for (Object v : violations) { - final ConstraintViolation<?> violation = (ConstraintViolation<?>) v; - String msg = getJavaxBeanValidatorFactory() - .getMessageInterpolator().interpolate( - violation.getMessageTemplate(), - new SimpleContext(value, violation - .getConstraintDescriptor()), locale); - exceptions.add(msg); - } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < exceptions.size(); i++) { - if (i != 0) { - b.append("<br/>"); - } - b.append(exceptions.get(i)); - } - throw new InvalidValueException(b.toString()); - } - } - - /** - * Sets the locale used for validation error messages. - * - * Revalidation is not automatically triggered by setting the locale. - * - * @param locale - */ - public void setLocale(Locale locale) { - this.locale = locale; - } - - /** - * Gets the locale used for validation error messages. - * - * @return locale used for validation - */ - public Locale getLocale() { - return locale; - } - - /** - * Returns the underlying JSR-303 bean validator factory used. A factory is - * created using {@link Validation} if necessary. - * - * @return {@link ValidatorFactory} to use - */ - protected static ValidatorFactory getJavaxBeanValidatorFactory() { - if (factory == null) { - factory = Validation.buildDefaultValidatorFactory(); - } - - return factory; - } - - /** - * Returns a shared Validator instance to use. An instance is created using - * the validator factory if necessary and thereafter reused by the - * {@link BeanValidator} instance. - * - * @return the JSR-303 {@link javax.validation.Validator} to use - */ - protected javax.validation.Validator getJavaxBeanValidator() { - if (javaxBeanValidator == null) { - javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator(); - } - - return javaxBeanValidator; - } - -}
\ No newline at end of file diff --git a/src/com/vaadin/data/validator/CompositeValidator.java b/src/com/vaadin/data/validator/CompositeValidator.java deleted file mode 100644 index cad31c9d4d..0000000000 --- a/src/com/vaadin/data/validator/CompositeValidator.java +++ /dev/null @@ -1,259 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.validator; - -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; - -import com.vaadin.data.Validator; - -/** - * The <code>CompositeValidator</code> allows you to chain (compose) many - * validators to validate one field. The contained validators may be required to - * all validate the value to validate or it may be enough that one contained - * validator validates the value. This behaviour is controlled by the modes - * <code>AND</code> and <code>OR</code>. - * - * @author Vaadin Ltd. - * @version @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class CompositeValidator implements Validator { - - public enum CombinationMode { - /** - * The validators are combined with <code>AND</code> clause: validity of - * the composite implies validity of the all validators it is composed - * of must be valid. - */ - AND, - /** - * The validators are combined with <code>OR</code> clause: validity of - * the composite implies that some of validators it is composed of must - * be valid. - */ - OR; - } - - /** - * @deprecated from 7.0, use {@link CombinationMode#AND} instead - */ - @Deprecated - public static final CombinationMode MODE_AND = CombinationMode.AND; - /** - * @deprecated from 7.0, use {@link CombinationMode#OR} instead - */ - @Deprecated - public static final CombinationMode MODE_OR = CombinationMode.OR; - - private String errorMessage; - - /** - * Operation mode. - */ - private CombinationMode mode = CombinationMode.AND; - - /** - * List of contained validators. - */ - private final List<Validator> validators = new LinkedList<Validator>(); - - /** - * Construct a composite validator in <code>AND</code> mode without error - * message. - */ - public CompositeValidator() { - this(CombinationMode.AND, ""); - } - - /** - * Constructs a composite validator in given mode. - * - * @param mode - * @param errorMessage - */ - public CompositeValidator(CombinationMode mode, String errorMessage) { - setErrorMessage(errorMessage); - setMode(mode); - } - - /** - * Validates the given value. - * <p> - * The value is valid, if: - * <ul> - * <li><code>MODE_AND</code>: All of the sub-validators are valid - * <li><code>MODE_OR</code>: Any of the sub-validators are valid - * </ul> - * - * If the value is invalid, validation error is thrown. If the error message - * is set (non-null), it is used. If the error message has not been set, the - * first error occurred is thrown. - * </p> - * - * @param value - * the value to check. - * @throws Validator.InvalidValueException - * if the value is not valid. - */ - @Override - public void validate(Object value) throws Validator.InvalidValueException { - switch (mode) { - case AND: - for (Validator validator : validators) { - validator.validate(value); - } - return; - - case OR: - Validator.InvalidValueException first = null; - for (Validator v : validators) { - try { - v.validate(value); - return; - } catch (final Validator.InvalidValueException e) { - if (first == null) { - first = e; - } - } - } - if (first == null) { - return; - } - final String em = getErrorMessage(); - if (em != null) { - throw new Validator.InvalidValueException(em); - } else { - throw first; - } - } - } - - /** - * Gets the mode of the validator. - * - * @return Operation mode of the validator: {@link CombinationMode#AND} or - * {@link CombinationMode#OR}. - */ - public final CombinationMode getMode() { - return mode; - } - - /** - * Sets the mode of the validator. The valid modes are: - * <ul> - * <li>{@link CombinationMode#AND} (default) - * <li>{@link CombinationMode#OR} - * </ul> - * - * @param mode - * the mode to set. - */ - public void setMode(CombinationMode mode) { - if (mode == null) { - throw new IllegalArgumentException( - "The validator can't be set to null"); - } - this.mode = mode; - } - - /** - * Gets the error message for the composite validator. If the error message - * is null, original error messages of the sub-validators are used instead. - */ - public String getErrorMessage() { - if (errorMessage != null) { - return errorMessage; - } - - // TODO Return composite error message - - return null; - } - - /** - * Adds validator to the interface. - * - * @param validator - * the Validator object which performs validation checks on this - * set of data field values. - */ - public void addValidator(Validator validator) { - if (validator == null) { - return; - } - validators.add(validator); - } - - /** - * Removes a validator from the composite. - * - * @param validator - * the Validator object which performs validation checks on this - * set of data field values. - */ - public void removeValidator(Validator validator) { - validators.remove(validator); - } - - /** - * Gets sub-validators by class. - * - * <p> - * If the component contains directly or recursively (it contains another - * composite containing the validator) validators compatible with given type - * they are returned. This only applies to <code>AND</code> mode composite - * validators. - * </p> - * - * <p> - * If the validator is in <code>OR</code> mode or does not contain any - * validators of given type null is returned. - * </p> - * - * @param validatorType - * The type of validators to return - * - * @return Collection<Validator> of validators compatible with given type - * that must apply or null if none found. - */ - public Collection<Validator> getSubValidators(Class validatorType) { - if (mode != CombinationMode.AND) { - return null; - } - - final HashSet<Validator> found = new HashSet<Validator>(); - for (Validator v : validators) { - if (validatorType.isAssignableFrom(v.getClass())) { - found.add(v); - } - if (v instanceof CompositeValidator - && ((CompositeValidator) v).getMode() == MODE_AND) { - final Collection<Validator> c = ((CompositeValidator) v) - .getSubValidators(validatorType); - if (c != null) { - found.addAll(c); - } - } - } - - return found.isEmpty() ? null : found; - } - - /** - * Sets the message to be included in the exception in case the value does - * not validate. The exception message is typically shown to the end user. - * - * @param errorMessage - * the error message. - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - -} diff --git a/src/com/vaadin/data/validator/DateRangeValidator.java b/src/com/vaadin/data/validator/DateRangeValidator.java deleted file mode 100644 index 24f3d3ce10..0000000000 --- a/src/com/vaadin/data/validator/DateRangeValidator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -import java.util.Date; - -import com.vaadin.ui.DateField.Resolution; - -/** - * Validator for validating that a Date is inside a given range. - * - * <p> - * Note that the comparison is done directly on the Date object so take care - * that the hours/minutes/seconds/milliseconds of the min/max values are - * properly set. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - */ -public class DateRangeValidator extends RangeValidator<Date> { - - /** - * Creates a validator for checking that an Date is within a given range. - * <p> - * By default the range is inclusive i.e. both minValue and maxValue are - * valid values. Use {@link #setMinValueIncluded(boolean)} or - * {@link #setMaxValueIncluded(boolean)} to change it. - * </p> - * <p> - * Note that the comparison is done directly on the Date object so take care - * that the hours/minutes/seconds/milliseconds of the min/max values are - * properly set. - * </p> - * - * @param errorMessage - * the message to display in case the value does not validate. - * @param minValue - * The minimum value to accept or null for no limit - * @param maxValue - * The maximum value to accept or null for no limit - */ - public DateRangeValidator(String errorMessage, Date minValue, - Date maxValue, Resolution resolution) { - super(errorMessage, Date.class, minValue, maxValue); - } - -} diff --git a/src/com/vaadin/data/validator/DoubleRangeValidator.java b/src/com/vaadin/data/validator/DoubleRangeValidator.java deleted file mode 100644 index 05ae2f827e..0000000000 --- a/src/com/vaadin/data/validator/DoubleRangeValidator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * Validator for validating that a {@link Double} is inside a given range. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - */ -@SuppressWarnings("serial") -public class DoubleRangeValidator extends RangeValidator<Double> { - - /** - * Creates a validator for checking that an Double is within a given range. - * - * By default the range is inclusive i.e. both minValue and maxValue are - * valid values. Use {@link #setMinValueIncluded(boolean)} or - * {@link #setMaxValueIncluded(boolean)} to change it. - * - * - * @param errorMessage - * the message to display in case the value does not validate. - * @param minValue - * The minimum value to accept or null for no limit - * @param maxValue - * The maximum value to accept or null for no limit - */ - public DoubleRangeValidator(String errorMessage, Double minValue, - Double maxValue) { - super(errorMessage, Double.class, minValue, maxValue); - } - -} diff --git a/src/com/vaadin/data/validator/DoubleValidator.java b/src/com/vaadin/data/validator/DoubleValidator.java deleted file mode 100644 index 18f1909add..0000000000 --- a/src/com/vaadin/data/validator/DoubleValidator.java +++ /dev/null @@ -1,58 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * String validator for a double precision floating point number. See - * {@link com.vaadin.data.validator.AbstractStringValidator} for more - * information. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - * @deprecated in Vaadin 7.0. Use an Double converter on the field instead. - */ -@Deprecated -@SuppressWarnings("serial") -public class DoubleValidator extends AbstractStringValidator { - - /** - * Creates a validator for checking that a string can be parsed as an - * double. - * - * @param errorMessage - * the message to display in case the value does not validate. - * @deprecated in Vaadin 7.0. Use a Double converter on the field instead - * and/or use a {@link DoubleRangeValidator} for validating that - * the value is inside a given range. - */ - @Deprecated - public DoubleValidator(String errorMessage) { - super(errorMessage); - } - - @Override - protected boolean isValidValue(String value) { - try { - Double.parseDouble(value); - return true; - } catch (Exception e) { - return false; - } - } - - @Override - public void validate(Object value) throws InvalidValueException { - if (value != null && value instanceof Double) { - // Allow Doubles to pass through the validator for easier - // migration. Otherwise a TextField connected to an double property - // with a DoubleValidator will fail. - return; - } - - super.validate(value); - } - -} diff --git a/src/com/vaadin/data/validator/EmailValidator.java b/src/com/vaadin/data/validator/EmailValidator.java deleted file mode 100644 index c76d7e13dc..0000000000 --- a/src/com/vaadin/data/validator/EmailValidator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * String validator for e-mail addresses. The e-mail address syntax is not - * complete according to RFC 822 but handles the vast majority of valid e-mail - * addresses correctly. - * - * See {@link com.vaadin.data.validator.AbstractStringValidator} for more - * information. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - */ -@SuppressWarnings("serial") -public class EmailValidator extends RegexpValidator { - - /** - * Creates a validator for checking that a string is a syntactically valid - * e-mail address. - * - * @param errorMessage - * the message to display in case the value does not validate. - */ - public EmailValidator(String errorMessage) { - super( - "^([a-zA-Z0-9_\\.\\-+])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,4})+$", - true, errorMessage); - } - -} diff --git a/src/com/vaadin/data/validator/IntegerRangeValidator.java b/src/com/vaadin/data/validator/IntegerRangeValidator.java deleted file mode 100644 index c171dd97d8..0000000000 --- a/src/com/vaadin/data/validator/IntegerRangeValidator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * Validator for validating that an {@link Integer} is inside a given range. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - */ -@SuppressWarnings("serial") -public class IntegerRangeValidator extends RangeValidator<Integer> { - - /** - * Creates a validator for checking that an Integer is within a given range. - * - * By default the range is inclusive i.e. both minValue and maxValue are - * valid values. Use {@link #setMinValueIncluded(boolean)} or - * {@link #setMaxValueIncluded(boolean)} to change it. - * - * - * @param errorMessage - * the message to display in case the value does not validate. - * @param minValue - * The minimum value to accept or null for no limit - * @param maxValue - * The maximum value to accept or null for no limit - */ - public IntegerRangeValidator(String errorMessage, Integer minValue, - Integer maxValue) { - super(errorMessage, Integer.class, minValue, maxValue); - } - -} diff --git a/src/com/vaadin/data/validator/IntegerValidator.java b/src/com/vaadin/data/validator/IntegerValidator.java deleted file mode 100644 index 88ae9f3f0b..0000000000 --- a/src/com/vaadin/data/validator/IntegerValidator.java +++ /dev/null @@ -1,58 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * String validator for integers. See - * {@link com.vaadin.data.validator.AbstractStringValidator} for more - * information. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - * @deprecated in Vaadin 7.0. Use an Integer converter on the field instead. - */ -@SuppressWarnings("serial") -@Deprecated -public class IntegerValidator extends AbstractStringValidator { - - /** - * Creates a validator for checking that a string can be parsed as an - * integer. - * - * @param errorMessage - * the message to display in case the value does not validate. - * @deprecated in Vaadin 7.0. Use an Integer converter on the field instead - * and/or use an {@link IntegerRangeValidator} for validating - * that the value is inside a given range. - */ - @Deprecated - public IntegerValidator(String errorMessage) { - super(errorMessage); - - } - - @Override - protected boolean isValidValue(String value) { - try { - Integer.parseInt(value); - return true; - } catch (Exception e) { - return false; - } - } - - @Override - public void validate(Object value) throws InvalidValueException { - if (value != null && value instanceof Integer) { - // Allow Integers to pass through the validator for easier - // migration. Otherwise a TextField connected to an integer property - // with an IntegerValidator will fail. - return; - } - - super.validate(value); - } -} diff --git a/src/com/vaadin/data/validator/NullValidator.java b/src/com/vaadin/data/validator/NullValidator.java deleted file mode 100644 index 551d88c776..0000000000 --- a/src/com/vaadin/data/validator/NullValidator.java +++ /dev/null @@ -1,92 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.validator; - -import com.vaadin.data.Validator; - -/** - * This validator is used for validating properties that do or do not allow null - * values. By default, nulls are not allowed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class NullValidator implements Validator { - - private boolean onlyNullAllowed; - - private String errorMessage; - - /** - * Creates a new NullValidator. - * - * @param errorMessage - * the error message to display on invalidation. - * @param onlyNullAllowed - * Are only nulls allowed? - */ - public NullValidator(String errorMessage, boolean onlyNullAllowed) { - setErrorMessage(errorMessage); - setNullAllowed(onlyNullAllowed); - } - - /** - * Validates the data given in value. - * - * @param value - * the value to validate. - * @throws Validator.InvalidValueException - * if the value was invalid. - */ - @Override - public void validate(Object value) throws Validator.InvalidValueException { - if ((onlyNullAllowed && value != null) - || (!onlyNullAllowed && value == null)) { - throw new Validator.InvalidValueException(errorMessage); - } - } - - /** - * Returns <code>true</code> if nulls are allowed otherwise - * <code>false</code>. - */ - public final boolean isNullAllowed() { - return onlyNullAllowed; - } - - /** - * Sets if nulls (and only nulls) are to be allowed. - * - * @param onlyNullAllowed - * If true, only nulls are allowed. If false only non-nulls are - * allowed. Do we allow nulls? - */ - public void setNullAllowed(boolean onlyNullAllowed) { - this.onlyNullAllowed = onlyNullAllowed; - } - - /** - * Gets the error message that is displayed in case the value is invalid. - * - * @return the Error Message. - */ - public String getErrorMessage() { - return errorMessage; - } - - /** - * Sets the error message to be displayed on invalid value. - * - * @param errorMessage - * the Error Message to set. - */ - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - -} diff --git a/src/com/vaadin/data/validator/RangeValidator.java b/src/com/vaadin/data/validator/RangeValidator.java deleted file mode 100644 index 433271274f..0000000000 --- a/src/com/vaadin/data/validator/RangeValidator.java +++ /dev/null @@ -1,186 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -/** - * An base implementation for validating any objects that implement - * {@link Comparable}. - * - * Verifies that the value is of the given type and within the (optionally) - * given limits. Typically you want to use a sub class of this like - * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or - * {@link DateRangeValidator} in applications. - * <p> - * Note that {@link RangeValidator} always accept null values. Make a field - * required to ensure that no empty values are accepted or override - * {@link #isValidValue(Comparable)}. - * </p> - * - * @param <T> - * The type of Number to validate. Must implement Comparable so that - * minimum and maximum checks work. - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - */ -public class RangeValidator<T extends Comparable> extends AbstractValidator<T> { - - private T minValue = null; - private boolean minValueIncluded = true; - private T maxValue = null; - private boolean maxValueIncluded = true; - private Class<T> type; - - /** - * Creates a new range validator of the given type. - * - * @param errorMessage - * The error message to use if validation fails - * @param type - * The type of object the validator can validate. - * @param minValue - * The minimum value that should be accepted or null for no limit - * @param maxValue - * The maximum value that should be accepted or null for no limit - */ - public RangeValidator(String errorMessage, Class<T> type, T minValue, - T maxValue) { - super(errorMessage); - this.type = type; - this.minValue = minValue; - this.maxValue = maxValue; - } - - /** - * Checks if the minimum value is part of the accepted range - * - * @return true if the minimum value is part of the range, false otherwise - */ - public boolean isMinValueIncluded() { - return minValueIncluded; - } - - /** - * Sets if the minimum value is part of the accepted range - * - * @param minValueIncluded - * true if the minimum value should be part of the range, false - * otherwise - */ - public void setMinValueIncluded(boolean minValueIncluded) { - this.minValueIncluded = minValueIncluded; - } - - /** - * Checks if the maximum value is part of the accepted range - * - * @return true if the maximum value is part of the range, false otherwise - */ - public boolean isMaxValueIncluded() { - return maxValueIncluded; - } - - /** - * Sets if the maximum value is part of the accepted range - * - * @param maxValueIncluded - * true if the maximum value should be part of the range, false - * otherwise - */ - public void setMaxValueIncluded(boolean maxValueIncluded) { - this.maxValueIncluded = maxValueIncluded; - } - - /** - * Gets the minimum value of the range - * - * @return the minimum value - */ - public T getMinValue() { - return minValue; - } - - /** - * Sets the minimum value of the range. Use - * {@link #setMinValueIncluded(boolean)} to control whether this value is - * part of the range or not. - * - * @param minValue - * the minimum value - */ - public void setMinValue(T minValue) { - this.minValue = minValue; - } - - /** - * Gets the maximum value of the range - * - * @return the maximum value - */ - public T getMaxValue() { - return maxValue; - } - - /** - * Sets the maximum value of the range. Use - * {@link #setMaxValueIncluded(boolean)} to control whether this value is - * part of the range or not. - * - * @param maxValue - * the maximum value - */ - public void setMaxValue(T maxValue) { - this.maxValue = maxValue; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object - * ) - */ - @Override - protected boolean isValidValue(T value) { - if (value == null) { - return true; - } - - if (getMinValue() != null) { - // Ensure that the min limit is ok - int result = value.compareTo(getMinValue()); - if (result < 0) { - // value less than min value - return false; - } else if (result == 0 && !isMinValueIncluded()) { - // values equal and min value not included - return false; - } - } - if (getMaxValue() != null) { - // Ensure that the Max limit is ok - int result = value.compareTo(getMaxValue()); - if (result > 0) { - // value greater than max value - return false; - } else if (result == 0 && !isMaxValueIncluded()) { - // values equal and max value not included - return false; - } - } - return true; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.validator.AbstractValidator#getType() - */ - @Override - public Class<T> getType() { - return type; - } - -} diff --git a/src/com/vaadin/data/validator/RegexpValidator.java b/src/com/vaadin/data/validator/RegexpValidator.java deleted file mode 100644 index 8143d54c97..0000000000 --- a/src/com/vaadin/data/validator/RegexpValidator.java +++ /dev/null @@ -1,97 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.data.validator; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * String validator comparing the string against a Java regular expression. Both - * complete matches and substring matches are supported. - * - * <p> - * For the Java regular expression syntax, see - * {@link java.util.regex.Pattern#sum} - * </p> - * <p> - * See {@link com.vaadin.data.validator.AbstractStringValidator} for more - * information. - * </p> - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - */ -@SuppressWarnings("serial") -public class RegexpValidator extends AbstractStringValidator { - - private Pattern pattern; - private boolean complete; - private transient Matcher matcher = null; - - /** - * Creates a validator for checking that the regular expression matches the - * complete string to validate. - * - * @param regexp - * a Java regular expression - * @param errorMessage - * the message to display in case the value does not validate. - */ - public RegexpValidator(String regexp, String errorMessage) { - this(regexp, true, errorMessage); - } - - /** - * Creates a validator for checking that the regular expression matches the - * string to validate. - * - * @param regexp - * a Java regular expression - * @param complete - * true to use check for a complete match, false to look for a - * matching substring - * @param errorMessage - * the message to display in case the value does not validate. - */ - public RegexpValidator(String regexp, boolean complete, String errorMessage) { - super(errorMessage); - pattern = Pattern.compile(regexp); - this.complete = complete; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object - * ) - */ - @Override - protected boolean isValidValue(String value) { - if (complete) { - return getMatcher(value).matches(); - } else { - return getMatcher(value).find(); - } - } - - /** - * Get a new or reused matcher for the pattern - * - * @param value - * the string to find matches in - * @return Matcher for the string - */ - private Matcher getMatcher(String value) { - if (matcher == null) { - matcher = pattern.matcher(value); - } else { - matcher.reset(value); - } - return matcher; - } - -} diff --git a/src/com/vaadin/data/validator/StringLengthValidator.java b/src/com/vaadin/data/validator/StringLengthValidator.java deleted file mode 100644 index 54b2d28f58..0000000000 --- a/src/com/vaadin/data/validator/StringLengthValidator.java +++ /dev/null @@ -1,139 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.data.validator; - -/** - * This <code>StringLengthValidator</code> is used to validate the length of - * strings. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class StringLengthValidator extends AbstractStringValidator { - - private Integer minLength = null; - - private Integer maxLength = null; - - private boolean allowNull = true; - - /** - * Creates a new StringLengthValidator with a given error message. - * - * @param errorMessage - * the message to display in case the value does not validate. - */ - public StringLengthValidator(String errorMessage) { - super(errorMessage); - } - - /** - * Creates a new StringLengthValidator with a given error message and - * minimum and maximum length limits. - * - * @param errorMessage - * the message to display in case the value does not validate. - * @param minLength - * the minimum permissible length of the string or null for no - * limit. A negative value for no limit is also supported for - * backwards compatibility. - * @param maxLength - * the maximum permissible length of the string or null for no - * limit. A negative value for no limit is also supported for - * backwards compatibility. - * @param allowNull - * Are null strings permissible? This can be handled better by - * setting a field as required or not. - */ - public StringLengthValidator(String errorMessage, Integer minLength, - Integer maxLength, boolean allowNull) { - this(errorMessage); - setMinLength(minLength); - setMaxLength(maxLength); - setNullAllowed(allowNull); - } - - /** - * Checks if the given value is valid. - * - * @param value - * the value to validate. - * @return <code>true</code> for valid value, otherwise <code>false</code>. - */ - @Override - protected boolean isValidValue(String value) { - if (value == null) { - return allowNull; - } - final int len = value.length(); - if ((minLength != null && minLength > -1 && len < minLength) - || (maxLength != null && maxLength > -1 && len > maxLength)) { - return false; - } - return true; - } - - /** - * Returns <code>true</code> if null strings are allowed. - * - * @return <code>true</code> if allows null string, otherwise - * <code>false</code>. - */ - @Deprecated - public final boolean isNullAllowed() { - return allowNull; - } - - /** - * Gets the maximum permissible length of the string. - * - * @return the maximum length of the string or null if there is no limit - */ - public Integer getMaxLength() { - return maxLength; - } - - /** - * Gets the minimum permissible length of the string. - * - * @return the minimum length of the string or null if there is no limit - */ - public Integer getMinLength() { - return minLength; - } - - /** - * Sets whether null-strings are to be allowed. This can be better handled - * by setting a field as required or not. - */ - @Deprecated - public void setNullAllowed(boolean allowNull) { - this.allowNull = allowNull; - } - - /** - * Sets the maximum permissible length of the string. - * - * @param maxLength - * the maximum length to accept or null for no limit - */ - public void setMaxLength(Integer maxLength) { - this.maxLength = maxLength; - } - - /** - * Sets the minimum permissible length. - * - * @param minLength - * the minimum length to accept or null for no limit - */ - public void setMinLength(Integer minLength) { - this.minLength = minLength; - } - -} diff --git a/src/com/vaadin/data/validator/package.html b/src/com/vaadin/data/validator/package.html deleted file mode 100644 index c991bfc82a..0000000000 --- a/src/com/vaadin/data/validator/package.html +++ /dev/null @@ -1,23 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> - -</head> - -<body bgcolor="white"> - -<!-- Package summary here --> - -<p>Provides various {@link com.vaadin.data.Validator} -implementations.</p> - -<p>{@link com.vaadin.data.validator.AbstractValidator -AbstractValidator} provides an abstract implementation of the {@link -com.vaadin.data.Validator} interface and can be extended for custom -validation needs. {@link -com.vaadin.data.validator.AbstractStringValidator -AbstractStringValidator} can also be extended if the value is a String.</p> - - -</body> -</html> |