diff options
author | Artur Signell <artur@vaadin.com> | 2016-08-18 21:58:46 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-08-20 00:08:47 +0300 |
commit | 65370e12a0605926cb80e205c2b0e74fefe83e5b (patch) | |
tree | 013b7a60741db3c902bb1a8ea29733aa117bd0b2 /server | |
parent | 34852cdb88c6c27b1341684204d78db0fdd061a6 (diff) | |
download | vaadin-framework-65370e12a0605926cb80e205c2b0e74fefe83e5b.tar.gz vaadin-framework-65370e12a0605926cb80e205c2b0e74fefe83e5b.zip |
Move Table/TreeTable to compatibility package
Change-Id: Ic9f2badf8688c32d704be67519c0f4c9a3da0e28
Diffstat (limited to 'server')
49 files changed, 6 insertions, 17514 deletions
diff --git a/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java index 6927adba8e..39fa9cb23e 100644 --- a/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java +++ b/server/src/main/java/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java @@ -23,13 +23,11 @@ import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropTarget; import com.vaadin.ui.Component; -import com.vaadin.ui.Table; -import com.vaadin.ui.Tree; /** * * A criterion that ensures the drag source is the same as drop target. Eg. - * {@link Tree} or {@link Table} could support only re-ordering of items, but no + * {code Tree} or {@code Table} could support only re-ordering of items, but no * {@link Transferable}s coming outside. * <p> * Note! Class is singleton, use {@link #get()} method to get the instance. diff --git a/server/src/main/java/com/vaadin/server/VaadinSession.java b/server/src/main/java/com/vaadin/server/VaadinSession.java index 1b852510e3..d10390dd64 100644 --- a/server/src/main/java/com/vaadin/server/VaadinSession.java +++ b/server/src/main/java/com/vaadin/server/VaadinSession.java @@ -49,14 +49,12 @@ import javax.servlet.http.HttpSessionBindingListener; import com.vaadin.event.EventRouter; import com.vaadin.shared.communication.PushMode; -import com.vaadin.ui.Table; import com.vaadin.ui.UI; import com.vaadin.util.CurrentInstance; import com.vaadin.util.ReflectTools; import com.vaadin.v7.data.util.converter.LegacyConverter; import com.vaadin.v7.data.util.converter.LegacyConverterFactory; import com.vaadin.v7.data.util.converter.LegacyDefaultConverterFactory; -import com.vaadin.v7.ui.LegacyAbstractField; /** * Contains everything that Vaadin needs to store for a specific user. This is @@ -615,12 +613,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * on a String). * </p> * <p> - * The {@link LegacyConverter} for an individual field can be overridden - * using {@link LegacyAbstractField#setConverter(LegacyConverter)} and for - * individual property ids in a {@link Table} using - * {@link Table#setConverter(Object, LegacyConverter)}. - * </p> - * <p> * The converter factory must never be set to null. * * @param converterFactory diff --git a/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java b/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java deleted file mode 100644 index 2ee5ecf00e..0000000000 --- a/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.ui; - -import java.text.Normalizer.Form; -import java.util.Date; - -import com.vaadin.data.Container; -import com.vaadin.data.Property; -import com.vaadin.shared.util.SharedUtil; -import com.vaadin.v7.ui.LegacyCheckBox; -import com.vaadin.v7.ui.LegacyDateField; -import com.vaadin.v7.ui.LegacyField; -import com.vaadin.v7.ui.LegacyTextField; - -/** - * This class contains a basic implementation for {@link TableFieldFactory}. The - * class is singleton, use {@link #get()} method to get reference to the - * instance. - * - * <p> - * There are also some static helper methods available for custom built field - * factories. - * - */ -public class DefaultFieldFactory implements TableFieldFactory { - - private static final DefaultFieldFactory instance = new DefaultFieldFactory(); - - /** - * Singleton method to get an instance of DefaultFieldFactory. - * - * @return an instance of DefaultFieldFactory - */ - public static DefaultFieldFactory get() { - return instance; - } - - protected DefaultFieldFactory() { - } - - @Override - public LegacyField createField(Container container, Object itemId, - Object propertyId, Component uiContext) { - Property containerProperty = container.getContainerProperty(itemId, - propertyId); - Class<?> type = containerProperty.getType(); - LegacyField<?> field = createFieldByPropertyType(type); - field.setCaption(createCaptionByPropertyId(propertyId)); - return field; - } - - /** - * If name follows method naming conventions, convert the name to spaced - * upper case text. For example, convert "firstName" to "First Name" - * - * @param propertyId - * @return the formatted caption string - */ - public static String createCaptionByPropertyId(Object propertyId) { - return SharedUtil.propertyIdToHumanFriendly(propertyId); - } - - /** - * Creates fields based on the property type. - * <p> - * The default field type is {@link LegacyTextField}. Other field types - * generated by this method: - * <p> - * <b>Boolean</b>: {@link CheckBox}.<br/> - * <b>Date</b>: {@link LegacyDateField}(resolution: day).<br/> - * <b>Item</b>: {@link Form}. <br/> - * <b>default field type</b>: {@link LegacyTextField}. - * <p> - * - * @param type - * the type of the property - * @return the most suitable generic {@link LegacyField} for given type - */ - public static LegacyField<?> createFieldByPropertyType(Class<?> type) { - // Null typed properties can not be edited - if (type == null) { - return null; - } - - // Date field - if (Date.class.isAssignableFrom(type)) { - final LegacyDateField df = new LegacyDateField(); - df.setResolution(LegacyDateField.RESOLUTION_DAY); - return df; - } - - // Boolean field - if (Boolean.class.isAssignableFrom(type)) { - return new LegacyCheckBox(); - } - - return new LegacyTextField(); - } - -} diff --git a/server/src/main/java/com/vaadin/ui/Table.java b/server/src/main/java/com/vaadin/ui/Table.java deleted file mode 100644 index 13333146f2..0000000000 --- a/server/src/main/java/com/vaadin/ui/Table.java +++ /dev/null @@ -1,6533 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.ContainerOrderedWrapper; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; -import com.vaadin.event.ContextClickEvent; -import com.vaadin.event.DataBoundTransferable; -import com.vaadin.event.ItemClickEvent; -import com.vaadin.event.ItemClickEvent.ItemClickListener; -import com.vaadin.event.ItemClickEvent.ItemClickNotifier; -import com.vaadin.event.MouseEvents.ClickEvent; -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DragSource; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion; -import com.vaadin.server.KeyMapper; -import com.vaadin.server.LegacyCommunicationManager; -import com.vaadin.server.LegacyPaint; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.server.Resource; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.MultiSelectMode; -import com.vaadin.shared.ui.table.CollapseMenuContent; -import com.vaadin.shared.ui.table.TableConstants; -import com.vaadin.shared.ui.table.TableConstants.Section; -import com.vaadin.shared.ui.table.TableServerRpc; -import com.vaadin.shared.ui.table.TableState; -import com.vaadin.shared.util.SharedUtil; -import com.vaadin.ui.declarative.DesignAttributeHandler; -import com.vaadin.ui.declarative.DesignContext; -import com.vaadin.ui.declarative.DesignException; -import com.vaadin.ui.declarative.DesignFormatter; -import com.vaadin.util.ReflectTools; -import com.vaadin.v7.data.util.converter.LegacyConverter; -import com.vaadin.v7.data.util.converter.LegacyConverterUtil; -import com.vaadin.v7.ui.LegacyField; - -/** - * <p> - * <code>Table</code> is used for representing data or components in a pageable - * and selectable table. - * </p> - * - * <p> - * Scalability of the Table is largely dictated by the container. A table does - * not have a limit for the number of items and is just as fast with hundreds of - * thousands of items as with just a few. The current GWT implementation with - * scrolling however limits the number of rows to around 500000, depending on - * the browser and the pixel height of rows. - * </p> - * - * <p> - * Components in a Table will not have their caption nor icon rendered. - * </p> - * - * @author Vaadin Ltd. - * @since 3.0 - */ -@SuppressWarnings({ "deprecation" }) -public class Table extends AbstractSelect implements Action.Container, - Container.Ordered, Container.Sortable, ItemClickNotifier, DragSource, - DropTarget, HasComponents, HasChildMeasurementHint { - - private transient Logger logger = null; - - /** - * Modes that Table support as drag sourse. - */ - public enum TableDragMode { - /** - * Table does not start drag and drop events. HTM5 style events started - * by browser may still happen. - */ - NONE, - /** - * Table starts drag with a one row only. - */ - ROW, - /** - * Table drags selected rows, if drag starts on a selected rows. Else it - * starts like in ROW mode. Note, that in Transferable there will still - * be only the row on which the drag started, other dragged rows need to - * be checked from the source Table. - */ - MULTIROW - } - - protected static final int CELL_KEY = 0; - - protected static final int CELL_HEADER = 1; - - protected static final int CELL_ICON = 2; - - protected static final int CELL_ITEMID = 3; - - protected static final int CELL_GENERATED_ROW = 4; - - protected static final int CELL_FIRSTCOL = 5; - - public enum Align { - /** - * Left column alignment. <b>This is the default behaviour. </b> - */ - LEFT("b"), - - /** - * Center column alignment. - */ - CENTER("c"), - - /** - * Right column alignment. - */ - RIGHT("e"); - - private String alignment; - - private Align(String alignment) { - this.alignment = alignment; - } - - @Override - public String toString() { - return alignment; - } - - public Align convertStringToAlign(String string) { - if (string == null) { - return null; - } - if (string.equals("b")) { - return Align.LEFT; - } else if (string.equals("c")) { - return Align.CENTER; - } else if (string.equals("e")) { - return Align.RIGHT; - } else { - return null; - } - } - } - - /** - * @deprecated As of 7.0, use {@link Align#LEFT} instead - */ - @Deprecated - public static final Align ALIGN_LEFT = Align.LEFT; - - /** - * @deprecated As of 7.0, use {@link Align#CENTER} instead - */ - @Deprecated - public static final Align ALIGN_CENTER = Align.CENTER; - - /** - * @deprecated As of 7.0, use {@link Align#RIGHT} instead - */ - @Deprecated - public static final Align ALIGN_RIGHT = Align.RIGHT; - - public enum ColumnHeaderMode { - /** - * Column headers are hidden. - */ - HIDDEN, - /** - * Property ID:s are used as column headers. - */ - ID, - /** - * Column headers are explicitly specified with - * {@link #setColumnHeaders(String[])}. - */ - EXPLICIT, - /** - * Column headers are explicitly specified with - * {@link #setColumnHeaders(String[])}. If a header is not specified for - * a given property, its property id is used instead. - * <p> - * <b>This is the default behavior. </b> - */ - EXPLICIT_DEFAULTS_ID - } - - /** - * @deprecated As of 7.0, use {@link ColumnHeaderMode#HIDDEN} instead - */ - @Deprecated - public static final ColumnHeaderMode COLUMN_HEADER_MODE_HIDDEN = ColumnHeaderMode.HIDDEN; - - /** - * @deprecated As of 7.0, use {@link ColumnHeaderMode#ID} instead - */ - @Deprecated - public static final ColumnHeaderMode COLUMN_HEADER_MODE_ID = ColumnHeaderMode.ID; - - /** - * @deprecated As of 7.0, use {@link ColumnHeaderMode#EXPLICIT} instead - */ - @Deprecated - public static final ColumnHeaderMode COLUMN_HEADER_MODE_EXPLICIT = ColumnHeaderMode.EXPLICIT; - - /** - * @deprecated As of 7.0, use {@link ColumnHeaderMode#EXPLICIT_DEFAULTS_ID} - * instead - */ - @Deprecated - public static final ColumnHeaderMode COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID = ColumnHeaderMode.EXPLICIT_DEFAULTS_ID; - - public enum RowHeaderMode { - /** - * Row caption mode: The row headers are hidden. <b>This is the default - * mode. </b> - */ - HIDDEN(null), - /** - * Row caption mode: Items Id-objects toString is used as row caption. - */ - ID(ItemCaptionMode.ID), - /** - * Row caption mode: Item-objects toString is used as row caption. - */ - ITEM(ItemCaptionMode.ITEM), - /** - * Row caption mode: Index of the item is used as item caption. The - * index mode can only be used with the containers implementing the - * {@link com.vaadin.data.Container.Indexed} interface. - */ - INDEX(ItemCaptionMode.INDEX), - /** - * Row caption mode: Item captions are explicitly specified, but if the - * caption is missing, the item id objects <code>toString()</code> is - * used instead. - */ - EXPLICIT_DEFAULTS_ID(ItemCaptionMode.EXPLICIT_DEFAULTS_ID), - /** - * Row caption mode: Item captions are explicitly specified. - */ - EXPLICIT(ItemCaptionMode.EXPLICIT), - /** - * Row caption mode: Only icons are shown, the captions are hidden. - */ - ICON_ONLY(ItemCaptionMode.ICON_ONLY), - /** - * Row caption mode: Item captions are read from property specified with - * {@link #setItemCaptionPropertyId(Object)} . - */ - PROPERTY(ItemCaptionMode.PROPERTY); - - ItemCaptionMode mode; - - private RowHeaderMode(ItemCaptionMode mode) { - this.mode = mode; - } - - public ItemCaptionMode getItemCaptionMode() { - return mode; - } - } - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#HIDDEN} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_HIDDEN = RowHeaderMode.HIDDEN; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#ID} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_ID = RowHeaderMode.ID; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#ITEM} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_ITEM = RowHeaderMode.ITEM; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#INDEX} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_INDEX = RowHeaderMode.INDEX; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#EXPLICIT_DEFAULTS_ID} - * instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID = RowHeaderMode.EXPLICIT_DEFAULTS_ID; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#EXPLICIT} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_EXPLICIT = RowHeaderMode.EXPLICIT; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#ICON_ONLY} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_ICON_ONLY = RowHeaderMode.ICON_ONLY; - - /** - * @deprecated As of 7.0, use {@link RowHeaderMode#PROPERTY} instead - */ - @Deprecated - public static final RowHeaderMode ROW_HEADER_MODE_PROPERTY = RowHeaderMode.PROPERTY; - - /** - * The default rate that table caches rows for smooth scrolling. - */ - private static final double CACHE_RATE_DEFAULT = 2; - - private static final String ROW_HEADER_COLUMN_KEY = "0"; - private static final Object ROW_HEADER_FAKE_PROPERTY_ID = new UniqueSerializable() { - }; - - /** - * How layout manager should behave when measuring Table's child components - */ - private ChildMeasurementHint childMeasurementHint = ChildMeasurementHint.MEASURE_ALWAYS; - - /* Private table extensions to Select */ - - /** - * True if column collapsing is allowed. - */ - private boolean columnCollapsingAllowed = false; - - /** - * True if reordering of columns is allowed on the client side. - */ - private boolean columnReorderingAllowed = false; - - /** - * Keymapper for column ids. - */ - private final KeyMapper<Object> columnIdMap = new KeyMapper<Object>(); - - /** - * Holds visible column propertyIds - in order. - */ - private LinkedList<Object> visibleColumns = new LinkedList<Object>(); - - /** - * Holds noncollapsible columns. - */ - private HashSet<Object> noncollapsibleColumns = new HashSet<Object>(); - - /** - * Holds propertyIds of currently collapsed columns. - */ - private final HashSet<Object> collapsedColumns = new HashSet<Object>(); - - /** - * Holds headers for visible columns (by propertyId). - */ - private final HashMap<Object, String> columnHeaders = new HashMap<Object, String>(); - - /** - * Holds footers for visible columns (by propertyId). - */ - private final HashMap<Object, String> columnFooters = new HashMap<Object, String>(); - - /** - * Holds icons for visible columns (by propertyId). - */ - private final HashMap<Object, Resource> columnIcons = new HashMap<Object, Resource>(); - - /** - * Holds alignments for visible columns (by propertyId). - */ - private HashMap<Object, Align> columnAlignments = new HashMap<Object, Align>(); - - /** - * Holds column widths in pixels for visible columns (by propertyId). - */ - private final HashMap<Object, Integer> columnWidths = new HashMap<Object, Integer>(); - - /** - * Holds column expand rations for visible columns (by propertyId). - */ - private final HashMap<Object, Float> columnExpandRatios = new HashMap<Object, Float>(); - - /** - * Holds column generators - */ - private final HashMap<Object, ColumnGenerator> columnGenerators = new LinkedHashMap<Object, ColumnGenerator>(); - - /** - * Holds value of property pageLength. 0 disables paging. - */ - private int pageLength = 15; - - /** - * Id the first item on the current page. - */ - private Object currentPageFirstItemId = null; - - /* - * If all rows get removed then scroll position of the previous container - * can be restored after re-adding/replacing rows via addAll(). This - * resolves #14581. - */ - private int repairOnReAddAllRowsDataScrollPositionItemIndex = -1; - - /** - * Index of the first item on the current page. - */ - private int currentPageFirstItemIndex = 0; - - /** - * Index of the "first" item on the last page if a user has used - * setCurrentPageFirstItemIndex to scroll down. -1 if not set. - */ - private int currentPageFirstItemIndexOnLastPage = -1; - - /** - * Holds value of property selectable. - */ - private Boolean selectable; - - /** - * Holds value of property columnHeaderMode. - */ - private ColumnHeaderMode columnHeaderMode = ColumnHeaderMode.EXPLICIT_DEFAULTS_ID; - - /** - * Holds value of property rowHeaderMode. - */ - private RowHeaderMode rowHeaderMode = RowHeaderMode.EXPLICIT_DEFAULTS_ID; - - /** - * Should the Table footer be visible? - */ - private boolean columnFootersVisible = false; - - /** - * Page contents buffer used in buffered mode. - */ - private Object[][] pageBuffer = null; - - /** - * Set of properties listened - the list is kept to release the listeners - * later. - */ - private HashSet<Property<?>> listenedProperties = null; - - /** - * Set of visible components - the is used for needsRepaint calculation. - */ - private HashSet<Component> visibleComponents = null; - - /** - * List of action handlers. - */ - private LinkedList<Handler> actionHandlers = null; - - /** - * Action mapper. - */ - private KeyMapper<Action> actionMapper = null; - - /** - * Table cell editor factory. - */ - private TableFieldFactory fieldFactory = DefaultFieldFactory.get(); - - /** - * Is table editable. - */ - private boolean editable = false; - - /** - * Current sorting direction. - */ - private boolean sortAscending = true; - - /** - * Currently table is sorted on this propertyId. - */ - private Object sortContainerPropertyId = null; - - /** - * Is table sorting by the user enabled. - */ - private boolean sortEnabled = true; - - /** - * Number of rows explicitly requested by the client to be painted on next - * paint. This is -1 if no request by the client is made. Painting the - * component will automatically reset this to -1. - */ - private int reqRowsToPaint = -1; - - /** - * Index of the first rows explicitly requested by the client to be painted. - * This is -1 if no request by the client is made. Painting the component - * will automatically reset this to -1. - */ - private int reqFirstRowToPaint = -1; - - private int firstToBeRenderedInClient = -1; - - private int lastToBeRenderedInClient = -1; - - private boolean isContentRefreshesEnabled = true; - - private int pageBufferFirstIndex; - - private boolean containerChangeToBeRendered = false; - - /** - * Table cell specific style generator - */ - private CellStyleGenerator cellStyleGenerator = null; - - /** - * Table cell specific tooltip generator - */ - private ItemDescriptionGenerator itemDescriptionGenerator; - - /* - * EXPERIMENTAL feature: will tell the client to re-calculate column widths - * if set to true. Currently no setter: extend to enable. - */ - protected boolean alwaysRecalculateColumnWidths = false; - - private double cacheRate = CACHE_RATE_DEFAULT; - - private TableDragMode dragMode = TableDragMode.NONE; - - private DropHandler dropHandler; - - private MultiSelectMode multiSelectMode = MultiSelectMode.DEFAULT; - - private boolean rowCacheInvalidated; - - private RowGenerator rowGenerator = null; - - private final Map<LegacyField<?>, Property<?>> associatedProperties = new HashMap<LegacyField<?>, Property<?>>(); - - private boolean painted = false; - - private HashMap<Object, LegacyConverter<String, Object>> propertyValueConverters = new HashMap<Object, LegacyConverter<String, Object>>(); - - /** - * Set to true if the client-side should be informed that the key mapper has - * been reset so it can avoid sending back references to keys that are no - * longer present. - */ - private boolean keyMapperReset; - - private List<Throwable> exceptionsDuringCachePopulation = new ArrayList<Throwable>(); - - private boolean isBeingPainted; - - /* Table constructors */ - - /** - * Creates a new empty table. - */ - public Table() { - setRowHeaderMode(ROW_HEADER_MODE_HIDDEN); - - registerRpc(new TableServerRpc() { - - @Override - public void contextClick(String rowKey, String colKey, - Section section, MouseEventDetails details) { - Object itemId = itemIdMapper.get(rowKey); - Object propertyId = columnIdMap.get(colKey); - fireEvent(new TableContextClickEvent(Table.this, details, - itemId, propertyId, section)); - } - }); - } - - /** - * Creates a new empty table with caption. - * - * @param caption - */ - public Table(String caption) { - this(); - setCaption(caption); - } - - /** - * Creates a new table with caption and connect it to a Container. - * - * @param caption - * @param dataSource - */ - public Table(String caption, Container dataSource) { - this(); - setCaption(caption); - setContainerDataSource(dataSource); - } - - /* Table functionality */ - - /** - * Gets the array of visible column id:s, including generated columns. - * - * <p> - * The columns are show in the order of their appearance in this array. - * </p> - * - * @return an array of currently visible propertyIds and generated column - * ids. - */ - public Object[] getVisibleColumns() { - if (visibleColumns == null) { - return null; - } - return visibleColumns.toArray(); - } - - /** - * Sets the array of visible column property id:s. - * - * <p> - * The columns are show in the order of their appearance in this array. - * </p> - * - * @param visibleColumns - * the Array of shown property id:s. - */ - public void setVisibleColumns(Object... visibleColumns) { - - // Visible columns must exist - if (visibleColumns == null) { - throw new NullPointerException( - "Can not set visible columns to null value"); - } - - final LinkedList<Object> newVC = new LinkedList<Object>(); - - // Checks that the new visible columns contains no nulls, properties - // exist and that there are no duplicates before adding them to newVC. - final Collection<?> properties = getContainerPropertyIds(); - for (int i = 0; i < visibleColumns.length; i++) { - if (visibleColumns[i] == null) { - throw new NullPointerException("Ids must be non-nulls"); - } else if (!properties.contains(visibleColumns[i]) - && !columnGenerators.containsKey(visibleColumns[i])) { - throw new IllegalArgumentException( - "Ids must exist in the Container or as a generated column, missing id: " - + visibleColumns[i]); - } else if (newVC.contains(visibleColumns[i])) { - throw new IllegalArgumentException( - "Ids must be unique, duplicate id: " - + visibleColumns[i]); - } else { - newVC.add(visibleColumns[i]); - } - } - - this.visibleColumns = newVC; - - // Assures visual refresh - refreshRowCache(); - } - - /** - * Gets the headers of the columns. - * - * <p> - * The headers match the property id:s given by the set visible column - * headers. The table must be set in either - * {@link #COLUMN_HEADER_MODE_EXPLICIT} or - * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the - * headers. In the defaults mode any nulls in the headers array are replaced - * with id.toString(). - * </p> - * - * @return the Array of column headers. - */ - public String[] getColumnHeaders() { - if (columnHeaders == null) { - return null; - } - final String[] headers = new String[visibleColumns.size()]; - int i = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it - .hasNext(); i++) { - headers[i] = getColumnHeader(it.next()); - } - return headers; - } - - /** - * Sets the headers of the columns. - * - * <p> - * The headers match the property id:s given by the set visible column - * headers. The table must be set in either - * {@link #COLUMN_HEADER_MODE_EXPLICIT} or - * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the - * headers. In the defaults mode any nulls in the headers array are replaced - * with id.toString() outputs when rendering. - * </p> - * - * @param columnHeaders - * the Array of column headers that match the - * {@link #getVisibleColumns()} method. - */ - public void setColumnHeaders(String... columnHeaders) { - - if (columnHeaders.length != visibleColumns.size()) { - throw new IllegalArgumentException( - "The length of the headers array must match the number of visible columns"); - } - - this.columnHeaders.clear(); - int i = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it.hasNext() - && i < columnHeaders.length; i++) { - this.columnHeaders.put(it.next(), columnHeaders[i]); - } - - markAsDirty(); - } - - /** - * Gets the icons of the columns. - * - * <p> - * The icons in headers match the property id:s given by the set visible - * column headers. The table must be set in either - * {@link #COLUMN_HEADER_MODE_EXPLICIT} or - * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers - * with icons. - * </p> - * - * @return the Array of icons that match the {@link #getVisibleColumns()}. - */ - public Resource[] getColumnIcons() { - if (columnIcons == null) { - return null; - } - final Resource[] icons = new Resource[visibleColumns.size()]; - int i = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it - .hasNext(); i++) { - icons[i] = columnIcons.get(it.next()); - } - - return icons; - } - - /** - * Sets the icons of the columns. - * - * <p> - * The icons in headers match the property id:s given by the set visible - * column headers. The table must be set in either - * {@link #COLUMN_HEADER_MODE_EXPLICIT} or - * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers - * with icons. - * </p> - * - * @param columnIcons - * the Array of icons that match the {@link #getVisibleColumns()} - * . - */ - public void setColumnIcons(Resource... columnIcons) { - - if (columnIcons.length != visibleColumns.size()) { - throw new IllegalArgumentException( - "The length of the icons array must match the number of visible columns"); - } - - this.columnIcons.clear(); - int i = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it.hasNext() - && i < columnIcons.length; i++) { - this.columnIcons.put(it.next(), columnIcons[i]); - } - - markAsDirty(); - } - - /** - * Gets the array of column alignments. - * - * <p> - * The items in the array must match the properties identified by - * {@link #getVisibleColumns()}. The possible values for the alignments - * include: - * <ul> - * <li>{@link Align#LEFT}: Left alignment</li> - * <li>{@link Align#CENTER}: Centered</li> - * <li>{@link Align#RIGHT}: Right alignment</li> - * </ul> - * The alignments default to {@link Align#LEFT}: any null values are - * rendered as align lefts. - * </p> - * - * @return the Column alignments array. - */ - public Align[] getColumnAlignments() { - if (columnAlignments == null) { - return null; - } - final Align[] alignments = new Align[visibleColumns.size()]; - int i = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it - .hasNext(); i++) { - alignments[i] = getColumnAlignment(it.next()); - } - - return alignments; - } - - /** - * Sets the column alignments. - * - * <p> - * The amount of items in the array must match the amount of properties - * identified by {@link #getVisibleColumns()}. The possible values for the - * alignments include: - * <ul> - * <li>{@link Align#LEFT}: Left alignment</li> - * <li>{@link Align#CENTER}: Centered</li> - * <li>{@link Align#RIGHT}: Right alignment</li> - * </ul> - * The alignments default to {@link Align#LEFT} - * </p> - * - * @param columnAlignments - * the Column alignments array. - */ - public void setColumnAlignments(Align... columnAlignments) { - - if (columnAlignments.length != visibleColumns.size()) { - throw new IllegalArgumentException( - "The length of the alignments array must match the number of visible columns"); - } - - // Resets the alignments - final HashMap<Object, Align> newCA = new HashMap<Object, Align>(); - int i = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it.hasNext() - && i < columnAlignments.length; i++) { - newCA.put(it.next(), columnAlignments[i]); - } - this.columnAlignments = newCA; - - // Assures the visual refresh. No need to reset the page buffer before - // as the content has not changed, only the alignments. - refreshRenderedCells(); - } - - /** - * Sets columns width (in pixels). Theme may not necessarily respect very - * small or very big values. Setting width to -1 (default) means that theme - * will make decision of width. - * - * <p> - * Column can either have a fixed width or expand ratio. The latter one set - * is used. See @link {@link #setColumnExpandRatio(Object, float)}. - * - * @param propertyId - * columns property id - * @param width - * width to be reserved for columns content - * @since 4.0.3 - */ - public void setColumnWidth(Object propertyId, int width) { - if (propertyId == null) { - // Since propertyId is null, this is the row header. Use the magic - // id to store the width of the row header. - propertyId = ROW_HEADER_FAKE_PROPERTY_ID; - } - - // Setting column width should remove any expand ratios as well - columnExpandRatios.remove(propertyId); - - if (width < 0) { - columnWidths.remove(propertyId); - } else { - columnWidths.put(propertyId, width); - } - markAsDirty(); - } - - /** - * Sets the column expand ratio for given column. - * <p> - * Expand ratios can be defined to customize the way how excess space is - * divided among columns. Table can have excess space if it has its width - * defined and there is horizontally more space than columns consume - * naturally. Excess space is the space that is not used by columns with - * explicit width (see {@link #setColumnWidth(Object, int)}) or with natural - * width (no width nor expand ratio). - * - * <p> - * By default (without expand ratios) the excess space is divided - * proportionally to columns natural widths. - * - * <p> - * Only expand ratios of visible columns are used in final calculations. - * - * <p> - * Column can either have a fixed width or expand ratio. The latter one set - * is used. - * - * <p> - * A column with expand ratio is considered to be minimum width by default - * (if no excess space exists). The minimum width is defined by terminal - * implementation. - * - * <p> - * If terminal implementation supports re-sizable columns the column becomes - * fixed width column if users resizes the column. - * - * @param propertyId - * columns property id - * @param expandRatio - * the expandRatio used to divide excess space for this column - */ - public void setColumnExpandRatio(Object propertyId, float expandRatio) { - if (propertyId == null) { - // Since propertyId is null, this is the row header. Use the magic - // id to store the width of the row header. - propertyId = ROW_HEADER_FAKE_PROPERTY_ID; - } - - // Setting the column expand ratio should remove and defined column - // width - columnWidths.remove(propertyId); - - if (expandRatio < 0) { - columnExpandRatios.remove(propertyId); - } else { - columnExpandRatios.put(propertyId, expandRatio); - } - - requestRepaint(); - } - - /** - * Gets the column expand ratio for a column. See - * {@link #setColumnExpandRatio(Object, float)} - * - * @param propertyId - * columns property id - * @return the expandRatio used to divide excess space for this column - */ - public float getColumnExpandRatio(Object propertyId) { - final Float width = columnExpandRatios.get(propertyId); - if (width == null) { - return -1; - } - return width.floatValue(); - } - - /** - * Gets the pixel width of column - * - * @param propertyId - * @return width of column or -1 when value not set - */ - public int getColumnWidth(Object propertyId) { - if (propertyId == null) { - // Since propertyId is null, this is the row header. Use the magic - // id to retrieve the width of the row header. - propertyId = ROW_HEADER_FAKE_PROPERTY_ID; - } - final Integer width = columnWidths.get(propertyId); - if (width == null) { - return -1; - } - return width.intValue(); - } - - /** - * Gets the page length. - * - * <p> - * Setting page length 0 disables paging. - * </p> - * - * @return the Length of one page. - */ - public int getPageLength() { - return pageLength; - } - - /** - * Sets the page length. - * - * <p> - * Setting page length 0 disables paging. The page length defaults to 15. - * </p> - * - * <p> - * If Table has height set ({@link #setHeight(float, Unit)} ) the client - * side may update the page length automatically the correct value. - * </p> - * - * @param pageLength - * the length of one page. - */ - public void setPageLength(int pageLength) { - if (pageLength >= 0 && this.pageLength != pageLength) { - this.pageLength = pageLength; - // Assures the visual refresh - refreshRowCache(); - } - } - - /** - * This method adjusts a possible caching mechanism of table implementation. - * - * <p> - * Table component may fetch and render some rows outside visible area. With - * complex tables (for example containing layouts and components), the - * client side may become unresponsive. Setting the value lower, UI will - * become more responsive. With higher values scrolling in client will hit - * server less frequently. - * - * <p> - * The amount of cached rows will be cacheRate multiplied with pageLength ( - * {@link #setPageLength(int)} both below and above visible area.. - * - * @param cacheRate - * a value over 0 (fastest rendering time). Higher value will - * cache more rows on server (smoother scrolling). Default value - * is 2. - */ - public void setCacheRate(double cacheRate) { - if (cacheRate < 0) { - throw new IllegalArgumentException( - "cacheRate cannot be less than zero"); - } - if (this.cacheRate != cacheRate) { - this.cacheRate = cacheRate; - markAsDirty(); - } - } - - /** - * @see #setCacheRate(double) - * - * @return the current cache rate value - */ - public double getCacheRate() { - return cacheRate; - } - - /** - * Getter for property currentPageFirstItem. - * - * @return the Value of property currentPageFirstItem. - */ - public Object getCurrentPageFirstItemId() { - - // Prioritise index over id if indexes are supported - if (items instanceof Container.Indexed) { - final int index = getCurrentPageFirstItemIndex(); - Object id = null; - if (index >= 0 && index < size()) { - id = getIdByIndex(index); - } - if (id != null && !id.equals(currentPageFirstItemId)) { - currentPageFirstItemId = id; - } - } - - // If there is no item id at all, use the first one - if (currentPageFirstItemId == null) { - currentPageFirstItemId = firstItemId(); - } - - return currentPageFirstItemId; - } - - /** - * Returns the item ID for the item represented by the index given. Assumes - * that the current container implements {@link Container.Indexed}. - * - * See {@link Container.Indexed#getIdByIndex(int)} for more information - * about the exceptions that can be thrown. - * - * @param index - * the index for which the item ID should be fetched - * @return the item ID for the given index - * - * @throws ClassCastException - * if container does not implement {@link Container.Indexed} - * @throws IndexOutOfBoundsException - * thrown by {@link Container.Indexed#getIdByIndex(int)} if the - * index is invalid - */ - protected Object getIdByIndex(int index) { - return ((Container.Indexed) items).getIdByIndex(index); - } - - /** - * Setter for property currentPageFirstItemId. - * - * @param currentPageFirstItemId - * the New value of property currentPageFirstItemId. - */ - public void setCurrentPageFirstItemId(Object currentPageFirstItemId) { - - // Gets the corresponding index - int index = -1; - if (items instanceof Container.Indexed) { - index = indexOfId(currentPageFirstItemId); - } else { - // If the table item container does not have index, we have to - // calculates the index by hand - Object id = firstItemId(); - while (id != null && !id.equals(currentPageFirstItemId)) { - index++; - id = nextItemId(id); - } - if (id == null) { - index = -1; - } - } - - // If the search for item index was successful - if (index >= 0) { - /* - * The table is not capable of displaying an item in the container - * as the first if there are not enough items following the selected - * item so the whole table (pagelength) is filled. - */ - int maxIndex = size() - pageLength; - if (maxIndex < 0) { - maxIndex = 0; - } - - if (index > maxIndex) { - // Note that we pass index, not maxIndex, letting - // setCurrentPageFirstItemIndex handle the situation. - setCurrentPageFirstItemIndex(index); - return; - } - - this.currentPageFirstItemId = currentPageFirstItemId; - currentPageFirstItemIndex = index; - } - - // Assures the visual refresh - refreshRowCache(); - - } - - protected int indexOfId(Object itemId) { - return ((Container.Indexed) items).indexOfId(itemId); - } - - /** - * Gets the icon Resource for the specified column. - * - * @param propertyId - * the propertyId identifying the column. - * @return the icon for the specified column; null if the column has no icon - * set, or if the column is not visible. - */ - public Resource getColumnIcon(Object propertyId) { - return columnIcons.get(propertyId); - } - - /** - * Sets the icon Resource for the specified column. - * <p> - * Throws IllegalArgumentException if the specified column is not visible. - * </p> - * - * @param propertyId - * the propertyId identifying the column. - * @param icon - * the icon Resource to set. - */ - public void setColumnIcon(Object propertyId, Resource icon) { - - if (icon == null) { - columnIcons.remove(propertyId); - } else { - columnIcons.put(propertyId, icon); - } - - markAsDirty(); - } - - /** - * Gets the header for the specified column. - * - * @param propertyId - * the propertyId identifying the column. - * @return the header for the specified column if it has one. - */ - public String getColumnHeader(Object propertyId) { - if (getColumnHeaderMode() == ColumnHeaderMode.HIDDEN) { - return null; - } - - String header = columnHeaders.get(propertyId); - if ((header == null - && getColumnHeaderMode() == ColumnHeaderMode.EXPLICIT_DEFAULTS_ID) - || getColumnHeaderMode() == ColumnHeaderMode.ID) { - header = propertyId.toString(); - } - - return header; - } - - /** - * Sets the column header for the specified column; - * - * @param propertyId - * the propertyId identifying the column. - * @param header - * the header to set. - */ - public void setColumnHeader(Object propertyId, String header) { - - if (header == null) { - columnHeaders.remove(propertyId); - } else { - columnHeaders.put(propertyId, header); - } - - markAsDirty(); - } - - /** - * Gets the specified column's alignment. - * - * @param propertyId - * the propertyID identifying the column. - * @return the specified column's alignment if it as one; {@link Align#LEFT} - * otherwise. - */ - public Align getColumnAlignment(Object propertyId) { - final Align a = columnAlignments.get(propertyId); - return a == null ? Align.LEFT : a; - } - - /** - * Sets the specified column's alignment. - * - * <p> - * Throws IllegalArgumentException if the alignment is not one of the - * following: {@link Align#LEFT}, {@link Align#CENTER} or - * {@link Align#RIGHT} - * </p> - * - * @param propertyId - * the propertyID identifying the column. - * @param alignment - * the desired alignment. - */ - public void setColumnAlignment(Object propertyId, Align alignment) { - if (alignment == null || alignment == Align.LEFT) { - columnAlignments.remove(propertyId); - } else { - columnAlignments.put(propertyId, alignment); - } - - // Assures the visual refresh. No need to reset the page buffer before - // as the content has not changed, only the alignments. - refreshRenderedCells(); - } - - /** - * Checks if the specified column is collapsed. - * - * @param propertyId - * the propertyID identifying the column. - * @return true if the column is collapsed; false otherwise; - */ - public boolean isColumnCollapsed(Object propertyId) { - return collapsedColumns != null - && collapsedColumns.contains(propertyId); - } - - /** - * Sets whether the specified column is collapsed or not. - * - * - * @param propertyId - * the propertyID identifying the column. - * @param collapsed - * the desired collapsedness. - * @throws IllegalStateException - * if column collapsing is not allowed - * @throws IllegalArgumentException - * if the property id does not exist - */ - public void setColumnCollapsed(Object propertyId, boolean collapsed) - throws IllegalStateException { - if (!isColumnCollapsingAllowed()) { - throw new IllegalStateException("Column collapsing not allowed!"); - } - if (collapsed && noncollapsibleColumns.contains(propertyId)) { - throw new IllegalStateException("The column is noncollapsible!"); - } - if (!getContainerPropertyIds().contains(propertyId) - && !columnGenerators.containsKey(propertyId)) { - throw new IllegalArgumentException("Property '" + propertyId - + "' was not found in the container"); - } - - if (collapsed) { - if (collapsedColumns.add(propertyId)) { - fireColumnCollapseEvent(propertyId); - } - } else { - if (collapsedColumns.remove(propertyId)) { - fireColumnCollapseEvent(propertyId); - } - } - - // Assures the visual refresh - refreshRowCache(); - } - - /** - * Checks if column collapsing is allowed. - * - * @return true if columns can be collapsed; false otherwise. - */ - public boolean isColumnCollapsingAllowed() { - return columnCollapsingAllowed; - } - - /** - * Sets whether column collapsing is allowed or not. - * - * @param collapsingAllowed - * specifies whether column collapsing is allowed. - */ - public void setColumnCollapsingAllowed(boolean collapsingAllowed) { - columnCollapsingAllowed = collapsingAllowed; - - if (!collapsingAllowed) { - collapsedColumns.clear(); - } - - // Assures the visual refresh. No need to reset the page buffer before - // as the content has not changed, only the alignments. - refreshRenderedCells(); - } - - /** - * Sets whether the given column is collapsible. Note that collapsible - * columns can only be actually collapsed (via UI or with - * {@link #setColumnCollapsed(Object, boolean) setColumnCollapsed()}) if - * {@link #isColumnCollapsingAllowed()} is true. By default all columns are - * collapsible. - * - * @param propertyId - * the propertyID identifying the column. - * @param collapsible - * true if the column should be collapsible, false otherwise. - */ - public void setColumnCollapsible(Object propertyId, boolean collapsible) { - if (collapsible) { - noncollapsibleColumns.remove(propertyId); - } else { - noncollapsibleColumns.add(propertyId); - collapsedColumns.remove(propertyId); - } - refreshRowCache(); - } - - /** - * Checks if the given column is collapsible. Note that even if this method - * returns <code>true</code>, the column can only be actually collapsed (via - * UI or with {@link #setColumnCollapsed(Object, boolean) - * setColumnCollapsed()}) if {@link #isColumnCollapsingAllowed()} is also - * true. - * - * @return true if the column can be collapsed; false otherwise. - */ - public boolean isColumnCollapsible(Object propertyId) { - return !noncollapsibleColumns.contains(propertyId); - } - - /** - * Checks if column reordering is allowed. - * - * @return true if columns can be reordered; false otherwise. - */ - public boolean isColumnReorderingAllowed() { - return columnReorderingAllowed; - } - - /** - * Sets whether column reordering is allowed or not. - * - * @param columnReorderingAllowed - * specifies whether column reordering is allowed. - */ - public void setColumnReorderingAllowed(boolean columnReorderingAllowed) { - if (columnReorderingAllowed != this.columnReorderingAllowed) { - this.columnReorderingAllowed = columnReorderingAllowed; - markAsDirty(); - } - } - - /* - * Arranges visible columns according to given columnOrder. Silently ignores - * colimnId:s that are not visible columns, and keeps the internal order of - * visible columns left out of the ordering (trailing). Silently does - * nothing if columnReordering is not allowed. - */ - private void setColumnOrder(Object[] columnOrder) { - if (columnOrder == null || !isColumnReorderingAllowed()) { - return; - } - final LinkedList<Object> newOrder = new LinkedList<Object>(); - for (int i = 0; i < columnOrder.length; i++) { - if (columnOrder[i] != null - && visibleColumns.contains(columnOrder[i])) { - visibleColumns.remove(columnOrder[i]); - newOrder.add(columnOrder[i]); - } - } - for (final Iterator<Object> it = visibleColumns.iterator(); it - .hasNext();) { - final Object columnId = it.next(); - if (!newOrder.contains(columnId)) { - newOrder.add(columnId); - } - } - visibleColumns = newOrder; - - // Assure visual refresh - refreshRowCache(); - } - - /** - * Getter for property currentPageFirstItem. - * - * @return the Value of property currentPageFirstItem. - */ - public int getCurrentPageFirstItemIndex() { - return currentPageFirstItemIndex; - } - - void setCurrentPageFirstItemIndex(int newIndex, - boolean needsPageBufferReset) { - - if (newIndex < 0) { - newIndex = 0; - } - - /* - * minimize Container.size() calls which may be expensive. For example - * it may cause sql query. - */ - final int size = size(); - - /* - * The table is not capable of displaying an item in the container as - * the first if there are not enough items following the selected item - * so the whole table (pagelength) is filled. - */ - int maxIndex = size - pageLength; - if (maxIndex < 0) { - maxIndex = 0; - } - - /* - * If the new index is on the last page we set the index to be the first - * item on that last page and make a note of the real index for the - * client side to be able to move the scroll position to the correct - * position. - */ - int indexOnLastPage = -1; - if (newIndex > maxIndex) { - indexOnLastPage = newIndex; - newIndex = maxIndex; - } - - // Refresh first item id - if (items instanceof Container.Indexed) { - try { - currentPageFirstItemId = getIdByIndex(newIndex); - } catch (final IndexOutOfBoundsException e) { - currentPageFirstItemId = null; - } - currentPageFirstItemIndex = newIndex; - - if (needsPageBufferReset) { - /* - * The flag currentPageFirstItemIndexOnLastPage denotes a user - * set scrolling position on the last page via - * setCurrentPageFirstItemIndex() and shouldn't be changed by - * the table component internally changing the firstvisible item - * on lazy row fetching. Doing so would make the scrolling - * position not be updated correctly when the lazy rows are - * finally rendered. - */ - - boolean isLastRowPossiblyPartiallyVisible = true; - if (indexOnLastPage != -1) { - /* - * If the requested row was greater than maxIndex, the last - * row should be fully visible (See - * TestCurrentPageFirstItem). - */ - isLastRowPossiblyPartiallyVisible = false; - } - - int extraRows = isLastRowPossiblyPartiallyVisible ? 0 : 1; - currentPageFirstItemIndexOnLastPage = currentPageFirstItemIndex - + extraRows; - } else { - currentPageFirstItemIndexOnLastPage = -1; - } - - } else { - - // For containers not supporting indexes, we must iterate the - // container forwards / backwards - // next available item forward or backward - - currentPageFirstItemId = firstItemId(); - - // Go forwards in the middle of the list (respect borders) - while (currentPageFirstItemIndex < newIndex - && !isLastId(currentPageFirstItemId)) { - currentPageFirstItemIndex++; - currentPageFirstItemId = nextItemId(currentPageFirstItemId); - } - - // If we did hit the border - if (isLastId(currentPageFirstItemId)) { - currentPageFirstItemIndex = size - 1; - } - - // Go backwards in the middle of the list (respect borders) - while (currentPageFirstItemIndex > newIndex - && !isFirstId(currentPageFirstItemId)) { - currentPageFirstItemIndex--; - currentPageFirstItemId = prevItemId(currentPageFirstItemId); - } - - // If we did hit the border - if (isFirstId(currentPageFirstItemId)) { - currentPageFirstItemIndex = 0; - } - - // Go forwards once more - while (currentPageFirstItemIndex < newIndex - && !isLastId(currentPageFirstItemId)) { - currentPageFirstItemIndex++; - currentPageFirstItemId = nextItemId(currentPageFirstItemId); - } - - // If for some reason we do hit border again, override - // the user index request - if (isLastId(currentPageFirstItemId)) { - newIndex = currentPageFirstItemIndex = size - 1; - } - } - - if (needsPageBufferReset) { - // Assures the visual refresh - refreshRowCache(); - } - } - - /** - * Setter for property currentPageFirstItem. - * - * @param newIndex - * the New value of property currentPageFirstItem. - */ - public void setCurrentPageFirstItemIndex(int newIndex) { - setCurrentPageFirstItemIndex(newIndex, true); - } - - /** - * Returns whether table is selectable. - * - * <p> - * The table is not selectable until it's explicitly set as selectable or at - * least one {@link ValueChangeListener} is added. - * </p> - * - * @return whether table is selectable. - */ - public boolean isSelectable() { - if (selectable == null) { - return hasListeners(ValueChangeEvent.class); - } - return selectable; - } - - /** - * Setter for property selectable. - * - * <p> - * The table is not selectable until it's explicitly set as selectable via - * this method or alternatively at least one {@link ValueChangeListener} is - * added. - * </p> - * - * @param selectable - * the New value of property selectable. - */ - public void setSelectable(boolean selectable) { - if (!SharedUtil.equals(this.selectable, selectable)) { - this.selectable = selectable; - markAsDirty(); - } - } - - /** - * Getter for property columnHeaderMode. - * - * @return the Value of property columnHeaderMode. - */ - public ColumnHeaderMode getColumnHeaderMode() { - return columnHeaderMode; - } - - /** - * Setter for property columnHeaderMode. - * - * @param columnHeaderMode - * the New value of property columnHeaderMode. - */ - public void setColumnHeaderMode(ColumnHeaderMode columnHeaderMode) { - if (columnHeaderMode == null) { - throw new IllegalArgumentException( - "Column header mode can not be null"); - } - if (columnHeaderMode != this.columnHeaderMode) { - this.columnHeaderMode = columnHeaderMode; - markAsDirty(); - } - - } - - /** - * Refreshes the rows in the internal cache. Only if - * {@link #resetPageBuffer()} is called before this then all values are - * guaranteed to be recreated. - */ - protected void refreshRenderedCells() { - if (!isAttached()) { - return; - } - - if (!isContentRefreshesEnabled) { - return; - } - - // Collects the basic facts about the table page - final int pagelen = getPageLength(); - int rows, totalRows; - rows = totalRows = size(); - int firstIndex = Math.min(getCurrentPageFirstItemIndex(), - totalRows - 1); - if (rows > 0 && firstIndex >= 0) { - rows -= firstIndex; - } - if (pagelen > 0 && pagelen < rows) { - rows = pagelen; - } - - // If "to be painted next" variables are set, use them - if (lastToBeRenderedInClient - firstToBeRenderedInClient > 0) { - rows = lastToBeRenderedInClient - firstToBeRenderedInClient + 1; - } - if (firstToBeRenderedInClient >= 0) { - if (firstToBeRenderedInClient < totalRows) { - firstIndex = firstToBeRenderedInClient; - } else { - firstIndex = totalRows - 1; - } - } else { - // initial load - - // #8805 send one extra row in the beginning in case a partial - // row is shown on the UI - if (firstIndex > 0) { - firstIndex = firstIndex - 1; - rows = rows + 1; - } - firstToBeRenderedInClient = firstIndex; - } - if (totalRows > 0) { - if (rows + firstIndex > totalRows) { - rows = totalRows - firstIndex; - } - } else { - rows = 0; - } - - // Saves the results to internal buffer - pageBuffer = getVisibleCellsNoCache(firstIndex, rows, true); - - if (rows > 0) { - pageBufferFirstIndex = firstIndex; - } - if (getPageLength() != 0) { - removeUnnecessaryRows(); - } - - setRowCacheInvalidated(true); - markAsDirty(); - maybeThrowCacheUpdateExceptions(); - - } - - private void maybeThrowCacheUpdateExceptions() { - if (!exceptionsDuringCachePopulation.isEmpty()) { - Throwable[] causes = new Throwable[exceptionsDuringCachePopulation - .size()]; - exceptionsDuringCachePopulation.toArray(causes); - - exceptionsDuringCachePopulation.clear(); - throw new CacheUpdateException(this, - "Error during Table cache update.", causes); - } - - } - - /** - * Exception thrown when one or more exceptions occurred during updating of - * the Table cache. - * <p> - * Contains all exceptions which occurred during the cache update. The first - * occurred exception is set as the cause of this exception. All occurred - * exceptions can be accessed using {@link #getCauses()}. - * </p> - * - */ - public static class CacheUpdateException extends RuntimeException { - private Throwable[] causes; - private Table table; - - public CacheUpdateException(Table table, String message, - Throwable[] causes) { - super(maybeSupplementMessage(message, causes.length), causes[0]); - this.table = table; - this.causes = causes; - } - - private static String maybeSupplementMessage(String message, - int causeCount) { - if (causeCount > 1) { - return message + " Additional causes not shown."; - } else { - return message; - } - } - - /** - * Returns the cause(s) for this exception - * - * @return the exception(s) which caused this exception - */ - public Throwable[] getCauses() { - return causes; - } - - public Table getTable() { - return table; - } - - } - - /** - * Removes rows that fall outside the required cache. - */ - private void removeUnnecessaryRows() { - int minPageBufferIndex = getMinPageBufferIndex(); - int maxPageBufferIndex = getMaxPageBufferIndex(); - - int maxBufferSize = maxPageBufferIndex - minPageBufferIndex + 1; - - /* - * Number of rows that were previously cached. This is not necessarily - * the same as pageLength if we do not have enough rows in the - * container. - */ - int currentlyCachedRowCount = pageBuffer[CELL_ITEMID].length; - - if (currentlyCachedRowCount <= maxBufferSize) { - // removal unnecessary - return; - } - - /* Figure out which rows to get rid of. */ - int firstCacheRowToRemoveInPageBuffer = -1; - if (minPageBufferIndex > pageBufferFirstIndex) { - firstCacheRowToRemoveInPageBuffer = pageBufferFirstIndex; - } else if (maxPageBufferIndex < pageBufferFirstIndex - + currentlyCachedRowCount) { - firstCacheRowToRemoveInPageBuffer = maxPageBufferIndex + 1; - } - - if (firstCacheRowToRemoveInPageBuffer - - pageBufferFirstIndex < currentlyCachedRowCount) { - /* - * Unregister all components that fall beyond the cache limits after - * inserting the new rows. - */ - unregisterComponentsAndPropertiesInRows( - firstCacheRowToRemoveInPageBuffer, currentlyCachedRowCount - - firstCacheRowToRemoveInPageBuffer); - } - } - - /** - * Requests that the Table should be repainted as soon as possible. - * - * Note that a {@code Table} does not necessarily repaint its contents when - * this method has been called. See {@link #refreshRowCache()} for forcing - * an update of the contents. - * - * @deprecated As of 7.0, use {@link #markAsDirty()} instead - */ - - @Deprecated - @Override - public void requestRepaint() { - markAsDirty(); - } - - /** - * Requests that the Table should be repainted as soon as possible. - * - * Note that a {@code Table} does not necessarily repaint its contents when - * this method has been called. See {@link #refreshRowCache()} for forcing - * an update of the contents. - */ - - @Override - public void markAsDirty() { - // Overridden only for javadoc - super.markAsDirty(); - } - - @Override - public void markAsDirtyRecursive() { - super.markAsDirtyRecursive(); - - // Avoid sending a partial repaint (#8714) - refreshRowCache(); - } - - private void removeRowsFromCacheAndFillBottom(int firstIndex, int rows) { - int totalCachedRows = pageBuffer[CELL_ITEMID].length; - int totalRows = size(); - int firstIndexInPageBuffer = firstIndex - pageBufferFirstIndex; - - /* - * firstIndexInPageBuffer is the first row to be removed. "rows" rows - * after that should be removed. If the page buffer does not contain - * that many rows, we only remove the rows that actually are in the page - * buffer. - */ - if (firstIndexInPageBuffer + rows > totalCachedRows) { - rows = totalCachedRows - firstIndexInPageBuffer; - } - - /* - * Unregister components that will no longer be in the page buffer to - * make sure that no components leak. - */ - unregisterComponentsAndPropertiesInRows(firstIndex, rows); - - /* - * The number of rows that should be in the cache after this operation - * is done (pageBuffer currently contains the expanded items). - */ - int newCachedRowCount = totalCachedRows; - if (newCachedRowCount + pageBufferFirstIndex > totalRows) { - newCachedRowCount = totalRows - pageBufferFirstIndex; - } - - /* - * The index at which we should render the first row that does not come - * from the previous page buffer. - */ - int firstAppendedRowInPageBuffer = totalCachedRows - rows; - int firstAppendedRow = firstAppendedRowInPageBuffer - + pageBufferFirstIndex; - - /* - * Calculate the maximum number of new rows that we can add to the page - * buffer. Less than the rows we removed if the container does not - * contain that many items afterwards. - */ - int maxRowsToRender = (totalRows - firstAppendedRow); - int rowsToAdd = rows; - if (rowsToAdd > maxRowsToRender) { - rowsToAdd = maxRowsToRender; - } - - Object[][] cells = null; - if (rowsToAdd > 0) { - cells = getVisibleCellsNoCache(firstAppendedRow, rowsToAdd, false); - } - /* - * Create the new cache buffer by copying the first rows from the old - * buffer, moving the following rows upwards and appending more rows if - * applicable. - */ - Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount]; - - for (int i = 0; i < pageBuffer.length; i++) { - for (int row = 0; row < firstIndexInPageBuffer; row++) { - // Copy the first rows - newPageBuffer[i][row] = pageBuffer[i][row]; - } - for (int row = firstIndexInPageBuffer; row < firstAppendedRowInPageBuffer; row++) { - // Move the rows that were after the expanded rows - newPageBuffer[i][row] = pageBuffer[i][row + rows]; - } - for (int row = firstAppendedRowInPageBuffer; row < newCachedRowCount; row++) { - // Add the newly rendered rows. Only used if rowsToAdd > 0 - // (cells != null) - newPageBuffer[i][row] = cells[i][row - - firstAppendedRowInPageBuffer]; - } - } - pageBuffer = newPageBuffer; - } - - private Object[][] getVisibleCellsUpdateCacheRows(int firstIndex, - int rows) { - Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false); - int cacheIx = firstIndex - pageBufferFirstIndex; - // update the new rows in the cache. - int totalCachedRows = pageBuffer[CELL_ITEMID].length; - int end = Math.min(cacheIx + rows, totalCachedRows); - for (int ix = cacheIx; ix < end; ix++) { - for (int i = 0; i < pageBuffer.length; i++) { - pageBuffer[i][ix] = cells[i][ix - cacheIx]; - } - } - return cells; - } - - /** - * @param firstIndex - * The position where new rows should be inserted - * @param rows - * The maximum number of rows that should be inserted at position - * firstIndex. Less rows will be inserted if the page buffer is - * too small. - * @return - */ - private Object[][] getVisibleCellsInsertIntoCache(int firstIndex, - int rows) { - getLogger().log(Level.FINEST, - "Insert {0} rows at index {1} to existing page buffer requested", - new Object[] { rows, firstIndex }); - - int minPageBufferIndex = getMinPageBufferIndex(); - int maxPageBufferIndex = getMaxPageBufferIndex(); - - int maxBufferSize = maxPageBufferIndex - minPageBufferIndex + 1; - - if (getPageLength() == 0) { - // If pageLength == 0 then all rows should be rendered - maxBufferSize = pageBuffer[CELL_ITEMID].length + rows; - } - /* - * Number of rows that were previously cached. This is not necessarily - * the same as maxBufferSize. - */ - int currentlyCachedRowCount = pageBuffer[CELL_ITEMID].length; - - /* If rows > size available in page buffer */ - if (firstIndex + rows - 1 > maxPageBufferIndex) { - rows = maxPageBufferIndex - firstIndex + 1; - } - - /* - * "rows" rows will be inserted at firstIndex. Find out how many old - * rows fall outside the new buffer so we can unregister components in - * the cache. - */ - - /* - * if there are rows before the new pageBuffer limits they must be - * removed - */ - int lastCacheRowToRemove = minPageBufferIndex - 1; - int rowsFromBeginning = lastCacheRowToRemove - pageBufferFirstIndex + 1; - if (lastCacheRowToRemove >= pageBufferFirstIndex) { - unregisterComponentsAndPropertiesInRows(pageBufferFirstIndex, - rowsFromBeginning); - } else { - rowsFromBeginning = 0; - } - - /* - * the rows that fall outside of the new pageBuffer limits after the new - * rows are inserted must also be removed - */ - int firstCacheRowToRemove = firstIndex; - /* - * IF there is space remaining in the buffer after the rows have been - * inserted, we can keep more rows. - */ - int numberOfOldRowsAfterInsertedRows = Math.min( - pageBufferFirstIndex + currentlyCachedRowCount + rows, - maxPageBufferIndex + 1) - (firstIndex + rows - 1); - if (numberOfOldRowsAfterInsertedRows > 0) { - firstCacheRowToRemove += numberOfOldRowsAfterInsertedRows; - } - int rowsFromAfter = currentlyCachedRowCount - - (firstCacheRowToRemove - pageBufferFirstIndex); - - if (rowsFromAfter > 0) { - /* - * Unregister all components that fall beyond the cache limits after - * inserting the new rows. - */ - unregisterComponentsAndPropertiesInRows(firstCacheRowToRemove, - rowsFromAfter); - } - - // Calculate the new cache size - int newCachedRowCount = maxBufferSize; - if (pageBufferFirstIndex + currentlyCachedRowCount + rows - - 1 < maxPageBufferIndex) { - // there aren't enough rows to fill the whole potential -> use what - // there is - newCachedRowCount -= maxPageBufferIndex - (pageBufferFirstIndex - + currentlyCachedRowCount + rows - 1); - } else if (minPageBufferIndex < pageBufferFirstIndex) { - newCachedRowCount -= pageBufferFirstIndex - minPageBufferIndex; - } - /* - * calculate the internal location of the new rows within the new cache - */ - int firstIndexInNewPageBuffer = firstIndex - pageBufferFirstIndex - - rowsFromBeginning; - - /* Paint the new rows into a separate buffer */ - Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false); - - /* - * Create the new cache buffer and fill it with the data from the old - * buffer as well as the inserted rows. - */ - Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount]; - - for (int i = 0; i < pageBuffer.length; i++) { - for (int row = 0; row < firstIndexInNewPageBuffer; row++) { - // Copy the first rows - newPageBuffer[i][row] = pageBuffer[i][rowsFromBeginning + row]; - } - for (int row = firstIndexInNewPageBuffer; row < firstIndexInNewPageBuffer - + rows; row++) { - // Copy the newly created rows - newPageBuffer[i][row] = cells[i][row - - firstIndexInNewPageBuffer]; - } - for (int row = firstIndexInNewPageBuffer - + rows; row < newCachedRowCount; row++) { - // Move the old rows down below the newly inserted rows - newPageBuffer[i][row] = pageBuffer[i][rowsFromBeginning + row - - rows]; - } - } - pageBuffer = newPageBuffer; - pageBufferFirstIndex = Math.max( - pageBufferFirstIndex + rowsFromBeginning, minPageBufferIndex); - if (getLogger().isLoggable(Level.FINEST)) { - getLogger().log(Level.FINEST, - "Page Buffer now contains {0} rows ({1}-{2})", - new Object[] { pageBuffer[CELL_ITEMID].length, - pageBufferFirstIndex, (pageBufferFirstIndex - + pageBuffer[CELL_ITEMID].length - 1) }); - } - return cells; - } - - private int getMaxPageBufferIndex() { - int total = size(); - if (getPageLength() == 0) { - // everything is shown at once, no caching - return total - 1; - } - // Page buffer must not become larger than pageLength*cacheRate after - // the current page - int maxPageBufferIndex = getCurrentPageFirstItemIndex() - + (int) (getPageLength() * (1 + getCacheRate())); - if (shouldHideNullSelectionItem()) { - --total; - } - if (maxPageBufferIndex >= total) { - maxPageBufferIndex = total - 1; - } - return maxPageBufferIndex; - } - - private int getMinPageBufferIndex() { - if (getPageLength() == 0) { - // everything is shown at once, no caching - return 0; - } - // Page buffer must not become larger than pageLength*cacheRate before - // the current page - int minPageBufferIndex = getCurrentPageFirstItemIndex() - - (int) (getPageLength() * getCacheRate()); - if (minPageBufferIndex < 0) { - minPageBufferIndex = 0; - } - return minPageBufferIndex; - } - - /** - * Render rows with index "firstIndex" to "firstIndex+rows-1" to a new - * buffer. - * - * Reuses values from the current page buffer if the rows are found there. - * - * @param firstIndex - * @param rows - * @param replaceListeners - * @return - */ - private Object[][] getVisibleCellsNoCache(int firstIndex, int rows, - boolean replaceListeners) { - if (getLogger().isLoggable(Level.FINEST)) { - getLogger().log(Level.FINEST, - "Render visible cells for rows {0}-{1}", - new Object[] { firstIndex, (firstIndex + rows - 1) }); - } - final Object[] colids = getVisibleColumns(); - final int cols = colids.length; - - HashSet<Property<?>> oldListenedProperties = listenedProperties; - HashSet<Component> oldVisibleComponents = visibleComponents; - - if (replaceListeners) { - // initialize the listener collections, this should only be done if - // the entire cache is refreshed (through refreshRenderedCells) - listenedProperties = new HashSet<Property<?>>(); - visibleComponents = new HashSet<Component>(); - } - - Object[][] cells = new Object[cols + CELL_FIRSTCOL][rows]; - if (rows == 0) { - unregisterPropertiesAndComponents(oldListenedProperties, - oldVisibleComponents); - return cells; - } - - final RowHeaderMode headmode = getRowHeaderMode(); - final boolean[] iscomponent = new boolean[cols]; - for (int i = 0; i < cols; i++) { - iscomponent[i] = columnGenerators.containsKey(colids[i]) - || Component.class.isAssignableFrom(getType(colids[i])); - } - int firstIndexNotInCache; - if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) { - firstIndexNotInCache = pageBufferFirstIndex - + pageBuffer[CELL_ITEMID].length; - } else { - firstIndexNotInCache = -1; - } - - // Creates the page contents - int filledRows = 0; - if (items instanceof Container.Indexed) { - // more efficient implementation for containers supporting access by - // index - - List<?> itemIds = getItemIds(firstIndex, rows); - for (int i = 0; i < rows && i < itemIds.size(); i++) { - Object id = itemIds.get(i); - if (id == null) { - throw new IllegalStateException( - "Null itemId returned from container"); - } - // Start by parsing the values, id should already be set - parseItemIdToCells(cells, id, i, firstIndex, headmode, cols, - colids, firstIndexNotInCache, iscomponent, - oldListenedProperties); - - filledRows++; - } - } else { - // slow back-up implementation for cases where the container does - // not support access by index - - // Gets the first item id - Object id = firstItemId(); - for (int i = 0; i < firstIndex; i++) { - id = nextItemId(id); - } - for (int i = 0; i < rows && id != null; i++) { - // Start by parsing the values, id should already be set - parseItemIdToCells(cells, id, i, firstIndex, headmode, cols, - colids, firstIndexNotInCache, iscomponent, - oldListenedProperties); - - // Gets the next item id for non indexed container - id = nextItemId(id); - - filledRows++; - } - } - - // Assures that all the rows of the cell-buffer are valid - if (filledRows != cells[0].length) { - final Object[][] temp = new Object[cells.length][filledRows]; - for (int i = 0; i < cells.length; i++) { - for (int j = 0; j < filledRows; j++) { - temp[i][j] = cells[i][j]; - } - } - cells = temp; - } - - unregisterPropertiesAndComponents(oldListenedProperties, - oldVisibleComponents); - - return cells; - } - - protected List<Object> getItemIds(int firstIndex, int rows) { - return (List<Object>) ((Container.Indexed) items).getItemIds(firstIndex, - rows); - } - - /** - * Update a cache array for a row, register any relevant listeners etc. - * - * This is an internal method extracted from - * {@link #getVisibleCellsNoCache(int, int, boolean)} and should be removed - * when the Table is rewritten. - */ - private void parseItemIdToCells(Object[][] cells, Object id, int i, - int firstIndex, RowHeaderMode headmode, int cols, Object[] colids, - int firstIndexNotInCache, boolean[] iscomponent, - HashSet<Property<?>> oldListenedProperties) { - - cells[CELL_ITEMID][i] = id; - cells[CELL_KEY][i] = itemIdMapper.key(id); - if (headmode != ROW_HEADER_MODE_HIDDEN) { - switch (headmode) { - case INDEX: - cells[CELL_HEADER][i] = String.valueOf(i + firstIndex + 1); - break; - default: - try { - cells[CELL_HEADER][i] = getItemCaption(id); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - cells[CELL_HEADER][i] = ""; - } - } - try { - cells[CELL_ICON][i] = getItemIcon(id); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - cells[CELL_ICON][i] = null; - } - } - - GeneratedRow generatedRow = rowGenerator != null - ? rowGenerator.generateRow(this, id) : null; - cells[CELL_GENERATED_ROW][i] = generatedRow; - - for (int j = 0; j < cols; j++) { - if (isColumnCollapsed(colids[j])) { - continue; - } - Property<?> p = null; - Object value = ""; - boolean isGeneratedRow = generatedRow != null; - boolean isGeneratedColumn = columnGenerators.containsKey(colids[j]); - boolean isGenerated = isGeneratedRow || isGeneratedColumn; - - if (!isGenerated) { - try { - p = getContainerProperty(id, colids[j]); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - value = null; - } - } - - if (isGeneratedRow) { - if (generatedRow.isSpanColumns() && j > 0) { - value = null; - } else if (generatedRow.isSpanColumns() && j == 0 - && generatedRow.getValue() instanceof Component) { - value = generatedRow.getValue(); - } else if (generatedRow.getText().length > j) { - value = generatedRow.getText()[j]; - } - } else { - // check if current pageBuffer already has row - int index = firstIndex + i; - if (p != null || isGenerated) { - int indexInOldBuffer = index - pageBufferFirstIndex; - if (index < firstIndexNotInCache - && index >= pageBufferFirstIndex - && pageBuffer[CELL_GENERATED_ROW][indexInOldBuffer] == null - && id.equals( - pageBuffer[CELL_ITEMID][indexInOldBuffer])) { - // we already have data in our cache, - // recycle it instead of fetching it via - // getValue/getPropertyValue - value = pageBuffer[CELL_FIRSTCOL + j][indexInOldBuffer]; - if (!isGeneratedColumn && iscomponent[j] - || !(value instanceof Component)) { - listenProperty(p, oldListenedProperties); - } - } else { - if (isGeneratedColumn) { - ColumnGenerator cg = columnGenerators - .get(colids[j]); - try { - value = cg.generateCell(this, id, colids[j]); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - value = null; - } - if (value != null && !(value instanceof Component) - && !(value instanceof String)) { - // Avoid errors if a generator returns - // something - // other than a Component or a String - value = value.toString(); - } - } else if (iscomponent[j]) { - try { - value = p.getValue(); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - value = null; - } - listenProperty(p, oldListenedProperties); - } else if (p != null) { - try { - value = getPropertyValue(id, colids[j], p); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - value = null; - } - /* - * If returned value is Component (via fieldfactory - * or overridden getPropertyValue) we expect it to - * listen property value changes. Otherwise if - * property emits value change events, table will - * start to listen them and refresh content when - * needed. - */ - if (!(value instanceof Component)) { - listenProperty(p, oldListenedProperties); - } - } else { - try { - value = getPropertyValue(id, colids[j], null); - } catch (Exception e) { - exceptionsDuringCachePopulation.add(e); - value = null; - } - } - } - } - } - - if (value instanceof Component) { - registerComponent((Component) value); - } - cells[CELL_FIRSTCOL + j][i] = value; - } - } - - protected void registerComponent(Component component) { - getLogger().log(Level.FINEST, "Registered {0}: {1}", new Object[] { - component.getClass().getSimpleName(), component.getCaption() }); - if (!equals(component.getParent())) { - component.setParent(this); - } - visibleComponents.add(component); - } - - private void listenProperty(Property<?> p, - HashSet<Property<?>> oldListenedProperties) { - if (p instanceof Property.ValueChangeNotifier) { - if (oldListenedProperties == null - || !oldListenedProperties.contains(p)) { - ((Property.ValueChangeNotifier) p).addListener(this); - } - /* - * register listened properties, so we can do proper cleanup to free - * memory. Essential if table has loads of data and it is used for a - * long time. - */ - listenedProperties.add(p); - - } - } - - /** - * @param firstIx - * Index of the first row to process. Global index, not relative - * to page buffer. - * @param count - */ - private void unregisterComponentsAndPropertiesInRows(int firstIx, - int count) { - if (getLogger().isLoggable(Level.FINEST)) { - getLogger().log(Level.FINEST, - "Unregistering components in rows {0}-{1}", - new Object[] { firstIx, (firstIx + count - 1) }); - } - Object[] colids = getVisibleColumns(); - if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) { - int bufSize = pageBuffer[CELL_ITEMID].length; - int ix = firstIx - pageBufferFirstIndex; - ix = ix < 0 ? 0 : ix; - if (ix < bufSize) { - count = count > bufSize - ix ? bufSize - ix : count; - for (int i = 0; i < count; i++) { - for (int c = 0; c < colids.length; c++) { - Object cellVal = pageBuffer[CELL_FIRSTCOL + c][i + ix]; - if (cellVal instanceof Component - && visibleComponents.contains(cellVal)) { - visibleComponents.remove(cellVal); - unregisterComponent((Component) cellVal); - } else { - Property<?> p = getContainerProperty( - pageBuffer[CELL_ITEMID][i + ix], colids[c]); - if (p instanceof ValueChangeNotifier - && listenedProperties.contains(p)) { - listenedProperties.remove(p); - ((ValueChangeNotifier) p).removeListener(this); - } - } - } - } - } - } - } - - /** - * Helper method to remove listeners and maintain correct component - * hierarchy. Detaches properties and components if those are no more - * rendered in client. - * - * @param oldListenedProperties - * set of properties that where listened in last render - * @param oldVisibleComponents - * set of components that where attached in last render - */ - private void unregisterPropertiesAndComponents( - HashSet<Property<?>> oldListenedProperties, - HashSet<Component> oldVisibleComponents) { - if (oldVisibleComponents != null) { - for (final Iterator<Component> i = oldVisibleComponents - .iterator(); i.hasNext();) { - Component c = i.next(); - if (!visibleComponents.contains(c)) { - unregisterComponent(c); - } - } - } - - if (oldListenedProperties != null) { - for (final Iterator<Property<?>> i = oldListenedProperties - .iterator(); i.hasNext();) { - Property.ValueChangeNotifier o = (ValueChangeNotifier) i.next(); - if (!listenedProperties.contains(o)) { - o.removeListener(this); - } - } - } - } - - /** - * This method cleans up a Component that has been generated when Table is - * in editable mode. The component needs to be detached from its parent and - * if it is a field, it needs to be detached from its property data source - * in order to allow garbage collection to take care of removing the unused - * component from memory. - * - * Override this method and getPropertyValue(Object, Object, Property) with - * custom logic if you need to deal with buffered fields. - * - * @see #getPropertyValue(Object, Object, Property) - * - * @param component - * component that should be unregistered. - */ - protected void unregisterComponent(Component component) { - getLogger().log(Level.FINEST, "Unregistered {0}: {1}", new Object[] { - component.getClass().getSimpleName(), component.getCaption() }); - component.setParent(null); - /* - * Also remove property data sources to unregister listeners keeping the - * fields in memory. - */ - if (component instanceof LegacyField) { - LegacyField<?> field = (LegacyField<?>) component; - Property<?> associatedProperty = associatedProperties - .remove(component); - if (associatedProperty != null - && field.getPropertyDataSource() == associatedProperty) { - // Remove the property data source only if it's the one we - // added in getPropertyValue - field.setPropertyDataSource(null); - } - } - } - - /** - * Sets the row header mode. - * <p> - * The mode can be one of the following ones: - * <ul> - * <li>{@link #ROW_HEADER_MODE_HIDDEN}: The row captions are hidden.</li> - * <li>{@link #ROW_HEADER_MODE_ID}: Items Id-objects <code>toString()</code> - * is used as row caption. - * <li>{@link #ROW_HEADER_MODE_ITEM}: Item-objects <code>toString()</code> - * is used as row caption. - * <li>{@link #ROW_HEADER_MODE_PROPERTY}: Property set with - * {@link #setItemCaptionPropertyId(Object)} is used as row header. - * <li>{@link #ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID}: Items Id-objects - * <code>toString()</code> is used as row header. If caption is explicitly - * specified, it overrides the id-caption. - * <li>{@link #ROW_HEADER_MODE_EXPLICIT}: The row headers must be explicitly - * specified.</li> - * <li>{@link #ROW_HEADER_MODE_INDEX}: The index of the item is used as row - * caption. The index mode can only be used with the containers implementing - * <code>Container.Indexed</code> interface.</li> - * </ul> - * The default value is {@link #ROW_HEADER_MODE_HIDDEN} - * </p> - * - * @param mode - * the One of the modes listed above. - */ - public void setRowHeaderMode(RowHeaderMode mode) { - if (mode != null) { - rowHeaderMode = mode; - if (mode != RowHeaderMode.HIDDEN) { - setItemCaptionMode(mode.getItemCaptionMode()); - } - // Assures the visual refresh. No need to reset the page buffer - // before - // as the content has not changed, only the alignments. - refreshRenderedCells(); - } - } - - /** - * Gets the row header mode. - * - * @return the Row header mode. - * @see #setRowHeaderMode - */ - public RowHeaderMode getRowHeaderMode() { - return rowHeaderMode; - } - - /** - * Adds the new row to table and fill the visible cells (except generated - * columns) with given values. - * - * @param cells - * the Object array that is used for filling the visible cells - * new row. The types must be settable to visible column property - * types. - * @param itemId - * the Id the new row. If null, a new id is automatically - * assigned. If given, the table cannot already have a item with - * given id. - * @return Returns item id for the new row. Returns null if operation fails. - */ - public Object addItem(Object[] cells, Object itemId) - throws UnsupportedOperationException { - - // remove generated columns from the list of columns being assigned - final LinkedList<Object> availableCols = new LinkedList<Object>(); - for (Iterator<Object> it = visibleColumns.iterator(); it.hasNext();) { - Object id = it.next(); - if (!columnGenerators.containsKey(id)) { - availableCols.add(id); - } - } - // Checks that a correct number of cells are given - if (cells.length != availableCols.size()) { - return null; - } - - // Creates new item - Item item; - if (itemId == null) { - itemId = items.addItem(); - if (itemId == null) { - return null; - } - item = items.getItem(itemId); - } else { - item = items.addItem(itemId); - } - if (item == null) { - return null; - } - - // Fills the item properties - for (int i = 0; i < availableCols.size(); i++) { - item.getItemProperty(availableCols.get(i)).setValue(cells[i]); - } - - if (!(items instanceof Container.ItemSetChangeNotifier)) { - refreshRowCache(); - } - - return itemId; - } - - /** - * Discards and recreates the internal row cache. Call this if you make - * changes that affect the rows but the information about the changes are - * not automatically propagated to the Table. - * <p> - * Do not call this e.g. if you have updated the data model through a - * Property. These types of changes are automatically propagated to the - * Table. - * <p> - * A typical case when this is needed is if you update a generator (e.g. - * CellStyleGenerator) and want to ensure that the rows are redrawn with new - * styles. - * <p> - * <i>Note that calling this method is not cheap so avoid calling it - * unnecessarily.</i> - * - * @since 6.7.2 - */ - public void refreshRowCache() { - resetPageBuffer(); - refreshRenderedCells(); - } - - /** - * Sets the Container that serves as the data source of the viewer. As a - * side-effect the table's selection value is set to null as the old - * selection might not exist in new Container.<br> - * <br> - * All rows and columns are generated as visible using this method. If the - * new container contains properties that are not meant to be shown you - * should use {@link Table#setContainerDataSource(Container, Collection)} - * instead, especially if the table is editable. - * <p> - * Keeps propertyValueConverters if the corresponding id exists in the new - * data source and is of a compatible type. - * </p> - * - * @param newDataSource - * the new data source. - */ - @Override - public void setContainerDataSource(Container newDataSource) { - if (newDataSource == null) { - newDataSource = new IndexedContainer(); - } - - Collection<Object> generated; - if (columnGenerators != null) { - generated = columnGenerators.keySet(); - } else { - generated = Collections.emptyList(); - } - List<Object> visibleIds = new ArrayList<Object>(); - if (generated.isEmpty()) { - visibleIds.addAll(newDataSource.getContainerPropertyIds()); - } else { - for (Object id : newDataSource.getContainerPropertyIds()) { - // don't add duplicates - if (!generated.contains(id)) { - visibleIds.add(id); - } - } - // generated columns to the end - visibleIds.addAll(generated); - } - setContainerDataSource(newDataSource, visibleIds); - } - - /** - * Sets the container data source and the columns that will be visible. - * Columns are shown in the collection's iteration order. - * <p> - * Keeps propertyValueConverters if the corresponding id exists in the new - * data source and is of a compatible type. - * </p> - * - * @see Table#setContainerDataSource(Container) - * @see Table#setVisibleColumns(Object[]) - * @see Table#setConverter(Object, Converter<String, ?>) - * - * @param newDataSource - * the new data source. - * @param visibleIds - * IDs of the visible columns - */ - public void setContainerDataSource(Container newDataSource, - Collection<?> visibleIds) { - - disableContentRefreshing(); - - if (newDataSource == null) { - newDataSource = new IndexedContainer(); - } - if (visibleIds == null) { - visibleIds = new ArrayList<Object>(); - } - - // Retain propertyValueConverters if their corresponding ids are - // properties of the new - // data source and are of a compatible type - if (propertyValueConverters != null) { - Collection<?> newPropertyIds = newDataSource - .getContainerPropertyIds(); - LinkedList<Object> retainableValueConverters = new LinkedList<Object>(); - for (Object propertyId : newPropertyIds) { - LegacyConverter<String, ?> converter = getConverter(propertyId); - if (converter != null) { - if (typeIsCompatible(converter.getModelType(), - newDataSource.getType(propertyId))) { - retainableValueConverters.add(propertyId); - } - } - } - propertyValueConverters.keySet() - .retainAll(retainableValueConverters); - } - - // Assures that the data source is ordered by making unordered - // containers ordered by wrapping them - if (newDataSource instanceof Container.Ordered) { - super.setContainerDataSource(newDataSource); - } else { - super.setContainerDataSource( - new ContainerOrderedWrapper(newDataSource)); - } - - // Resets page position - currentPageFirstItemId = null; - currentPageFirstItemIndex = 0; - - // Resets column properties - if (collapsedColumns != null) { - collapsedColumns.clear(); - } - - // don't add the same id twice - Collection<Object> col = new LinkedList<Object>(); - for (Iterator<?> it = visibleIds.iterator(); it.hasNext();) { - Object id = it.next(); - if (!col.contains(id)) { - col.add(id); - } - } - - setVisibleColumns(col.toArray()); - - // Assure visual refresh - resetPageBuffer(); - - enableContentRefreshing(true); - } - - /** - * Checks if class b can be safely assigned to class a. - * - * @param a - * @param b - * @return - */ - private boolean typeIsCompatible(Class<?> a, Class<?> b) { - // TODO Implement this check properly - // Basically we need to do a a.isAssignableFrom(b) - // with special considerations for primitive types. - return true; - } - - /** - * Gets items ids from a range of key values - * - * @param itemId - * The start key - * @param length - * amount of items to be retrieved - * @return - */ - private LinkedHashSet<Object> getItemIdsInRange(Object itemId, - final int length) { - LinkedHashSet<Object> ids = new LinkedHashSet<Object>(); - for (int i = 0; i < length; i++) { - assert itemId != null; // should not be null unless client-server - // are out of sync - ids.add(itemId); - itemId = nextItemId(itemId); - } - return ids; - } - - /** - * Handles selection if selection is a multiselection - * - * @param variables - * The variables - */ - private void handleSelectedItems(Map<String, Object> variables) { - final String[] ka = (String[]) variables.get("selected"); - final String[] ranges = (String[]) variables.get("selectedRanges"); - - Set<Object> renderedButNotSelectedItemIds = getCurrentlyRenderedItemIds(); - - @SuppressWarnings("unchecked") - HashSet<Object> newValue = new LinkedHashSet<Object>( - (Collection<Object>) getValue()); - - if (variables.containsKey("clearSelections")) { - // the client side has instructed to swipe all previous selections - newValue.clear(); - } - - /* - * Then add (possibly some of them back) rows that are currently - * selected on the client side (the ones that the client side is aware - * of). - */ - for (int i = 0; i < ka.length; i++) { - // key to id - final Object id = itemIdMapper.get(ka[i]); - if (!isNullSelectionAllowed() - && (id == null || id == getNullSelectionItemId())) { - // skip empty selection if nullselection is not allowed - markAsDirty(); - } else if (id != null && containsId(id)) { - newValue.add(id); - renderedButNotSelectedItemIds.remove(id); - } - } - - /* Add range items aka shift clicked multiselection areas */ - if (ranges != null) { - for (String range : ranges) { - String[] split = range.split("-"); - Object startItemId = itemIdMapper.get(split[0]); - int length = Integer.valueOf(split[1]); - LinkedHashSet<Object> itemIdsInRange = getItemIdsInRange( - startItemId, length); - newValue.addAll(itemIdsInRange); - renderedButNotSelectedItemIds.removeAll(itemIdsInRange); - } - } - /* - * finally clear all currently rendered rows (the ones that the client - * side counterpart is aware of) that the client didn't send as selected - */ - newValue.removeAll(renderedButNotSelectedItemIds); - - if (!isNullSelectionAllowed() && newValue.isEmpty()) { - // empty selection not allowed, keep old value - markAsDirty(); - return; - } - - setValue(newValue, true); - - } - - private Set<Object> getCurrentlyRenderedItemIds() { - HashSet<Object> ids = new HashSet<Object>(); - if (pageBuffer != null) { - for (int i = 0; i < pageBuffer[CELL_ITEMID].length; i++) { - ids.add(pageBuffer[CELL_ITEMID][i]); - } - } - return ids; - } - - /* Component basics */ - - /** - * Invoked when the value of a variable has changed. - * - * @see com.vaadin.ui.Select#changeVariables(java.lang.Object, - * java.util.Map) - */ - - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - - boolean clientNeedsContentRefresh = false; - - handleClickEvent(variables); - - handleColumnResizeEvent(variables); - - handleColumnWidthUpdates(variables); - - disableContentRefreshing(); - - if (!isSelectable() && variables.containsKey("selected")) { - // Not-selectable is a special case, AbstractSelect does not support - // TODO could be optimized. - variables = new HashMap<String, Object>(variables); - variables.remove("selected"); - } - - /* - * The AbstractSelect cannot handle the multiselection properly, instead - * we handle it ourself - */ - else if (isSelectable() && isMultiSelect() - && variables.containsKey("selected") - && multiSelectMode == MultiSelectMode.DEFAULT) { - handleSelectedItems(variables); - variables = new HashMap<String, Object>(variables); - variables.remove("selected"); - } - - super.changeVariables(source, variables); - - // Client might update the pagelength if Table height is fixed - if (variables.containsKey("pagelength")) { - // Sets pageLength directly to avoid repaint that setter causes - pageLength = (Integer) variables.get("pagelength"); - } - - // Page start index - if (variables.containsKey("firstvisible")) { - final Integer value = (Integer) variables.get("firstvisible"); - if (value != null) { - setCurrentPageFirstItemIndex(value.intValue(), false); - } - } - - // Sets requested firstrow and rows for the next paint - if (variables.containsKey("reqfirstrow") - || variables.containsKey("reqrows")) { - - try { - firstToBeRenderedInClient = ((Integer) variables - .get("firstToBeRendered")).intValue(); - lastToBeRenderedInClient = ((Integer) variables - .get("lastToBeRendered")).intValue(); - } catch (Exception e) { - // FIXME: Handle exception - getLogger().log(Level.FINER, - "Could not parse the first and/or last rows.", e); - } - - // respect suggested rows only if table is not otherwise updated - // (row caches emptied by other event) - if (!containerChangeToBeRendered) { - Integer value = (Integer) variables.get("reqfirstrow"); - if (value != null) { - reqFirstRowToPaint = value.intValue(); - } - - value = (Integer) variables.get("reqrows"); - if (value != null) { - reqRowsToPaint = value.intValue(); - int size = size(); - // sanity check - - if (reqFirstRowToPaint >= size) { - reqFirstRowToPaint = size; - } - - if (reqFirstRowToPaint + reqRowsToPaint > size) { - reqRowsToPaint = size - reqFirstRowToPaint; - } - } - } - if (getLogger().isLoggable(Level.FINEST)) { - getLogger().log(Level.FINEST, "Client wants rows {0}-{1}", - new Object[] { reqFirstRowToPaint, - (reqFirstRowToPaint + reqRowsToPaint - 1) }); - } - clientNeedsContentRefresh = true; - } - - if (isSortEnabled()) { - // Sorting - boolean doSort = false; - if (variables.containsKey("sortcolumn")) { - final String colId = (String) variables.get("sortcolumn"); - if (colId != null && !"".equals(colId) - && !"null".equals(colId)) { - final Object id = columnIdMap.get(colId); - setSortContainerPropertyId(id, false); - doSort = true; - } - } - if (variables.containsKey("sortascending")) { - final boolean state = ((Boolean) variables.get("sortascending")) - .booleanValue(); - if (state != sortAscending) { - setSortAscending(state, false); - doSort = true; - } - } - if (doSort) { - this.sort(); - resetPageBuffer(); - } - } - - // Dynamic column hide/show and order - // Update visible columns - if (isColumnCollapsingAllowed()) { - if (variables.containsKey("collapsedcolumns")) { - try { - final Object[] ids = (Object[]) variables - .get("collapsedcolumns"); - Set<Object> idSet = new HashSet<Object>(); - for (Object id : ids) { - idSet.add(columnIdMap.get(id.toString())); - } - for (final Iterator<Object> it = visibleColumns - .iterator(); it.hasNext();) { - Object propertyId = it.next(); - if (isColumnCollapsed(propertyId)) { - if (!idSet.contains(propertyId)) { - setColumnCollapsed(propertyId, false); - } - } else if (idSet.contains(propertyId)) { - setColumnCollapsed(propertyId, true); - } - } - } catch (final Exception e) { - // FIXME: Handle exception - getLogger().log(Level.FINER, - "Could not determine column collapsing state", e); - } - clientNeedsContentRefresh = true; - } - } - if (isColumnReorderingAllowed()) { - if (variables.containsKey("columnorder")) { - try { - final Object[] ids = (Object[]) variables - .get("columnorder"); - // need a real Object[], ids can be a String[] - final Object[] idsTemp = new Object[ids.length]; - for (int i = 0; i < ids.length; i++) { - idsTemp[i] = columnIdMap.get(ids[i].toString()); - } - setColumnOrder(idsTemp); - if (hasListeners(ColumnReorderEvent.class)) { - fireEvent(new ColumnReorderEvent(this)); - } - } catch (final Exception e) { - // FIXME: Handle exception - getLogger().log(Level.FINER, - "Could not determine column reordering state", e); - } - clientNeedsContentRefresh = true; - } - } - - enableContentRefreshing(clientNeedsContentRefresh); - - // Actions - if (variables.containsKey("action")) { - final StringTokenizer st = new StringTokenizer( - (String) variables.get("action"), ","); - if (st.countTokens() == 2) { - final Object itemId = itemIdMapper.get(st.nextToken()); - final Action action = actionMapper.get(st.nextToken()); - - if (action != null && (itemId == null || containsId(itemId)) - && actionHandlers != null) { - for (Handler ah : actionHandlers) { - ah.handleAction(action, this, itemId); - } - } - } - } - - } - - /** - * Handles click event - * - * @param variables - */ - private void handleClickEvent(Map<String, Object> variables) { - - // Item click event - if (variables.containsKey("clickEvent")) { - String key = (String) variables.get("clickedKey"); - Object itemId = itemIdMapper.get(key); - Object propertyId = null; - String colkey = (String) variables.get("clickedColKey"); - // click is not necessary on a property - if (colkey != null) { - propertyId = columnIdMap.get(colkey); - } - MouseEventDetails evt = MouseEventDetails - .deSerialize((String) variables.get("clickEvent")); - Item item = getItem(itemId); - if (item != null) { - fireEvent(new ItemClickEvent(this, item, itemId, propertyId, - evt)); - } - } - - // Header click event - else if (variables.containsKey("headerClickEvent")) { - - MouseEventDetails details = MouseEventDetails - .deSerialize((String) variables.get("headerClickEvent")); - - Object cid = variables.get("headerClickCID"); - Object propertyId = null; - if (cid != null) { - propertyId = columnIdMap.get(cid.toString()); - } - fireEvent(new HeaderClickEvent(this, propertyId, details)); - } - - // Footer click event - else if (variables.containsKey("footerClickEvent")) { - MouseEventDetails details = MouseEventDetails - .deSerialize((String) variables.get("footerClickEvent")); - - Object cid = variables.get("footerClickCID"); - Object propertyId = null; - if (cid != null) { - propertyId = columnIdMap.get(cid.toString()); - } - fireEvent(new FooterClickEvent(this, propertyId, details)); - } - } - - /** - * Handles the column resize event sent by the client. - * - * @param variables - */ - private void handleColumnResizeEvent(Map<String, Object> variables) { - if (variables.containsKey("columnResizeEventColumn")) { - Object cid = variables.get("columnResizeEventColumn"); - Object propertyId = null; - if (cid != null) { - propertyId = columnIdMap.get(cid.toString()); - - Object prev = variables.get("columnResizeEventPrev"); - int previousWidth = -1; - if (prev != null) { - previousWidth = Integer.valueOf(prev.toString()); - } - - Object curr = variables.get("columnResizeEventCurr"); - int currentWidth = -1; - if (curr != null) { - currentWidth = Integer.valueOf(curr.toString()); - } - - fireColumnResizeEvent(propertyId, previousWidth, currentWidth); - } - } - } - - private void fireColumnCollapseEvent(Object propertyId) { - fireEvent(new ColumnCollapseEvent(this, propertyId)); - } - - private void fireColumnResizeEvent(Object propertyId, int previousWidth, - int currentWidth) { - /* - * Update the sizes on the server side. If a column previously had a - * expand ratio and the user resized the column then the expand ratio - * will be turned into a static pixel size. - */ - setColumnWidth(propertyId, currentWidth); - - fireEvent(new ColumnResizeEvent(this, propertyId, previousWidth, - currentWidth)); - } - - private void handleColumnWidthUpdates(Map<String, Object> variables) { - if (variables.containsKey("columnWidthUpdates")) { - String[] events = (String[]) variables.get("columnWidthUpdates"); - for (String str : events) { - String[] eventDetails = str.split(":"); - Object propertyId = columnIdMap.get(eventDetails[0]); - if (propertyId == null) { - propertyId = ROW_HEADER_FAKE_PROPERTY_ID; - } - int width = Integer.valueOf(eventDetails[1]); - setColumnWidth(propertyId, width); - } - } - } - - /** - * Go to mode where content updates are not done. This is due we want to - * bypass expensive content for some reason (like when we know we may have - * other content changes on their way). - * - * @return true if content refresh flag was enabled prior this call - */ - protected boolean disableContentRefreshing() { - boolean wasDisabled = isContentRefreshesEnabled; - isContentRefreshesEnabled = false; - return wasDisabled; - } - - /** - * Go to mode where content content refreshing has effect. - * - * @param refreshContent - * true if content refresh needs to be done - */ - protected void enableContentRefreshing(boolean refreshContent) { - isContentRefreshesEnabled = true; - if (refreshContent) { - refreshRenderedCells(); - // Ensure that client gets a response - markAsDirty(); - } - } - - @Override - public void beforeClientResponse(boolean initial) { - super.beforeClientResponse(initial); - - // Ensure pageBuffer is filled before sending the response to avoid - // calls to markAsDirty during paint - getVisibleCells(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.AbstractSelect#paintContent(com.vaadin. - * terminal.PaintTarget) - */ - - @Override - public void paintContent(PaintTarget target) throws PaintException { - isBeingPainted = true; - try { - doPaintContent(target); - } finally { - isBeingPainted = false; - } - } - - private void doPaintContent(PaintTarget target) throws PaintException { - /* - * Body actions - Actions which has the target null and can be invoked - * by right clicking on the table body. - */ - final Set<Action> actionSet = findAndPaintBodyActions(target); - - final Object[][] cells = getVisibleCells(); - int rows = findNumRowsToPaint(target, cells); - - int total = size(); - if (shouldHideNullSelectionItem()) { - total--; - rows--; - } - - // Table attributes - paintTableAttributes(target, rows, total); - - paintVisibleColumnOrder(target); - - // Rows - if (isPartialRowUpdate() && painted && !target.isFullRepaint()) { - paintPartialRowUpdate(target, actionSet); - } else if (target.isFullRepaint() || isRowCacheInvalidated()) { - paintRows(target, cells, actionSet); - setRowCacheInvalidated(false); - } - - /* - * Send the page buffer indexes to ensure that the client side stays in - * sync. Otherwise we _might_ have the situation where the client side - * discards too few or too many rows, causing out of sync issues. - */ - int pageBufferLastIndex = pageBufferFirstIndex - + pageBuffer[CELL_ITEMID].length - 1; - target.addAttribute(TableConstants.ATTRIBUTE_PAGEBUFFER_FIRST, - pageBufferFirstIndex); - target.addAttribute(TableConstants.ATTRIBUTE_PAGEBUFFER_LAST, - pageBufferLastIndex); - - paintSorting(target); - - resetVariablesAndPageBuffer(target); - - // Actions - paintActions(target, actionSet); - - paintColumnOrder(target); - - // Available columns - paintAvailableColumns(target); - - paintVisibleColumns(target); - - if (keyMapperReset) { - keyMapperReset = false; - target.addAttribute(TableConstants.ATTRIBUTE_KEY_MAPPER_RESET, - true); - } - - if (dropHandler != null) { - dropHandler.getAcceptCriterion().paint(target); - } - - painted = true; - } - - private void setRowCacheInvalidated(boolean invalidated) { - rowCacheInvalidated = invalidated; - } - - protected boolean isRowCacheInvalidated() { - return rowCacheInvalidated; - } - - private void paintPartialRowUpdate(PaintTarget target, - Set<Action> actionSet) throws PaintException { - paintPartialRowUpdates(target, actionSet); - paintPartialRowAdditions(target, actionSet); - } - - private void paintPartialRowUpdates(PaintTarget target, - Set<Action> actionSet) throws PaintException { - final boolean[] iscomponent = findCellsWithComponents(); - - int firstIx = getFirstUpdatedItemIndex(); - int count = getUpdatedRowCount(); - - target.startTag("urows"); - target.addAttribute("firsturowix", firstIx); - target.addAttribute("numurows", count); - - // Partial row updates bypass the normal caching mechanism. - Object[][] cells = getVisibleCellsUpdateCacheRows(firstIx, count); - for (int indexInRowbuffer = 0; indexInRowbuffer < count; indexInRowbuffer++) { - final Object itemId = cells[CELL_ITEMID][indexInRowbuffer]; - - if (shouldHideNullSelectionItem()) { - // Remove null selection item if null selection is not allowed - continue; - } - - paintRow(target, cells, isEditable(), actionSet, iscomponent, - indexInRowbuffer, itemId); - } - target.endTag("urows"); - maybeThrowCacheUpdateExceptions(); - } - - private void paintPartialRowAdditions(PaintTarget target, - Set<Action> actionSet) throws PaintException { - final boolean[] iscomponent = findCellsWithComponents(); - - int firstIx = getFirstAddedItemIndex(); - int count = getAddedRowCount(); - - target.startTag("prows"); - - if (!shouldHideAddedRows()) { - getLogger().log(Level.FINEST, - "Paint rows for add. Index: {0}, count: {1}.", - new Object[] { firstIx, count }); - - // Partial row additions bypass the normal caching mechanism. - Object[][] cells = getVisibleCellsInsertIntoCache(firstIx, count); - if (cells[0].length < count) { - // delete the rows below, since they will fall beyond the cache - // page. - target.addAttribute("delbelow", true); - count = cells[0].length; - } - - for (int indexInRowbuffer = 0; indexInRowbuffer < count; indexInRowbuffer++) { - final Object itemId = cells[CELL_ITEMID][indexInRowbuffer]; - if (shouldHideNullSelectionItem()) { - // Remove null selection item if null selection is not - // allowed - continue; - } - - paintRow(target, cells, isEditable(), actionSet, iscomponent, - indexInRowbuffer, itemId); - } - } else { - getLogger().log(Level.FINEST, - "Paint rows for remove. Index: {0}, count: {1}.", - new Object[] { firstIx, count }); - removeRowsFromCacheAndFillBottom(firstIx, count); - target.addAttribute("hide", true); - } - - target.addAttribute("firstprowix", firstIx); - target.addAttribute("numprows", count); - target.endTag("prows"); - maybeThrowCacheUpdateExceptions(); - } - - /** - * Subclass and override this to enable partial row updates and additions, - * which bypass the normal caching mechanism. This is useful for e.g. - * TreeTable. - * - * @return true if this update is a partial row update, false if not. For - * plain Table it is always false. - */ - protected boolean isPartialRowUpdate() { - return false; - } - - /** - * Subclass and override this to enable partial row additions, bypassing the - * normal caching mechanism. This is useful for e.g. TreeTable, where - * expanding a node should only fetch and add the items inside of that node. - * - * @return The index of the first added item. For plain Table it is always - * 0. - */ - protected int getFirstAddedItemIndex() { - return 0; - } - - /** - * Subclass and override this to enable partial row additions, bypassing the - * normal caching mechanism. This is useful for e.g. TreeTable, where - * expanding a node should only fetch and add the items inside of that node. - * - * @return the number of rows to be added, starting at the index returned by - * {@link #getFirstAddedItemIndex()}. For plain Table it is always - * 0. - */ - protected int getAddedRowCount() { - return 0; - } - - /** - * Subclass and override this to enable removing of rows, bypassing the - * normal caching and lazy loading mechanism. This is useful for e.g. - * TreeTable, when you need to hide certain rows as a node is collapsed. - * - * This should return true if the rows pointed to by - * {@link #getFirstAddedItemIndex()} and {@link #getAddedRowCount()} should - * be hidden instead of added. - * - * @return whether the rows to add (see {@link #getFirstAddedItemIndex()} - * and {@link #getAddedRowCount()}) should be added or hidden. For - * plain Table it is always false. - */ - protected boolean shouldHideAddedRows() { - return false; - } - - /** - * Subclass and override this to enable partial row updates, bypassing the - * normal caching and lazy loading mechanism. This is useful for updating - * the state of certain rows, e.g. in the TreeTable the collapsed state of a - * single node is updated using this mechanism. - * - * @return the index of the first item to be updated. For plain Table it is - * always 0. - */ - protected int getFirstUpdatedItemIndex() { - return 0; - } - - /** - * Subclass and override this to enable partial row updates, bypassing the - * normal caching and lazy loading mechanism. This is useful for updating - * the state of certain rows, e.g. in the TreeTable the collapsed state of a - * single node is updated using this mechanism. - * - * @return the number of rows to update, starting at the index returned by - * {@link #getFirstUpdatedItemIndex()}. For plain table it is always - * 0. - */ - protected int getUpdatedRowCount() { - return 0; - } - - private void paintTableAttributes(PaintTarget target, int rows, int total) - throws PaintException { - paintTabIndex(target); - paintDragMode(target); - paintSelectMode(target); - paintTableChildLayoutMeasureMode(target); - - if (cacheRate != CACHE_RATE_DEFAULT) { - target.addAttribute("cr", cacheRate); - } - - target.addAttribute("cols", getVisibleColumns().length); - target.addAttribute("rows", rows); - - target.addAttribute("firstrow", (reqFirstRowToPaint >= 0 - ? reqFirstRowToPaint : firstToBeRenderedInClient)); - target.addAttribute("totalrows", total); - if (getPageLength() != 0) { - target.addAttribute("pagelength", getPageLength()); - } - if (areColumnHeadersEnabled()) { - target.addAttribute("colheaders", true); - } - if (rowHeadersAreEnabled()) { - target.addAttribute("rowheaders", true); - } - - target.addAttribute("colfooters", columnFootersVisible); - - // The cursors are only shown on pageable table - if (getCurrentPageFirstItemIndex() != 0 || getPageLength() > 0) { - target.addVariable(this, "firstvisible", - getCurrentPageFirstItemIndex()); - target.addVariable(this, "firstvisibleonlastpage", - currentPageFirstItemIndexOnLastPage); - } - } - - /** - * Resets and paints "to be painted next" variables. Also reset pageBuffer - */ - private void resetVariablesAndPageBuffer(PaintTarget target) - throws PaintException { - reqFirstRowToPaint = -1; - reqRowsToPaint = -1; - containerChangeToBeRendered = false; - target.addVariable(this, "reqrows", reqRowsToPaint); - target.addVariable(this, "reqfirstrow", reqFirstRowToPaint); - } - - private boolean areColumnHeadersEnabled() { - return getColumnHeaderMode() != ColumnHeaderMode.HIDDEN; - } - - private void paintVisibleColumns(PaintTarget target) throws PaintException { - target.startTag("visiblecolumns"); - if (rowHeadersAreEnabled()) { - target.startTag("column"); - target.addAttribute("cid", ROW_HEADER_COLUMN_KEY); - paintColumnWidth(target, ROW_HEADER_FAKE_PROPERTY_ID); - paintColumnExpandRatio(target, ROW_HEADER_FAKE_PROPERTY_ID); - target.endTag("column"); - } - final Collection<?> sortables = getSortableContainerPropertyIds(); - for (Object colId : visibleColumns) { - if (colId != null) { - target.startTag("column"); - target.addAttribute("cid", columnIdMap.key(colId)); - final String head = getColumnHeader(colId); - target.addAttribute("caption", (head != null ? head : "")); - final String foot = getColumnFooter(colId); - target.addAttribute("fcaption", (foot != null ? foot : "")); - if (isColumnCollapsed(colId)) { - target.addAttribute("collapsed", true); - } - if (areColumnHeadersEnabled()) { - if (getColumnIcon(colId) != null) { - target.addAttribute("icon", getColumnIcon(colId)); - } - if (sortables.contains(colId)) { - target.addAttribute("sortable", true); - } - } - if (!Align.LEFT.equals(getColumnAlignment(colId))) { - target.addAttribute("align", - getColumnAlignment(colId).toString()); - } - paintColumnWidth(target, colId); - paintColumnExpandRatio(target, colId); - target.endTag("column"); - } - } - target.endTag("visiblecolumns"); - } - - private void paintAvailableColumns(PaintTarget target) - throws PaintException { - if (columnCollapsingAllowed) { - final HashSet<Object> collapsedCols = new HashSet<Object>(); - for (Object colId : visibleColumns) { - if (isColumnCollapsed(colId)) { - collapsedCols.add(colId); - } - } - final String[] collapsedKeys = new String[collapsedCols.size()]; - int nextColumn = 0; - for (Object colId : visibleColumns) { - if (isColumnCollapsed(colId)) { - collapsedKeys[nextColumn++] = columnIdMap.key(colId); - } - } - target.addVariable(this, "collapsedcolumns", collapsedKeys); - - final String[] noncollapsibleKeys = new String[noncollapsibleColumns - .size()]; - nextColumn = 0; - for (Object colId : noncollapsibleColumns) { - noncollapsibleKeys[nextColumn++] = columnIdMap.key(colId); - } - target.addVariable(this, "noncollapsiblecolumns", - noncollapsibleKeys); - } - - } - - private void paintActions(PaintTarget target, final Set<Action> actionSet) - throws PaintException { - if (!actionSet.isEmpty()) { - target.addVariable(this, "action", ""); - target.startTag("actions"); - for (Action a : actionSet) { - target.startTag("action"); - if (a.getCaption() != null) { - target.addAttribute("caption", a.getCaption()); - } - if (a.getIcon() != null) { - target.addAttribute("icon", a.getIcon()); - } - target.addAttribute("key", actionMapper.key(a)); - target.endTag("action"); - } - target.endTag("actions"); - } - } - - private void paintColumnOrder(PaintTarget target) throws PaintException { - if (columnReorderingAllowed) { - final String[] colorder = new String[visibleColumns.size()]; - int i = 0; - for (Object colId : visibleColumns) { - colorder[i++] = columnIdMap.key(colId); - } - target.addVariable(this, "columnorder", colorder); - } - } - - private void paintSorting(PaintTarget target) throws PaintException { - // Sorting - if (getContainerDataSource() instanceof Container.Sortable) { - target.addVariable(this, "sortcolumn", - columnIdMap.key(sortContainerPropertyId)); - target.addVariable(this, "sortascending", sortAscending); - } - } - - private void paintRows(PaintTarget target, final Object[][] cells, - final Set<Action> actionSet) throws PaintException { - final boolean[] iscomponent = findCellsWithComponents(); - - target.startTag("rows"); - // cells array contains all that are supposed to be visible on client, - // but we'll start from the one requested by client - int start = 0; - if (reqFirstRowToPaint != -1 && firstToBeRenderedInClient != -1) { - start = reqFirstRowToPaint - firstToBeRenderedInClient; - } - int end = cells[0].length; - if (reqRowsToPaint != -1) { - end = start + reqRowsToPaint; - } - // sanity check - if (lastToBeRenderedInClient != -1 && lastToBeRenderedInClient < end) { - end = lastToBeRenderedInClient + 1; - } - if (start > cells[CELL_ITEMID].length || start < 0) { - start = 0; - } - if (end > cells[CELL_ITEMID].length) { - end = cells[CELL_ITEMID].length; - } - - for (int indexInRowbuffer = start; indexInRowbuffer < end; indexInRowbuffer++) { - final Object itemId = cells[CELL_ITEMID][indexInRowbuffer]; - - if (shouldHideNullSelectionItem()) { - // Remove null selection item if null selection is not allowed - continue; - } - - paintRow(target, cells, isEditable(), actionSet, iscomponent, - indexInRowbuffer, itemId); - } - target.endTag("rows"); - } - - private boolean[] findCellsWithComponents() { - final boolean[] isComponent = new boolean[visibleColumns.size()]; - int ix = 0; - for (Object columnId : visibleColumns) { - if (columnGenerators.containsKey(columnId)) { - isComponent[ix++] = true; - } else { - final Class<?> colType = getType(columnId); - isComponent[ix++] = colType != null - && Component.class.isAssignableFrom(colType); - } - } - return isComponent; - } - - private void paintVisibleColumnOrder(PaintTarget target) { - // Visible column order - final ArrayList<String> visibleColOrder = new ArrayList<String>(); - for (Object columnId : visibleColumns) { - if (!isColumnCollapsed(columnId)) { - visibleColOrder.add(columnIdMap.key(columnId)); - } - } - target.addAttribute("vcolorder", visibleColOrder.toArray()); - } - - private Set<Action> findAndPaintBodyActions(PaintTarget target) { - Set<Action> actionSet = new LinkedHashSet<Action>(); - if (actionHandlers != null) { - final ArrayList<String> keys = new ArrayList<String>(); - for (Handler ah : actionHandlers) { - // Getting actions for the null item, which in this case means - // the body item - final Action[] actions = ah.getActions(null, this); - if (actions != null) { - for (Action action : actions) { - actionSet.add(action); - keys.add(actionMapper.key(action)); - } - } - } - target.addAttribute("alb", keys.toArray()); - } - return actionSet; - } - - private boolean shouldHideNullSelectionItem() { - return !isNullSelectionAllowed() && getNullSelectionItemId() != null - && containsId(getNullSelectionItemId()); - } - - private int findNumRowsToPaint(PaintTarget target, final Object[][] cells) - throws PaintException { - int rows; - if (reqRowsToPaint >= 0) { - rows = reqRowsToPaint; - } else { - rows = cells[0].length; - if (alwaysRecalculateColumnWidths) { - // TODO experimental feature for now: tell the client to - // recalculate column widths. - // We'll only do this for paints that do not originate from - // table scroll/cache requests (i.e when reqRowsToPaint<0) - target.addAttribute("recalcWidths", true); - } - } - return rows; - } - - private void paintSelectMode(PaintTarget target) throws PaintException { - if (multiSelectMode != MultiSelectMode.DEFAULT) { - target.addAttribute("multiselectmode", multiSelectMode.ordinal()); - } - if (isSelectable()) { - target.addAttribute("selectmode", - (isMultiSelect() ? "multi" : "single")); - } else { - target.addAttribute("selectmode", "none"); - } - if (!isNullSelectionAllowed()) { - target.addAttribute("nsa", false); - } - - // selection support - // The select variable is only enabled if selectable - if (isSelectable()) { - target.addVariable(this, "selected", findSelectedKeys()); - } - } - - private String[] findSelectedKeys() { - LinkedList<String> selectedKeys = new LinkedList<String>(); - if (isMultiSelect()) { - HashSet<?> sel = new HashSet<Object>((Set<?>) getValue()); - Collection<?> vids = getVisibleItemIds(); - for (Iterator<?> it = vids.iterator(); it.hasNext();) { - Object id = it.next(); - if (sel.contains(id)) { - selectedKeys.add(itemIdMapper.key(id)); - } - } - } else { - Object value = getValue(); - if (value == null) { - value = getNullSelectionItemId(); - } - if (value != null) { - selectedKeys.add(itemIdMapper.key(value)); - } - } - return selectedKeys.toArray(new String[selectedKeys.size()]); - } - - private void paintDragMode(PaintTarget target) throws PaintException { - if (dragMode != TableDragMode.NONE) { - target.addAttribute("dragmode", dragMode.ordinal()); - } - } - - private void paintTabIndex(PaintTarget target) throws PaintException { - // The tab ordering number - if (getTabIndex() > 0) { - target.addAttribute("tabindex", getTabIndex()); - } - } - - private void paintColumnWidth(PaintTarget target, final Object columnId) - throws PaintException { - if (columnWidths.containsKey(columnId)) { - target.addAttribute("width", getColumnWidth(columnId)); - } - } - - private void paintColumnExpandRatio(PaintTarget target, - final Object columnId) throws PaintException { - if (columnExpandRatios.containsKey(columnId)) { - target.addAttribute("er", getColumnExpandRatio(columnId)); - } - } - - private void paintTableChildLayoutMeasureMode(PaintTarget target) - throws PaintException { - target.addAttribute("measurehint", getChildMeasurementHint().ordinal()); - } - - /** - * Checks whether row headers are visible. - * - * @return {@code false} if row headers are hidden, {@code true} otherwise - * @since 7.3.9 - */ - protected boolean rowHeadersAreEnabled() { - return getRowHeaderMode() != RowHeaderMode.HIDDEN; - } - - private void paintRow(PaintTarget target, final Object[][] cells, - final boolean iseditable, final Set<Action> actionSet, - final boolean[] iscomponent, int indexInRowbuffer, - final Object itemId) throws PaintException { - target.startTag("tr"); - - paintRowAttributes(target, cells, actionSet, indexInRowbuffer, itemId); - - // cells - int currentColumn = 0; - for (final Iterator<Object> it = visibleColumns.iterator(); it - .hasNext(); currentColumn++) { - final Object columnId = it.next(); - if (columnId == null || isColumnCollapsed(columnId)) { - continue; - } - /* - * For each cell, if a cellStyleGenerator is specified, get the - * specific style for the cell. If there is any, add it to the - * target. - */ - if (cellStyleGenerator != null) { - String cellStyle = cellStyleGenerator.getStyle(this, itemId, - columnId); - if (cellStyle != null && !cellStyle.equals("")) { - target.addAttribute("style-" + columnIdMap.key(columnId), - cellStyle); - } - } - - if ((iscomponent[currentColumn] || iseditable - || cells[CELL_GENERATED_ROW][indexInRowbuffer] != null) - && Component.class.isInstance(cells[CELL_FIRSTCOL - + currentColumn][indexInRowbuffer])) { - final Component c = (Component) cells[CELL_FIRSTCOL - + currentColumn][indexInRowbuffer]; - if (c == null || !LegacyCommunicationManager - .isComponentVisibleToClient(c)) { - target.addText(""); - } else { - LegacyPaint.paint(c, target); - } - } else { - target.addText((String) cells[CELL_FIRSTCOL - + currentColumn][indexInRowbuffer]); - } - paintCellTooltips(target, itemId, columnId); - } - - target.endTag("tr"); - } - - private void paintCellTooltips(PaintTarget target, Object itemId, - Object columnId) throws PaintException { - if (itemDescriptionGenerator != null) { - String itemDescription = itemDescriptionGenerator - .generateDescription(this, itemId, columnId); - if (itemDescription != null && !itemDescription.equals("")) { - target.addAttribute("descr-" + columnIdMap.key(columnId), - itemDescription); - } - } - } - - private void paintRowTooltips(PaintTarget target, Object itemId) - throws PaintException { - if (itemDescriptionGenerator != null) { - String rowDescription = itemDescriptionGenerator - .generateDescription(this, itemId, null); - if (rowDescription != null && !rowDescription.equals("")) { - target.addAttribute("rowdescr", rowDescription); - } - } - } - - private void paintRowAttributes(PaintTarget target, final Object[][] cells, - final Set<Action> actionSet, int indexInRowbuffer, - final Object itemId) throws PaintException { - // tr attributes - - paintRowIcon(target, cells, indexInRowbuffer); - paintRowHeader(target, cells, indexInRowbuffer); - paintGeneratedRowInfo(target, cells, indexInRowbuffer); - target.addAttribute("key", - Integer.parseInt(cells[CELL_KEY][indexInRowbuffer].toString())); - - if (isSelected(itemId)) { - target.addAttribute("selected", true); - } - - // Actions - if (actionHandlers != null) { - final ArrayList<String> keys = new ArrayList<String>(); - for (Handler ah : actionHandlers) { - final Action[] aa = ah.getActions(itemId, this); - if (aa != null) { - for (int ai = 0; ai < aa.length; ai++) { - final String key = actionMapper.key(aa[ai]); - actionSet.add(aa[ai]); - keys.add(key); - } - } - } - target.addAttribute("al", keys.toArray()); - } - - /* - * For each row, if a cellStyleGenerator is specified, get the specific - * style for the cell, using null as propertyId. If there is any, add it - * to the target. - */ - if (cellStyleGenerator != null) { - String rowStyle = cellStyleGenerator.getStyle(this, itemId, null); - if (rowStyle != null && !rowStyle.equals("")) { - target.addAttribute("rowstyle", rowStyle); - } - } - - paintRowTooltips(target, itemId); - - paintRowAttributes(target, itemId); - } - - private void paintGeneratedRowInfo(PaintTarget target, Object[][] cells, - int indexInRowBuffer) throws PaintException { - GeneratedRow generatedRow = (GeneratedRow) cells[CELL_GENERATED_ROW][indexInRowBuffer]; - if (generatedRow != null) { - target.addAttribute("gen_html", - generatedRow.isHtmlContentAllowed()); - target.addAttribute("gen_span", generatedRow.isSpanColumns()); - target.addAttribute("gen_widget", - generatedRow.getValue() instanceof Component); - } - } - - protected void paintRowHeader(PaintTarget target, Object[][] cells, - int indexInRowbuffer) throws PaintException { - if (rowHeadersAreEnabled()) { - if (cells[CELL_HEADER][indexInRowbuffer] != null) { - target.addAttribute("caption", - (String) cells[CELL_HEADER][indexInRowbuffer]); - } - } - - } - - protected void paintRowIcon(PaintTarget target, final Object[][] cells, - int indexInRowbuffer) throws PaintException { - if (rowHeadersAreEnabled() - && cells[CELL_ICON][indexInRowbuffer] != null) { - target.addAttribute("icon", - (Resource) cells[CELL_ICON][indexInRowbuffer]); - } - } - - /** - * A method where extended Table implementations may add their custom - * attributes for rows. - * - * @param target - * @param itemId - */ - protected void paintRowAttributes(PaintTarget target, Object itemId) - throws PaintException { - - } - - /** - * Gets the cached visible table contents. - * - * @return the cached visible table contents. - */ - private Object[][] getVisibleCells() { - if (pageBuffer == null) { - refreshRenderedCells(); - } - return pageBuffer; - } - - /** - * Gets the value of property. - * - * By default if the table is editable the fieldFactory is used to create - * editors for table cells. Otherwise formatPropertyValue is used to format - * the value representation. - * - * @param rowId - * the Id of the row (same as item Id). - * @param colId - * the Id of the column. - * @param property - * the Property to be presented. - * @return Object Either formatted value or Component for field. - * @see #setTableFieldFactory(TableFieldFactory) - */ - protected Object getPropertyValue(Object rowId, Object colId, - Property property) { - if (isEditable() && fieldFactory != null) { - final LegacyField<?> f = fieldFactory - .createField(getContainerDataSource(), rowId, colId, this); - if (f != null) { - // Remember that we have made this association so we can remove - // it when the component is removed - associatedProperties.put(f, property); - bindPropertyToField(rowId, colId, property, f); - return f; - } - } - - return formatPropertyValue(rowId, colId, property); - } - - /** - * Binds an item property to a field generated by TableFieldFactory. The - * default behavior is to bind property straight to LegacyField. If - * Property.Viewer type property (e.g. PropertyFormatter) is already set for - * field, the property is bound to that Property.Viewer. - * - * @param rowId - * @param colId - * @param property - * @param field - * @since 6.7.3 - */ - protected void bindPropertyToField(Object rowId, Object colId, - Property property, LegacyField field) { - // check if field has a property that is Viewer set. In that case we - // expect developer has e.g. PropertyFormatter that he wishes to use and - // assign the property to the Viewer instead. - boolean hasFilterProperty = field.getPropertyDataSource() != null - && (field.getPropertyDataSource() instanceof Property.Viewer); - if (hasFilterProperty) { - ((Property.Viewer) field.getPropertyDataSource()) - .setPropertyDataSource(property); - } else { - field.setPropertyDataSource(property); - } - } - - /** - * Formats table cell property values. By default the property.toString() - * and return a empty string for null properties. - * - * @param rowId - * the Id of the row (same as item Id). - * @param colId - * the Id of the column. - * @param property - * the Property to be formatted. - * @return the String representation of property and its value. - * @since 3.1 - */ - protected String formatPropertyValue(Object rowId, Object colId, - Property<?> property) { - if (property == null) { - return ""; - } - LegacyConverter<String, Object> converter = null; - - if (hasConverter(colId)) { - converter = getConverter(colId); - } else { - converter = (LegacyConverter) LegacyConverterUtil.getConverter( - String.class, property.getType(), getSession()); - } - Object value = property.getValue(); - if (converter != null) { - return converter.convertToPresentation(value, String.class, - getLocale()); - } - return (null != value) ? value.toString() : ""; - } - - /* Action container */ - - /** - * Registers a new action handler for this container - * - * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler) - */ - - @Override - public void addActionHandler(Action.Handler actionHandler) { - - if (actionHandler != null) { - - if (actionHandlers == null) { - actionHandlers = new LinkedList<Handler>(); - actionMapper = new KeyMapper<Action>(); - } - - if (!actionHandlers.contains(actionHandler)) { - actionHandlers.add(actionHandler); - // Assures the visual refresh. No need to reset the page buffer - // before as the content has not changed, only the action - // handlers. - refreshRenderedCells(); - } - - } - } - - /** - * Removes a previously registered action handler for the contents of this - * container. - * - * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler) - */ - - @Override - public void removeActionHandler(Action.Handler actionHandler) { - - if (actionHandlers != null && actionHandlers.contains(actionHandler)) { - - actionHandlers.remove(actionHandler); - - if (actionHandlers.isEmpty()) { - actionHandlers = null; - actionMapper = null; - } - - // Assures the visual refresh. No need to reset the page buffer - // before as the content has not changed, only the action - // handlers. - refreshRenderedCells(); - } - } - - /** - * Removes all action handlers - */ - public void removeAllActionHandlers() { - actionHandlers = null; - actionMapper = null; - // Assures the visual refresh. No need to reset the page buffer - // before as the content has not changed, only the action - // handlers. - refreshRenderedCells(); - } - - /* Property value change listening support */ - - /** - * Notifies this listener that the Property's value has changed. - * - * Also listens changes in rendered items to refresh content area. - * - * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent) - */ - - @Override - public void valueChange(Property.ValueChangeEvent event) { - if (equals(event.getProperty()) - || event.getProperty() == getPropertyDataSource()) { - super.valueChange(event); - } else { - refreshRowCache(); - containerChangeToBeRendered = true; - } - markAsDirty(); - } - - /** - * Clears the current page buffer. Call this before - * {@link #refreshRenderedCells()} to ensure that all content is updated - * from the properties. - */ - protected void resetPageBuffer() { - firstToBeRenderedInClient = -1; - lastToBeRenderedInClient = -1; - reqFirstRowToPaint = -1; - reqRowsToPaint = -1; - pageBuffer = null; - } - - /** - * Notifies the component that it is connected to an application. - * - * @see com.vaadin.ui.Component#attach() - */ - - @Override - public void attach() { - super.attach(); - - refreshRenderedCells(); - } - - /** - * Notifies the component that it is detached from the application - * - * @see com.vaadin.ui.Component#detach() - */ - - @Override - public void detach() { - super.detach(); - } - - /** - * Removes all Items from the Container. - * - * @see com.vaadin.data.Container#removeAllItems() - */ - - @Override - public boolean removeAllItems() { - currentPageFirstItemId = null; - currentPageFirstItemIndex = 0; - return super.removeAllItems(); - } - - /** - * Removes the Item identified by <code>ItemId</code> from the Container. - * - * @see com.vaadin.data.Container#removeItem(Object) - */ - - @Override - public boolean removeItem(Object itemId) { - final Object nextItemId = nextItemId(itemId); - final boolean ret = super.removeItem(itemId); - if (ret && (itemId != null) - && (itemId.equals(currentPageFirstItemId))) { - currentPageFirstItemId = nextItemId; - } - if (!(items instanceof Container.ItemSetChangeNotifier)) { - refreshRowCache(); - } - return ret; - } - - /** - * Removes a Property specified by the given Property ID from the Container. - * - * @see com.vaadin.data.Container#removeContainerProperty(Object) - */ - - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - - // If a visible property is removed, remove the corresponding column - visibleColumns.remove(propertyId); - columnAlignments.remove(propertyId); - columnIcons.remove(propertyId); - columnHeaders.remove(propertyId); - columnFooters.remove(propertyId); - // If a propertyValueConverter was defined for the property, remove it. - propertyValueConverters.remove(propertyId); - - return super.removeContainerProperty(propertyId); - } - - /** - * Adds a new property to the table and show it as a visible column. - * - * @param propertyId - * the Id of the property. - * @param type - * the class of the property. - * @param defaultValue - * the default value given for all existing items. - * @see com.vaadin.data.Container#addContainerProperty(Object, Class, - * Object) - */ - - @Override - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue) throws UnsupportedOperationException { - - boolean visibleColAdded = false; - if (!visibleColumns.contains(propertyId)) { - visibleColumns.add(propertyId); - visibleColAdded = true; - } - - if (!super.addContainerProperty(propertyId, type, defaultValue)) { - if (visibleColAdded) { - visibleColumns.remove(propertyId); - } - return false; - } - if (!(items instanceof Container.PropertySetChangeNotifier)) { - refreshRowCache(); - } - return true; - } - - /** - * Adds a new property to the table and show it as a visible column. - * - * @param propertyId - * the Id of the property - * @param type - * the class of the property - * @param defaultValue - * the default value given for all existing items - * @param columnHeader - * the Explicit header of the column. If explicit header is not - * needed, this should be set null. - * @param columnIcon - * the Icon of the column. If icon is not needed, this should be - * set null. - * @param columnAlignment - * the Alignment of the column. Null implies align left. - * @throws UnsupportedOperationException - * if the operation is not supported. - * @see com.vaadin.data.Container#addContainerProperty(Object, Class, - * Object) - */ - public boolean addContainerProperty(Object propertyId, Class<?> type, - Object defaultValue, String columnHeader, Resource columnIcon, - Align columnAlignment) throws UnsupportedOperationException { - if (!this.addContainerProperty(propertyId, type, defaultValue)) { - return false; - } - setColumnAlignment(propertyId, columnAlignment); - setColumnHeader(propertyId, columnHeader); - setColumnIcon(propertyId, columnIcon); - return true; - } - - /** - * Adds a generated column to the Table. - * <p> - * A generated column is a column that exists only in the Table, not as a - * property in the underlying Container. It shows up just as a regular - * column. - * </p> - * <p> - * A generated column will override a property with the same id, so that the - * generated column is shown instead of the column representing the - * property. Note that getContainerProperty() will still get the real - * property. - * </p> - * <p> - * Table will not listen to value change events from properties overridden - * by generated columns. If the content of your generated column depends on - * properties that are not directly visible in the table, attach value - * change listener to update the content on all depended properties. - * Otherwise your UI might not get updated as expected. - * </p> - * <p> - * Also note that getVisibleColumns() will return the generated columns, - * while getContainerPropertyIds() will not. - * </p> - * - * @param id - * the id of the column to be added - * @param generatedColumn - * the {@link ColumnGenerator} to use for this column - */ - public void addGeneratedColumn(Object id, ColumnGenerator generatedColumn) { - if (generatedColumn == null) { - throw new IllegalArgumentException( - "Can not add null as a GeneratedColumn"); - } - if (columnGenerators.containsKey(id)) { - throw new IllegalArgumentException( - "Can not add the same GeneratedColumn twice, id:" + id); - } else { - columnGenerators.put(id, generatedColumn); - /* - * add to visible column list unless already there (overriding - * column from DS) - */ - if (!visibleColumns.contains(id)) { - visibleColumns.add(id); - } - refreshRowCache(); - } - } - - /** - * Returns the ColumnGenerator used to generate the given column. - * - * @param columnId - * The id of the generated column - * @return The ColumnGenerator used for the given columnId or null. - */ - public ColumnGenerator getColumnGenerator(Object columnId) - throws IllegalArgumentException { - return columnGenerators.get(columnId); - } - - /** - * Removes a generated column previously added with addGeneratedColumn. - * - * @param columnId - * id of the generated column to remove - * @return true if the column could be removed (existed in the Table) - */ - public boolean removeGeneratedColumn(Object columnId) { - if (columnGenerators.containsKey(columnId)) { - columnGenerators.remove(columnId); - // remove column from visibleColumns list unless it exists in - // container (generator previously overrode this column) - if (!items.getContainerPropertyIds().contains(columnId)) { - visibleColumns.remove(columnId); - } - refreshRowCache(); - return true; - } else { - return false; - } - } - - /** - * Returns item identifiers of the items which are currently rendered on the - * client. - * <p> - * Note, that some due to historical reasons the name of the method is bit - * misleading. Some items may be partly or totally out of the viewport of - * the table's scrollable area. Actually detecting rows which can be - * actually seen by the end user may be problematic due to the client server - * architecture. Using {@link #getCurrentPageFirstItemId()} combined with - * {@link #getPageLength()} may produce good enough estimates in some - * situations. - * - * @see com.vaadin.ui.Select#getVisibleItemIds() - */ - - @Override - public Collection<?> getVisibleItemIds() { - - final LinkedList<Object> visible = new LinkedList<Object>(); - - final Object[][] cells = getVisibleCells(); - // may be null if the table has not been rendered yet (e.g. not attached - // to a layout) - if (null != cells) { - for (int i = 0; i < cells[CELL_ITEMID].length; i++) { - visible.add(cells[CELL_ITEMID][i]); - } - } - - return visible; - } - - /** - * Container datasource item set change. Table must flush its buffers on - * change. - * - * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent) - */ - - @Override - public void containerItemSetChange(Container.ItemSetChangeEvent event) { - if (isBeingPainted) { - return; - } - - super.containerItemSetChange(event); - - // super method clears the key map, must inform client about this to - // avoid getting invalid keys back (#8584) - keyMapperReset = true; - - int currentFirstItemIndex = getCurrentPageFirstItemIndex(); - - if (event.getContainer().size() == 0) { - repairOnReAddAllRowsDataScrollPositionItemIndex = getCurrentPageFirstItemIndex(); - } else { - if (repairOnReAddAllRowsDataScrollPositionItemIndex != -1) { - currentFirstItemIndex = repairOnReAddAllRowsDataScrollPositionItemIndex; - /* - * Reset repairOnReAddAllRowsDataScrollPositionItemIndex. - * - * Next string should be commented (removed) if we want to have - * possibility to restore scroll position during adding items to - * container one by one via add() but not only addAll(). The - * problem in this case: we cannot track what happened between - * add() and add()... So it is ambiguous where to stop restore - * scroll position. - */ - repairOnReAddAllRowsDataScrollPositionItemIndex = -1; - } - } - - // ensure that page still has first item in page, ignore buffer refresh - // (forced in this method) - setCurrentPageFirstItemIndex(currentFirstItemIndex, false); - refreshRowCache(); - } - - /** - * Container datasource property set change. Table must flush its buffers on - * change. - * - * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent) - */ - - @Override - public void containerPropertySetChange( - Container.PropertySetChangeEvent event) { - if (isBeingPainted) { - return; - } - - disableContentRefreshing(); - super.containerPropertySetChange(event); - - // sanitize visibleColumns. note that we are not adding previously - // non-existing properties as columns - Collection<?> containerPropertyIds = getContainerDataSource() - .getContainerPropertyIds(); - - LinkedList<Object> newVisibleColumns = new LinkedList<Object>( - visibleColumns); - for (Iterator<Object> iterator = newVisibleColumns.iterator(); iterator - .hasNext();) { - Object id = iterator.next(); - if (!(containerPropertyIds.contains(id) - || columnGenerators.containsKey(id))) { - iterator.remove(); - } - } - setVisibleColumns(newVisibleColumns.toArray()); - // same for collapsed columns - for (Iterator<Object> iterator = collapsedColumns.iterator(); iterator - .hasNext();) { - Object id = iterator.next(); - if (!(containerPropertyIds.contains(id) - || columnGenerators.containsKey(id))) { - iterator.remove(); - } - } - - resetPageBuffer(); - enableContentRefreshing(true); - } - - /** - * Adding new items is not supported. - * - * @throws UnsupportedOperationException - * if set to true. - * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean) - */ - - @Override - public void setNewItemsAllowed(boolean allowNewOptions) - throws UnsupportedOperationException { - if (allowNewOptions) { - throw new UnsupportedOperationException(); - } - } - - /** - * Gets the ID of the Item following the Item that corresponds to itemId. - * - * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) - */ - - @Override - public Object nextItemId(Object itemId) { - return ((Container.Ordered) items).nextItemId(itemId); - } - - /** - * Gets the ID of the Item preceding the Item that corresponds to the - * itemId. - * - * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) - */ - - @Override - public Object prevItemId(Object itemId) { - return ((Container.Ordered) items).prevItemId(itemId); - } - - /** - * Gets the ID of the first Item in the Container. - * - * @see com.vaadin.data.Container.Ordered#firstItemId() - */ - - @Override - public Object firstItemId() { - return ((Container.Ordered) items).firstItemId(); - } - - /** - * Gets the ID of the last Item in the Container. - * - * @see com.vaadin.data.Container.Ordered#lastItemId() - */ - - @Override - public Object lastItemId() { - return ((Container.Ordered) items).lastItemId(); - } - - /** - * Tests if the Item corresponding to the given Item ID is the first Item in - * the Container. - * - * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) - */ - - @Override - public boolean isFirstId(Object itemId) { - return ((Container.Ordered) items).isFirstId(itemId); - } - - /** - * Tests if the Item corresponding to the given Item ID is the last Item in - * the Container. - * - * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) - */ - - @Override - public boolean isLastId(Object itemId) { - return ((Container.Ordered) items).isLastId(itemId); - } - - /** - * Adds new item after the given item. - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) - */ - - @Override - public Object addItemAfter(Object previousItemId) - throws UnsupportedOperationException { - Object itemId = ((Container.Ordered) items) - .addItemAfter(previousItemId); - if (!(items instanceof Container.ItemSetChangeNotifier)) { - refreshRowCache(); - } - return itemId; - } - - /** - * Adds new item after the given item. - * - * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, - * java.lang.Object) - */ - - @Override - public Item addItemAfter(Object previousItemId, Object newItemId) - throws UnsupportedOperationException { - Item item = ((Container.Ordered) items).addItemAfter(previousItemId, - newItemId); - if (!(items instanceof Container.ItemSetChangeNotifier)) { - refreshRowCache(); - } - return item; - } - - /** - * Sets the TableFieldFactory that is used to create editor for table cells. - * - * The TableFieldFactory is only used if the Table is editable. By default - * the DefaultFieldFactory is used. - * - * @param fieldFactory - * the field factory to set. - * @see #isEditable - * @see DefaultFieldFactory - */ - public void setTableFieldFactory(TableFieldFactory fieldFactory) { - this.fieldFactory = fieldFactory; - - // Assure visual refresh - refreshRowCache(); - } - - /** - * Gets the TableFieldFactory that is used to create editor for table cells. - * - * The FieldFactory is only used if the Table is editable. - * - * @return TableFieldFactory used to create the LegacyField instances. - * @see #isEditable - */ - public TableFieldFactory getTableFieldFactory() { - return fieldFactory; - } - - /** - * Is table editable. - * - * If table is editable a editor of type LegacyField is created for each - * table cell. The assigned FieldFactory is used to create the instances. - * - * To provide custom editors for table cells create a class implementing the - * FieldFactory interface, and assign it to table, and set the editable - * property to true. - * - * @return true if table is editable, false otherwise. - * @see LegacyField - * @see FieldFactory - * - */ - public boolean isEditable() { - return editable; - } - - /** - * Sets the editable property. - * - * If table is editable a editor of type LegacyField is created for each - * table cell. The assigned FieldFactory is used to create the instances. - * - * To provide custom editors for table cells create a class implementing the - * FieldFactory interface, and assign it to table, and set the editable - * property to true. - * - * @param editable - * true if table should be editable by user. - * @see LegacyField - * @see FieldFactory - * - */ - public void setEditable(boolean editable) { - this.editable = editable; - - // Assure visual refresh - refreshRowCache(); - } - - /** - * Sorts the table. - * - * @throws UnsupportedOperationException - * if the container data source does not implement - * Container.Sortable - * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], - * boolean[]) - * - */ - - @Override - public void sort(Object[] propertyId, boolean[] ascending) - throws UnsupportedOperationException { - final Container c = getContainerDataSource(); - if (c instanceof Container.Sortable) { - final int pageIndex = getCurrentPageFirstItemIndex(); - boolean refreshingPreviouslyEnabled = disableContentRefreshing(); - ((Container.Sortable) c).sort(propertyId, ascending); - setCurrentPageFirstItemIndex(pageIndex); - if (refreshingPreviouslyEnabled) { - enableContentRefreshing(true); - } - if (propertyId.length > 0 && ascending.length > 0) { - // The first propertyId is the primary sorting criterion, - // therefore the sort indicator should be there - sortAscending = ascending[0]; - sortContainerPropertyId = propertyId[0]; - } else { - sortAscending = true; - sortContainerPropertyId = null; - } - } else if (c != null) { - throw new UnsupportedOperationException( - "Underlying Data does not allow sorting"); - } - } - - /** - * Sorts the table by currently selected sorting column. - * - * @throws UnsupportedOperationException - * if the container data source does not implement - * Container.Sortable - */ - public void sort() { - if (getSortContainerPropertyId() == null) { - return; - } - sort(new Object[] { sortContainerPropertyId }, - new boolean[] { sortAscending }); - } - - /** - * Gets the container property IDs, which can be used to sort the item. - * <p> - * Note that the {@link #isSortEnabled()} state affects what this method - * returns. Disabling sorting causes this method to always return an empty - * collection. - * </p> - * - * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() - */ - - @Override - public Collection<?> getSortableContainerPropertyIds() { - final Container c = getContainerDataSource(); - if (c instanceof Container.Sortable && isSortEnabled()) { - return ((Container.Sortable) c).getSortableContainerPropertyIds(); - } else { - return Collections.EMPTY_LIST; - } - } - - /** - * Gets the currently sorted column property ID. - * - * @return the Container property id of the currently sorted column. - */ - public Object getSortContainerPropertyId() { - return sortContainerPropertyId; - } - - /** - * Sets the currently sorted column property id. - * - * @param propertyId - * the Container property id of the currently sorted column. - */ - public void setSortContainerPropertyId(Object propertyId) { - setSortContainerPropertyId(propertyId, true); - } - - /** - * Internal method to set currently sorted column property id. With doSort - * flag actual sorting may be bypassed. - * - * @param propertyId - * @param doSort - */ - private void setSortContainerPropertyId(Object propertyId, boolean doSort) { - if ((sortContainerPropertyId != null - && !sortContainerPropertyId.equals(propertyId)) - || (sortContainerPropertyId == null && propertyId != null)) { - sortContainerPropertyId = propertyId; - - if (doSort) { - sort(); - // Assures the visual refresh. This should not be necessary as - // sort() calls refreshRowCache - refreshRenderedCells(); - } - } - } - - /** - * Is the table currently sorted in ascending order. - * - * @return <code>true</code> if ascending, <code>false</code> if descending. - */ - public boolean isSortAscending() { - return sortAscending; - } - - /** - * Sets the table in ascending order. - * - * @param ascending - * <code>true</code> if ascending, <code>false</code> if - * descending. - */ - public void setSortAscending(boolean ascending) { - setSortAscending(ascending, true); - } - - /** - * Internal method to set sort ascending. With doSort flag actual sort can - * be bypassed. - * - * @param ascending - * @param doSort - */ - private void setSortAscending(boolean ascending, boolean doSort) { - if (sortAscending != ascending) { - sortAscending = ascending; - if (doSort) { - sort(); - // Assures the visual refresh. This should not be necessary as - // sort() calls refreshRowCache - refreshRenderedCells(); - } - } - } - - /** - * Is sorting disabled altogether. - * - * True iff no sortable columns are given even in the case where data source - * would support this. - * - * @return True iff sorting is disabled. - * @deprecated As of 7.0, use {@link #isSortEnabled()} instead - */ - @Deprecated - public boolean isSortDisabled() { - return !isSortEnabled(); - } - - /** - * Checks if sorting is enabled. - * - * @return true if sorting by the user is allowed, false otherwise - */ - public boolean isSortEnabled() { - return sortEnabled; - } - - /** - * Disables the sorting by the user altogether. - * - * @param sortDisabled - * True iff sorting is disabled. - * @deprecated As of 7.0, use {@link #setSortEnabled(boolean)} instead - */ - @Deprecated - public void setSortDisabled(boolean sortDisabled) { - setSortEnabled(!sortDisabled); - } - - /** - * Enables or disables sorting. - * <p> - * Setting this to false disallows sorting by the user. It is still possible - * to call {@link #sort()}. - * </p> - * - * @param sortEnabled - * true to allow the user to sort the table, false to disallow it - */ - public void setSortEnabled(boolean sortEnabled) { - if (this.sortEnabled != sortEnabled) { - this.sortEnabled = sortEnabled; - markAsDirty(); - } - } - - /** - * Used to create "generated columns"; columns that exist only in the Table, - * not in the underlying Container. Implement this interface and pass it to - * Table.addGeneratedColumn along with an id for the column to be generated. - * - */ - public interface ColumnGenerator extends Serializable { - - /** - * Called by Table when a cell in a generated column needs to be - * generated. - * - * @param source - * the source Table - * @param itemId - * the itemId (aka rowId) for the of the cell to be generated - * @param columnId - * the id for the generated column (as specified in - * addGeneratedColumn) - * @return A {@link Component} that should be rendered in the cell or a - * {@link String} that should be displayed in the cell. Other - * return values are not supported. - */ - public abstract Object generateCell(Table source, Object itemId, - Object columnId); - } - - /** - * Set cell style generator for Table. - * - * @param cellStyleGenerator - * New cell style generator or null to remove generator. - */ - public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator) { - this.cellStyleGenerator = cellStyleGenerator; - // Assures the visual refresh. No need to reset the page buffer - // before as the content has not changed, only the style generators - refreshRenderedCells(); - - } - - /** - * Get the current cell style generator. - * - */ - public CellStyleGenerator getCellStyleGenerator() { - return cellStyleGenerator; - } - - /** - * Allow to define specific style on cells (and rows) contents. Implements - * this interface and pass it to Table.setCellStyleGenerator. Row styles are - * generated when porpertyId is null. The CSS class name that will be added - * to the cell content is <tt>v-table-cell-content-[style name]</tt>, and - * the row style will be <tt>v-table-row-[style name]</tt>. - */ - public interface CellStyleGenerator extends Serializable { - - /** - * Called by Table when a cell (and row) is painted. - * - * @param source - * the source Table - * @param itemId - * The itemId of the painted cell - * @param propertyId - * The propertyId of the cell, null when getting row style - * @return The style name to add to this cell or row. (the CSS class - * name will be v-table-cell-content-[style name], or - * v-table-row-[style name] for rows) - */ - public abstract String getStyle(Table source, Object itemId, - Object propertyId); - } - - @Override - public void addItemClickListener(ItemClickListener listener) { - addListener(TableConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, - listener, ItemClickEvent.ITEM_CLICK_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addItemClickListener(ItemClickListener)} - **/ - @Override - @Deprecated - public void addListener(ItemClickListener listener) { - addItemClickListener(listener); - } - - @Override - public void removeItemClickListener(ItemClickListener listener) { - removeListener(TableConstants.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, - listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeItemClickListener(ItemClickListener)} - **/ - @Override - @Deprecated - public void removeListener(ItemClickListener listener) { - removeItemClickListener(listener); - } - - // Identical to AbstractCompoenentContainer.setEnabled(); - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - if (getParent() != null && !getParent().isEnabled()) { - // some ancestor still disabled, don't update children - return; - } else { - markAsDirtyRecursive(); - } - } - - /** - * Sets the drag start mode of the Table. Drag start mode controls how Table - * behaves as a drag source. - * - * @param newDragMode - */ - public void setDragMode(TableDragMode newDragMode) { - dragMode = newDragMode; - markAsDirty(); - } - - /** - * @return the current start mode of the Table. Drag start mode controls how - * Table behaves as a drag source. - */ - public TableDragMode getDragMode() { - return dragMode; - } - - /** - * Concrete implementation of {@link DataBoundTransferable} for data - * transferred from a table. - * - * @see {@link DataBoundTransferable}. - * - * @since 6.3 - */ - public class TableTransferable extends DataBoundTransferable { - - protected TableTransferable(Map<String, Object> rawVariables) { - super(Table.this, rawVariables); - Object object = rawVariables.get("itemId"); - if (object != null) { - setData("itemId", itemIdMapper.get((String) object)); - } - object = rawVariables.get("propertyId"); - if (object != null) { - setData("propertyId", columnIdMap.get((String) object)); - } - } - - @Override - public Object getItemId() { - return getData("itemId"); - } - - @Override - public Object getPropertyId() { - return getData("propertyId"); - } - - @Override - public Table getSourceComponent() { - return (Table) super.getSourceComponent(); - } - - } - - @Override - public TableTransferable getTransferable(Map<String, Object> rawVariables) { - TableTransferable transferable = new TableTransferable(rawVariables); - return transferable; - } - - @Override - public DropHandler getDropHandler() { - return dropHandler; - } - - public void setDropHandler(DropHandler dropHandler) { - this.dropHandler = dropHandler; - } - - @Override - public AbstractSelectTargetDetails translateDropTargetDetails( - Map<String, Object> clientVariables) { - return new AbstractSelectTargetDetails(clientVariables); - } - - /** - * Sets the behavior of how the multi-select mode should behave when the - * table is both selectable and in multi-select mode. - * <p> - * Note, that on some clients the mode may not be respected. E.g. on touch - * based devices CTRL/SHIFT base selection method is invalid, so touch based - * browsers always use the {@link MultiSelectMode#SIMPLE}. - * - * @param mode - * The select mode of the table - */ - public void setMultiSelectMode(MultiSelectMode mode) { - multiSelectMode = mode; - markAsDirty(); - } - - /** - * Returns the select mode in which multi-select is used. - * - * @return The multi select mode - */ - public MultiSelectMode getMultiSelectMode() { - return multiSelectMode; - } - - /** - * Lazy loading accept criterion for Table. Accepted target rows are loaded - * from server once per drag and drop operation. Developer must override one - * method that decides on which rows the currently dragged data can be - * dropped. - * - * <p> - * Initially pretty much no data is sent to client. On first required - * criterion check (per drag request) the client side data structure is - * initialized from server and no subsequent requests requests are needed - * during that drag and drop operation. - */ - public static abstract class TableDropCriterion - extends ServerSideCriterion { - - private Table table; - - private Set<Object> allowedItemIds; - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.acceptcriteria.ServerSideCriterion#getIdentifier - * () - */ - - @Override - protected String getIdentifier() { - return TableDropCriterion.class.getCanonicalName(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.acceptcriteria.AcceptCriterion#accepts(com.vaadin - * .event.dd.DragAndDropEvent) - */ - @Override - @SuppressWarnings("unchecked") - public boolean accept(DragAndDropEvent dragEvent) { - AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent - .getTargetDetails(); - table = (Table) dragEvent.getTargetDetails().getTarget(); - Collection<?> visibleItemIds = table.getVisibleItemIds(); - allowedItemIds = getAllowedItemIds(dragEvent, table, - (Collection<Object>) visibleItemIds); - - return allowedItemIds.contains(dropTargetData.getItemIdOver()); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.event.dd.acceptcriteria.AcceptCriterion#paintResponse( - * com.vaadin.server.PaintTarget) - */ - - @Override - public void paintResponse(PaintTarget target) throws PaintException { - /* - * send allowed nodes to client so subsequent requests can be - * avoided - */ - Object[] array = allowedItemIds.toArray(); - for (int i = 0; i < array.length; i++) { - String key = table.itemIdMapper.key(array[i]); - array[i] = key; - } - target.addAttribute("allowedIds", array); - } - - /** - * @param dragEvent - * @param table - * the table for which the allowed item identifiers are - * defined - * @param visibleItemIds - * the list of currently rendered item identifiers, accepted - * item id's need to be detected only for these visible items - * @return the set of identifiers for items on which the dragEvent will - * be accepted - */ - protected abstract Set<Object> getAllowedItemIds( - DragAndDropEvent dragEvent, Table table, - Collection<Object> visibleItemIds); - - } - - /** - * Click event fired when clicking on the Table headers. The event includes - * a reference the the Table the event originated from, the property id of - * the column which header was pressed and details about the mouse event - * itself. - */ - public static class HeaderClickEvent extends ClickEvent { - public static final Method HEADER_CLICK_METHOD; - - static { - try { - // Set the header click method - HEADER_CLICK_METHOD = HeaderClickListener.class - .getDeclaredMethod("headerClick", - new Class[] { HeaderClickEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException(e); - } - } - - // The property id of the column which header was pressed - private final Object columnPropertyId; - - public HeaderClickEvent(Component source, Object propertyId, - MouseEventDetails details) { - super(source, details); - columnPropertyId = propertyId; - } - - /** - * Gets the property id of the column which header was pressed - * - * @return The column property id - */ - public Object getPropertyId() { - return columnPropertyId; - } - } - - /** - * Click event fired when clicking on the Table footers. The event includes - * a reference the the Table the event originated from, the property id of - * the column which header was pressed and details about the mouse event - * itself. - */ - public static class FooterClickEvent extends ClickEvent { - public static final Method FOOTER_CLICK_METHOD; - - static { - try { - // Set the header click method - FOOTER_CLICK_METHOD = FooterClickListener.class - .getDeclaredMethod("footerClick", - new Class[] { FooterClickEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException(e); - } - } - - // The property id of the column which header was pressed - private final Object columnPropertyId; - - /** - * Constructor - * - * @param source - * The source of the component - * @param propertyId - * The propertyId of the column - * @param details - * The mouse details of the click - */ - public FooterClickEvent(Component source, Object propertyId, - MouseEventDetails details) { - super(source, details); - columnPropertyId = propertyId; - } - - /** - * Gets the property id of the column which header was pressed - * - * @return The column property id - */ - public Object getPropertyId() { - return columnPropertyId; - } - } - - /** - * Interface for the listener for column header mouse click events. The - * headerClick method is called when the user presses a header column cell. - */ - public interface HeaderClickListener extends Serializable { - - /** - * Called when a user clicks a header column cell - * - * @param event - * The event which contains information about the column and - * the mouse click event - */ - public void headerClick(HeaderClickEvent event); - } - - /** - * Interface for the listener for column footer mouse click events. The - * footerClick method is called when the user presses a footer column cell. - */ - public interface FooterClickListener extends Serializable { - - /** - * Called when a user clicks a footer column cell - * - * @param event - * The event which contains information about the column and - * the mouse click event - */ - public void footerClick(FooterClickEvent event); - } - - /** - * Adds a header click listener which handles the click events when the user - * clicks on a column header cell in the Table. - * <p> - * The listener will receive events which contain information about which - * column was clicked and some details about the mouse event. - * </p> - * - * @param listener - * The handler which should handle the header click events. - */ - public void addHeaderClickListener(HeaderClickListener listener) { - addListener(TableConstants.HEADER_CLICK_EVENT_ID, - HeaderClickEvent.class, listener, - HeaderClickEvent.HEADER_CLICK_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addHeaderClickListener(HeaderClickListener)} - **/ - @Deprecated - public void addListener(HeaderClickListener listener) { - addHeaderClickListener(listener); - } - - /** - * Removes a header click listener - * - * @param listener - * The listener to remove. - */ - public void removeHeaderClickListener(HeaderClickListener listener) { - removeListener(TableConstants.HEADER_CLICK_EVENT_ID, - HeaderClickEvent.class, listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeHeaderClickListener(HeaderClickListener)} - **/ - @Deprecated - public void removeListener(HeaderClickListener listener) { - removeHeaderClickListener(listener); - } - - /** - * Adds a footer click listener which handles the click events when the user - * clicks on a column footer cell in the Table. - * <p> - * The listener will receive events which contain information about which - * column was clicked and some details about the mouse event. - * </p> - * - * @param listener - * The handler which should handle the footer click events. - */ - public void addFooterClickListener(FooterClickListener listener) { - addListener(TableConstants.FOOTER_CLICK_EVENT_ID, - FooterClickEvent.class, listener, - FooterClickEvent.FOOTER_CLICK_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addFooterClickListener(FooterClickListener)} - **/ - @Deprecated - public void addListener(FooterClickListener listener) { - addFooterClickListener(listener); - } - - /** - * Removes a footer click listener - * - * @param listener - * The listener to remove. - */ - public void removeFooterClickListener(FooterClickListener listener) { - removeListener(TableConstants.FOOTER_CLICK_EVENT_ID, - FooterClickEvent.class, listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeFooterClickListener(FooterClickListener)} - **/ - @Deprecated - public void removeListener(FooterClickListener listener) { - removeFooterClickListener(listener); - } - - /** - * Gets the footer caption beneath the rows - * - * @param propertyId - * The propertyId of the column * - * @return The caption of the footer or NULL if not set - */ - public String getColumnFooter(Object propertyId) { - return columnFooters.get(propertyId); - } - - /** - * Sets the column footer caption. The column footer caption is the text - * displayed beneath the column if footers have been set visible. - * - * @param propertyId - * The properyId of the column - * - * @param footer - * The caption of the footer - */ - public void setColumnFooter(Object propertyId, String footer) { - if (footer == null) { - columnFooters.remove(propertyId); - } else { - columnFooters.put(propertyId, footer); - } - - markAsDirty(); - } - - /** - * Sets the footer visible in the bottom of the table. - * <p> - * The footer can be used to add column related data like sums to the bottom - * of the Table using setColumnFooter(Object propertyId, String footer). - * </p> - * - * @param visible - * Should the footer be visible - */ - public void setFooterVisible(boolean visible) { - if (visible != columnFootersVisible) { - columnFootersVisible = visible; - markAsDirty(); - } - } - - /** - * Is the footer currently visible? - * - * @return Returns true if visible else false - */ - public boolean isFooterVisible() { - return columnFootersVisible; - } - - /** - * This event is fired when a column is resized. The event contains the - * columns property id which was fired, the previous width of the column and - * the width of the column after the resize. - */ - public static class ColumnResizeEvent extends Component.Event { - public static final Method COLUMN_RESIZE_METHOD; - - static { - try { - COLUMN_RESIZE_METHOD = ColumnResizeListener.class - .getDeclaredMethod("columnResize", - new Class[] { ColumnResizeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException(e); - } - } - - private final int previousWidth; - private final int currentWidth; - private final Object columnPropertyId; - - /** - * Constructor - * - * @param source - * The source of the event - * @param propertyId - * The columns property id - * @param previous - * The width in pixels of the column before the resize event - * @param current - * The width in pixels of the column after the resize event - */ - public ColumnResizeEvent(Component source, Object propertyId, - int previous, int current) { - super(source); - previousWidth = previous; - currentWidth = current; - columnPropertyId = propertyId; - } - - /** - * Get the column property id of the column that was resized. - * - * @return The column property id - */ - public Object getPropertyId() { - return columnPropertyId; - } - - /** - * Get the width in pixels of the column before the resize event - * - * @return Width in pixels - */ - public int getPreviousWidth() { - return previousWidth; - } - - /** - * Get the width in pixels of the column after the resize event - * - * @return Width in pixels - */ - public int getCurrentWidth() { - return currentWidth; - } - } - - /** - * Interface for listening to column resize events. - */ - public interface ColumnResizeListener extends Serializable { - - /** - * This method is triggered when the column has been resized - * - * @param event - * The event which contains the column property id, the - * previous width of the column and the current width of the - * column - */ - public void columnResize(ColumnResizeEvent event); - } - - /** - * Adds a column resize listener to the Table. A column resize listener is - * called when a user resizes a columns width. - * - * @param listener - * The listener to attach to the Table - */ - public void addColumnResizeListener(ColumnResizeListener listener) { - addListener(TableConstants.COLUMN_RESIZE_EVENT_ID, - ColumnResizeEvent.class, listener, - ColumnResizeEvent.COLUMN_RESIZE_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addColumnResizeListener(ColumnResizeListener)} - **/ - @Deprecated - public void addListener(ColumnResizeListener listener) { - addColumnResizeListener(listener); - } - - /** - * Removes a column resize listener from the Table. - * - * @param listener - * The listener to remove - */ - public void removeColumnResizeListener(ColumnResizeListener listener) { - removeListener(TableConstants.COLUMN_RESIZE_EVENT_ID, - ColumnResizeEvent.class, listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeColumnResizeListener(ColumnResizeListener)} - **/ - @Deprecated - public void removeListener(ColumnResizeListener listener) { - removeColumnResizeListener(listener); - } - - /** - * This event is fired when a columns are reordered by the end user user. - */ - public static class ColumnReorderEvent extends Component.Event { - public static final Method METHOD; - - static { - try { - METHOD = ColumnReorderListener.class.getDeclaredMethod( - "columnReorder", - new Class[] { ColumnReorderEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException(e); - } - } - - /** - * Constructor - * - * @param source - * The source of the event - */ - public ColumnReorderEvent(Component source) { - super(source); - } - - } - - /** - * Interface for listening to column reorder events. - */ - public interface ColumnReorderListener extends Serializable { - - /** - * This method is triggered when the column has been reordered - * - * @param event - */ - public void columnReorder(ColumnReorderEvent event); - } - - /** - * This event is fired when the collapse state of a column changes. - * - * @since 7.6 - */ - public static class ColumnCollapseEvent extends Component.Event { - - public static final Method METHOD = ReflectTools.findMethod( - ColumnCollapseListener.class, "columnCollapseStateChange", - ColumnCollapseEvent.class); - private Object propertyId; - - /** - * Constructor - * - * @param source - * The source of the event - * @param propertyId - * The id of the column - */ - public ColumnCollapseEvent(Component source, Object propertyId) { - super(source); - this.propertyId = propertyId; - } - - /** - * Gets the id of the column whose collapse state changed - * - * @return the property id of the column - */ - public Object getPropertyId() { - return propertyId; - } - } - - /** - * Interface for listening to column collapse events. - * - * @since 7.6 - */ - public interface ColumnCollapseListener extends Serializable { - - /** - * This method is triggered when the collapse state for a column has - * changed - * - * @param event - */ - public void columnCollapseStateChange(ColumnCollapseEvent event); - } - - /** - * Adds a column reorder listener to the Table. A column reorder listener is - * called when a user reorders columns. - * - * @param listener - * The listener to attach to the Table - */ - public void addColumnReorderListener(ColumnReorderListener listener) { - addListener(TableConstants.COLUMN_REORDER_EVENT_ID, - ColumnReorderEvent.class, listener, ColumnReorderEvent.METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addColumnReorderListener(ColumnReorderListener)} - **/ - @Deprecated - public void addListener(ColumnReorderListener listener) { - addColumnReorderListener(listener); - } - - /** - * Removes a column reorder listener from the Table. - * - * @param listener - * The listener to remove - */ - public void removeColumnReorderListener(ColumnReorderListener listener) { - removeListener(TableConstants.COLUMN_REORDER_EVENT_ID, - ColumnReorderEvent.class, listener); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeColumnReorderListener(ColumnReorderListener)} - **/ - @Deprecated - public void removeListener(ColumnReorderListener listener) { - removeColumnReorderListener(listener); - } - - /** - * Adds a column collapse listener to the Table. A column collapse listener - * is called when the collapsed state of a column changes. - * - * @since 7.6 - * - * @param listener - * The listener to attach - */ - public void addColumnCollapseListener(ColumnCollapseListener listener) { - addListener(TableConstants.COLUMN_COLLAPSE_EVENT_ID, - ColumnCollapseEvent.class, listener, - ColumnCollapseEvent.METHOD); - } - - /** - * Removes a column reorder listener from the Table. - * - * @since 7.6 - * @param listener - * The listener to remove - */ - public void removeColumnCollapseListener(ColumnCollapseListener listener) { - removeListener(TableConstants.COLUMN_COLLAPSE_EVENT_ID, - ColumnCollapseEvent.class, listener); - } - - /** - * Set the item description generator which generates tooltips for cells and - * rows in the Table - * - * @param generator - * The generator to use or null to disable - */ - public void setItemDescriptionGenerator( - ItemDescriptionGenerator generator) { - if (generator != itemDescriptionGenerator) { - itemDescriptionGenerator = generator; - // Assures the visual refresh. No need to reset the page buffer - // before as the content has not changed, only the descriptions - refreshRenderedCells(); - } - } - - /** - * Get the item description generator which generates tooltips for cells and - * rows in the Table. - */ - public ItemDescriptionGenerator getItemDescriptionGenerator() { - return itemDescriptionGenerator; - } - - /** - * Row generators can be used to replace certain items in a table with a - * generated string. The generator is called each time the table is - * rendered, which means that new strings can be generated each time. - * - * Row generators can be used for e.g. summary rows or grouping of items. - */ - public interface RowGenerator extends Serializable { - /** - * Called for every row that is painted in the Table. Returning a - * GeneratedRow object will cause the row to be painted based on the - * contents of the GeneratedRow. A generated row is by default styled - * similarly to a header or footer row. - * <p> - * The GeneratedRow data object contains the text that should be - * rendered in the row. The itemId in the container thus works only as a - * placeholder. - * <p> - * If GeneratedRow.setSpanColumns(true) is used, there will be one - * String spanning all columns (use setText("Spanning text")). Otherwise - * you can define one String per visible column. - * <p> - * If GeneratedRow.setRenderAsHtml(true) is used, the strings can - * contain HTML markup, otherwise all strings will be rendered as text - * (the default). - * <p> - * A "v-table-generated-row" CSS class is added to all generated rows. - * For custom styling of a generated row you can combine a RowGenerator - * with a CellStyleGenerator. - * <p> - * - * @param table - * The Table that is being painted - * @param itemId - * The itemId for the row - * @return A GeneratedRow describing how the row should be painted or - * null to paint the row with the contents from the container - */ - public GeneratedRow generateRow(Table table, Object itemId); - } - - public static class GeneratedRow implements Serializable { - private boolean htmlContentAllowed = false; - private boolean spanColumns = false; - private String[] text = null; - - /** - * Creates a new generated row. If only one string is passed in, columns - * are automatically spanned. - * - * @param text - */ - public GeneratedRow(String... text) { - setHtmlContentAllowed(false); - setSpanColumns(text == null || text.length == 1); - setText(text); - } - - /** - * Pass one String if spanColumns is used, one String for each visible - * column otherwise - */ - public void setText(String... text) { - if (text == null || (text.length == 1 && text[0] == null)) { - text = new String[] { "" }; - } - this.text = text; - } - - protected String[] getText() { - return text; - } - - protected Object getValue() { - return getText(); - } - - protected boolean isHtmlContentAllowed() { - return htmlContentAllowed; - } - - /** - * If set to true, all strings passed to {@link #setText(String...)} - * will be rendered as HTML. - * - * @param htmlContentAllowed - */ - public void setHtmlContentAllowed(boolean htmlContentAllowed) { - this.htmlContentAllowed = htmlContentAllowed; - } - - protected boolean isSpanColumns() { - return spanColumns; - } - - /** - * If set to true, only one string will be rendered, spanning the entire - * row. - * - * @param spanColumns - */ - public void setSpanColumns(boolean spanColumns) { - this.spanColumns = spanColumns; - } - } - - /** - * Assigns a row generator to the table. The row generator will be able to - * replace rows in the table when it is rendered. - * - * @param generator - * the new row generator - */ - public void setRowGenerator(RowGenerator generator) { - rowGenerator = generator; - refreshRowCache(); - } - - /** - * @return the current row generator - */ - public RowGenerator getRowGenerator() { - return rowGenerator; - } - - /** - * Sets a converter for a property id. - * <p> - * The converter is used to format the the data for the given property id - * before displaying it in the table. - * </p> - * - * @param propertyId - * The propertyId to format using the converter - * @param converter - * The converter to use for the property id - */ - public void setConverter(Object propertyId, - LegacyConverter<String, ?> converter) { - if (!getContainerPropertyIds().contains(propertyId)) { - throw new IllegalArgumentException( - "PropertyId " + propertyId + " must be in the container"); - } - - if (!typeIsCompatible(converter.getModelType(), getType(propertyId))) { - throw new IllegalArgumentException( - "Property type (" + getType(propertyId) - + ") must match converter source type (" - + converter.getModelType() + ")"); - } - propertyValueConverters.put(propertyId, - (LegacyConverter<String, Object>) converter); - refreshRowCache(); - } - - /** - * Checks if there is a converter set explicitly for the given property id. - * - * @param propertyId - * The propertyId to check - * @return true if a converter has been set for the property id, false - * otherwise - */ - protected boolean hasConverter(Object propertyId) { - return propertyValueConverters.containsKey(propertyId); - } - - /** - * Returns the converter used to format the given propertyId. - * - * @param propertyId - * The propertyId to check - * @return The converter used to format the propertyId or null if no - * converter has been set - */ - public LegacyConverter<String, Object> getConverter(Object propertyId) { - return propertyValueConverters.get(propertyId); - } - - @Override - public void setVisible(boolean visible) { - if (visible) { - // We need to ensure that the rows are sent to the client when the - // Table is made visible if it has been rendered as invisible. - setRowCacheInvalidated(true); - } - super.setVisible(visible); - } - - @Override - public Iterator<Component> iterator() { - if (visibleComponents == null) { - Collection<Component> empty = Collections.emptyList(); - return empty.iterator(); - } - return visibleComponents.iterator(); - } - - /** - * @deprecated As of 7.0, use {@link #iterator()} instead. - */ - @Deprecated - public Iterator<Component> getComponentIterator() { - return iterator(); - } - - @Override - public void readDesign(Element design, DesignContext context) { - super.readDesign(design, context); - - if (design.hasAttr("sortable")) { - setSortEnabled(DesignAttributeHandler.readAttribute("sortable", - design.attributes(), boolean.class)); - } - - readColumns(design); - readHeader(design); - readBody(design, context); - readFooter(design); - } - - private void readColumns(Element design) { - Element colgroup = design.select("> table > colgroup").first(); - - if (colgroup != null) { - int i = 0; - List<Object> pIds = new ArrayList<Object>(); - for (Element col : colgroup.children()) { - if (!col.tagName().equals("col")) { - throw new DesignException("invalid column"); - } - - String id = DesignAttributeHandler.readAttribute("property-id", - col.attributes(), "property-" + i++, String.class); - pIds.add(id); - - addContainerProperty(id, String.class, null); - - if (col.hasAttr("width")) { - setColumnWidth(id, DesignAttributeHandler.readAttribute( - "width", col.attributes(), Integer.class)); - } - if (col.hasAttr("center")) { - setColumnAlignment(id, Align.CENTER); - } else if (col.hasAttr("right")) { - setColumnAlignment(id, Align.RIGHT); - } - if (col.hasAttr("expand")) { - if (col.attr("expand").isEmpty()) { - setColumnExpandRatio(id, 1); - } else { - setColumnExpandRatio(id, - DesignAttributeHandler.readAttribute("expand", - col.attributes(), float.class)); - } - } - if (col.hasAttr("collapsible")) { - setColumnCollapsible(id, - DesignAttributeHandler.readAttribute("collapsible", - col.attributes(), boolean.class)); - } - if (col.hasAttr("collapsed")) { - setColumnCollapsed(id, DesignAttributeHandler.readAttribute( - "collapsed", col.attributes(), boolean.class)); - } - } - setVisibleColumns(pIds.toArray()); - } - } - - private void readFooter(Element design) { - readHeaderOrFooter(design, false); - } - - private void readHeader(Element design) { - readHeaderOrFooter(design, true); - } - - @Override - protected void readItems(Element design, DesignContext context) { - // Do nothing - header/footer and inline data must be handled after - // colgroup. - } - - private void readHeaderOrFooter(Element design, boolean header) { - String selector = header ? "> table > thead" : "> table > tfoot"; - Element elem = design.select(selector).first(); - if (elem != null) { - if (!header) { - setFooterVisible(true); - } - if (elem.children().size() != 1) { - throw new DesignException( - "Table header and footer should contain exactly one <tr> element"); - } - Element tr = elem.child(0); - Elements elems = tr.children(); - Collection<?> propertyIds = visibleColumns; - if (elems.size() != propertyIds.size()) { - throw new DesignException( - "Table header and footer should contain as many items as there" - + " are columns in the Table."); - } - Iterator<?> propertyIt = propertyIds.iterator(); - for (Element e : elems) { - String columnValue = DesignFormatter - .decodeFromTextNode(e.html()); - Object propertyId = propertyIt.next(); - if (header) { - setColumnHeader(propertyId, columnValue); - if (e.hasAttr("icon")) { - setColumnIcon(propertyId, - DesignAttributeHandler.readAttribute("icon", - e.attributes(), Resource.class)); - } - } else { - setColumnFooter(propertyId, columnValue); - } - } - } - } - - protected void readBody(Element design, DesignContext context) { - Element tbody = design.select("> table > tbody").first(); - if (tbody == null) { - return; - } - - Set<String> selected = new HashSet<String>(); - for (Element tr : tbody.children()) { - readItem(tr, selected, context); - } - } - - @Override - protected Object readItem(Element tr, Set<String> selected, - DesignContext context) { - Elements cells = tr.children(); - if (visibleColumns.size() != cells.size()) { - throw new DesignException( - "Wrong number of columns in a Table row. Expected " - + visibleColumns.size() + ", was " + cells.size() - + "."); - } - Object[] data = new String[cells.size()]; - for (int c = 0; c < cells.size(); ++c) { - data[c] = DesignFormatter.decodeFromTextNode(cells.get(c).html()); - } - - Object itemId = addItem(data, - tr.hasAttr("item-id") ? tr.attr("item-id") : null); - - if (itemId == null) { - throw new DesignException("Failed to add a Table row: " + data); - } - - return itemId; - } - - @Override - public void writeDesign(Element design, DesignContext context) { - Table def = context.getDefaultInstance(this); - - DesignAttributeHandler.writeAttribute("sortable", design.attributes(), - isSortEnabled(), def.isSortEnabled(), boolean.class); - - Element table = null; - boolean hasColumns = getVisibleColumns().length != 0; - if (hasColumns) { - table = design.appendElement("table"); - writeColumns(table, def); - writeHeader(table, def); - } - super.writeDesign(design, context); - if (hasColumns) { - writeFooter(table); - } - } - - private void writeColumns(Element table, Table def) { - Object[] columns = getVisibleColumns(); - if (columns.length == 0) { - return; - } - - Element colgroup = table.appendElement("colgroup"); - for (Object id : columns) { - Element col = colgroup.appendElement("col"); - - col.attr("property-id", id.toString()); - - if (getColumnAlignment(id) == Align.CENTER) { - col.attr("center", true); - } else if (getColumnAlignment(id) == Align.RIGHT) { - col.attr("right", true); - } - - DesignAttributeHandler.writeAttribute("width", col.attributes(), - getColumnWidth(id), def.getColumnWidth(null), int.class); - - DesignAttributeHandler.writeAttribute("expand", col.attributes(), - getColumnExpandRatio(id), def.getColumnExpandRatio(null), - float.class); - - DesignAttributeHandler.writeAttribute("collapsible", - col.attributes(), isColumnCollapsible(id), - def.isColumnCollapsible(null), boolean.class); - - DesignAttributeHandler.writeAttribute("collapsed", col.attributes(), - isColumnCollapsed(id), def.isColumnCollapsed(null), - boolean.class); - } - } - - private void writeHeader(Element table, Table def) { - Object[] columns = getVisibleColumns(); - if (columns.length == 0 - || (columnIcons.isEmpty() && columnHeaders.isEmpty())) { - return; - } - - Element header = table.appendElement("thead").appendElement("tr"); - for (Object id : columns) { - Element th = header.appendElement("th"); - th.html(getColumnHeader(id)); - DesignAttributeHandler.writeAttribute("icon", th.attributes(), - getColumnIcon(id), def.getColumnIcon(null), Resource.class); - } - - } - - private void writeFooter(Element table) { - Object[] columns = getVisibleColumns(); - if (columns.length == 0 || columnFooters.isEmpty()) { - return; - } - - Element footer = table.appendElement("tfoot").appendElement("tr"); - for (Object id : columns) { - footer.appendElement("td").text(getColumnFooter(id)); - } - } - - @Override - protected void writeItems(Element design, DesignContext context) { - if (getVisibleColumns().length == 0) { - return; - } - Element tbody = design.child(0).appendElement("tbody"); - super.writeItems(tbody, context); - } - - @Override - protected Element writeItem(Element tbody, Object itemId, - DesignContext context) { - Element tr = tbody.appendElement("tr"); - tr.attr("item-id", String.valueOf(itemId)); - Item item = getItem(itemId); - for (Object id : getVisibleColumns()) { - Element td = tr.appendElement("td"); - Object value = item.getItemProperty(id).getValue(); - td.html(value != null ? value.toString() : ""); - } - return tr; - } - - @Override - protected Collection<String> getCustomAttributes() { - Collection<String> result = super.getCustomAttributes(); - result.add("sortable"); - result.add("sort-enabled"); - result.add("sort-disabled"); - result.add("footer-visible"); - result.add("item-caption-mode"); - result.add("current-page-first-item-id"); - result.add("current-page-first-item-index"); - return result; - } - - /** - * ContextClickEvent for the Table Component. - * - * @since 7.6 - */ - public static class TableContextClickEvent extends ContextClickEvent { - - private final Object itemId; - private final Object propertyId; - private final Section section; - - public TableContextClickEvent(Table source, - MouseEventDetails mouseEventDetails, Object itemId, - Object propertyId, Section section) { - super(source, mouseEventDetails); - - this.itemId = itemId; - this.propertyId = propertyId; - this.section = section; - } - - /** - * Returns the item id of context clicked row. - * - * @return item id of clicked row; <code>null</code> if header, footer - * or empty area of Table - */ - public Object getItemId() { - return itemId; - } - - /** - * Returns the property id of context clicked column. - * - * @return property id; or <code>null</code> if we've clicked on the - * empty area of the Table - */ - public Object getPropertyId() { - return propertyId; - } - - /** - * Returns the clicked section of Table. - * - * @return section of Table - */ - public Section getSection() { - return section; - } - - @Override - public Table getComponent() { - return (Table) super.getComponent(); - } - } - - @Override - protected TableState getState() { - return getState(true); - } - - @Override - protected TableState getState(boolean markAsDirty) { - return (TableState) super.getState(markAsDirty); - } - - private final Logger getLogger() { - if (logger == null) { - logger = Logger.getLogger(Table.class.getName()); - } - return logger; - } - - @Override - public void setChildMeasurementHint(ChildMeasurementHint hint) { - if (hint == null) { - childMeasurementHint = ChildMeasurementHint.MEASURE_ALWAYS; - } else { - childMeasurementHint = hint; - } - } - - @Override - public ChildMeasurementHint getChildMeasurementHint() { - return childMeasurementHint; - } - - /** - * Sets whether only collapsible columns should be shown to the user in the - * column collapse menu. The default is - * {@link CollapseMenuContent#ALL_COLUMNS}. - * - * - * @since 7.6 - * @param content - * the desired collapsible menu content setting - */ - public void setCollapseMenuContent(CollapseMenuContent content) { - getState().collapseMenuContent = content; - } - - /** - * Checks whether only collapsible columns are shown to the user in the - * column collapse menu. The default is - * {@link CollapseMenuContent#ALL_COLUMNS} . - * - * @since 7.6 - * @return the current collapsible menu content setting - */ - public CollapseMenuContent getCollapseMenuContent() { - return getState(false).collapseMenuContent; - } -} diff --git a/server/src/main/java/com/vaadin/ui/TableFieldFactory.java b/server/src/main/java/com/vaadin/ui/TableFieldFactory.java deleted file mode 100644 index 54f8bc5110..0000000000 --- a/server/src/main/java/com/vaadin/ui/TableFieldFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.ui; - -import java.io.Serializable; - -import com.vaadin.data.Container; -import com.vaadin.v7.ui.LegacyField; - -/** - * Factory interface for creating new LegacyField-instances based on Container - * (datasource), item id, property id and uiContext (the component responsible - * for displaying fields). Currently this interface is used by {@link Table}, - * but might later be used by some other components for {@link LegacyField} - * generation. - * - * <p> - * - * @author Vaadin Ltd. - * @since 6.0 - * @see FormFieldFactory - */ -public interface TableFieldFactory extends Serializable { - /** - * Creates a field based on the Container, item id, property id and the - * component responsible for displaying the field (most commonly - * {@link Table}). - * - * @param container - * the Container where the property belongs to. - * @param itemId - * the item Id. - * @param propertyId - * the Id of the property. - * @param uiContext - * the component where the field is presented. - * @return A field suitable for editing the specified data or null if the - * property should not be editable. - */ - LegacyField<?> createField(Container container, Object itemId, - Object propertyId, Component uiContext); - -} diff --git a/server/src/main/java/com/vaadin/ui/TreeTable.java b/server/src/main/java/com/vaadin/ui/TreeTable.java deleted file mode 100644 index 2e69a0071d..0000000000 --- a/server/src/main/java/com/vaadin/ui/TreeTable.java +++ /dev/null @@ -1,985 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.jsoup.nodes.Element; - -import com.vaadin.data.Collapsible; -import com.vaadin.data.Container; -import com.vaadin.data.Container.Hierarchical; -import com.vaadin.data.Container.ItemSetChangeEvent; -import com.vaadin.data.util.ContainerHierarchicalWrapper; -import com.vaadin.data.util.HierarchicalContainer; -import com.vaadin.data.util.HierarchicalContainerOrderedWrapper; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; -import com.vaadin.server.Resource; -import com.vaadin.shared.ui.treetable.TreeTableConstants; -import com.vaadin.shared.ui.treetable.TreeTableState; -import com.vaadin.ui.Tree.CollapseEvent; -import com.vaadin.ui.Tree.CollapseListener; -import com.vaadin.ui.Tree.ExpandEvent; -import com.vaadin.ui.Tree.ExpandListener; -import com.vaadin.ui.declarative.DesignAttributeHandler; -import com.vaadin.ui.declarative.DesignContext; -import com.vaadin.ui.declarative.DesignException; - -/** - * TreeTable extends the {@link Table} component so that it can also visualize a - * hierarchy of its Items in a similar manner that {@link Tree} does. The tree - * hierarchy is always displayed in the first actual column of the TreeTable. - * <p> - * The TreeTable supports the usual {@link Table} features like lazy loading, so - * it should be no problem to display lots of items at once. Only required rows - * and some cache rows are sent to the client. - * <p> - * TreeTable supports standard {@link Hierarchical} container interfaces, but - * also a more fine tuned version - {@link Collapsible}. A container - * implementing the {@link Collapsible} interface stores the collapsed/expanded - * state internally and can this way scale better on the server side than with - * standard Hierarchical implementations. Developer must however note that - * {@link Collapsible} containers can not be shared among several users as they - * share UI state in the container. - */ -@SuppressWarnings({ "serial" }) -public class TreeTable extends Table implements Hierarchical { - - private interface ContainerStrategy extends Serializable { - public int size(); - - public boolean isNodeOpen(Object itemId); - - public int getDepth(Object itemId); - - public void toggleChildVisibility(Object itemId); - - public Object getIdByIndex(int index); - - public int indexOfId(Object id); - - public Object nextItemId(Object itemId); - - public Object lastItemId(); - - public Object prevItemId(Object itemId); - - public boolean isLastId(Object itemId); - - public Collection<?> getItemIds(); - - public void containerItemSetChange(ItemSetChangeEvent event); - } - - private abstract class AbstractStrategy implements ContainerStrategy { - - /** - * Consider adding getDepth to {@link Collapsible}, might help - * scalability with some container implementations. - */ - - @Override - public int getDepth(Object itemId) { - int depth = 0; - Hierarchical hierarchicalContainer = getContainerDataSource(); - while (!hierarchicalContainer.isRoot(itemId)) { - depth++; - itemId = hierarchicalContainer.getParent(itemId); - } - return depth; - } - - @Override - public void containerItemSetChange(ItemSetChangeEvent event) { - } - - } - - /** - * This strategy is used if current container implements {@link Collapsible} - * . - * - * open-collapsed logic diverted to container, otherwise use default - * implementations. - */ - private class CollapsibleStrategy extends AbstractStrategy { - - private Collapsible c() { - return (Collapsible) getContainerDataSource(); - } - - @Override - public void toggleChildVisibility(Object itemId) { - c().setCollapsed(itemId, !c().isCollapsed(itemId)); - } - - @Override - public boolean isNodeOpen(Object itemId) { - return !c().isCollapsed(itemId); - } - - @Override - public int size() { - return TreeTable.super.size(); - } - - @Override - public Object getIdByIndex(int index) { - return TreeTable.super.getIdByIndex(index); - } - - @Override - public int indexOfId(Object id) { - return TreeTable.super.indexOfId(id); - } - - @Override - public boolean isLastId(Object itemId) { - // using the default impl - return TreeTable.super.isLastId(itemId); - } - - @Override - public Object lastItemId() { - // using the default impl - return TreeTable.super.lastItemId(); - } - - @Override - public Object nextItemId(Object itemId) { - return TreeTable.super.nextItemId(itemId); - } - - @Override - public Object prevItemId(Object itemId) { - return TreeTable.super.prevItemId(itemId); - } - - @Override - public Collection<?> getItemIds() { - return TreeTable.super.getItemIds(); - } - - } - - /** - * Strategy for Hierarchical but not Collapsible container like - * {@link HierarchicalContainer}. - * - * Store collapsed/open states internally, fool Table to use preorder when - * accessing items from container via Ordered/Indexed methods. - */ - private class HierarchicalStrategy extends AbstractStrategy { - - private final HashSet<Object> openItems = new HashSet<Object>(); - - @Override - public boolean isNodeOpen(Object itemId) { - return openItems.contains(itemId); - } - - @Override - public int size() { - return getPreOrder().size(); - } - - @Override - public Collection<Object> getItemIds() { - return Collections.unmodifiableCollection(getPreOrder()); - } - - @Override - public boolean isLastId(Object itemId) { - if (itemId == null) { - return false; - } - - return itemId.equals(lastItemId()); - } - - @Override - public Object lastItemId() { - if (getPreOrder().size() > 0) { - return getPreOrder().get(getPreOrder().size() - 1); - } else { - return null; - } - } - - @Override - public Object nextItemId(Object itemId) { - int indexOf = getPreOrder().indexOf(itemId); - if (indexOf == -1) { - return null; - } - indexOf++; - if (indexOf == getPreOrder().size()) { - return null; - } else { - return getPreOrder().get(indexOf); - } - } - - @Override - public Object prevItemId(Object itemId) { - int indexOf = getPreOrder().indexOf(itemId); - indexOf--; - if (indexOf < 0) { - return null; - } else { - return getPreOrder().get(indexOf); - } - } - - @Override - public void toggleChildVisibility(Object itemId) { - boolean removed = openItems.remove(itemId); - if (!removed) { - openItems.add(itemId); - getLogger().log(Level.FINEST, "Item {0} is now expanded", - itemId); - } else { - getLogger().log(Level.FINEST, "Item {0} is now collapsed", - itemId); - } - clearPreorderCache(); - } - - private void clearPreorderCache() { - preOrder = null; // clear preorder cache - } - - List<Object> preOrder; - - /** - * Preorder of ids currently visible - * - * @return - */ - private List<Object> getPreOrder() { - if (preOrder == null) { - preOrder = new ArrayList<Object>(); - Collection<?> rootItemIds = getContainerDataSource() - .rootItemIds(); - for (Object id : rootItemIds) { - preOrder.add(id); - addVisibleChildTree(id); - } - } - return preOrder; - } - - private void addVisibleChildTree(Object id) { - if (isNodeOpen(id)) { - Collection<?> children = getContainerDataSource() - .getChildren(id); - if (children != null) { - for (Object childId : children) { - preOrder.add(childId); - addVisibleChildTree(childId); - } - } - } - - } - - @Override - public int indexOfId(Object id) { - return getPreOrder().indexOf(id); - } - - @Override - public Object getIdByIndex(int index) { - return getPreOrder().get(index); - } - - @Override - public void containerItemSetChange(ItemSetChangeEvent event) { - // preorder becomes invalid on sort, item additions etc. - clearPreorderCache(); - super.containerItemSetChange(event); - } - - } - - /** - * Creates an empty TreeTable with a default container. - */ - public TreeTable() { - super(null, new HierarchicalContainer()); - } - - /** - * Creates an empty TreeTable with a default container. - * - * @param caption - * the caption for the TreeTable - */ - public TreeTable(String caption) { - this(); - setCaption(caption); - } - - /** - * Creates a TreeTable instance with given captions and data source. - * - * @param caption - * the caption for the component - * @param dataSource - * the dataSource that is used to list items in the component - */ - public TreeTable(String caption, Container dataSource) { - super(caption, dataSource); - } - - private ContainerStrategy cStrategy; - private Object focusedRowId = null; - private Object hierarchyColumnId; - - /** - * The item id that was expanded or collapsed during this request. Reset at - * the end of paint and only used for determining if a partial or full paint - * should be done. - * - * Can safely be reset to null whenever a change occurs that would prevent a - * partial update from rendering the correct result, e.g. rows added or - * removed during an expand operation. - */ - private Object toggledItemId; - private boolean animationsEnabled; - private boolean clearFocusedRowPending; - - /** - * If the container does not send item set change events, always do a full - * repaint instead of a partial update when expanding/collapsing nodes. - */ - private boolean containerSupportsPartialUpdates; - - private ContainerStrategy getContainerStrategy() { - if (cStrategy == null) { - if (getContainerDataSource() instanceof Collapsible) { - cStrategy = new CollapsibleStrategy(); - } else { - cStrategy = new HierarchicalStrategy(); - } - } - return cStrategy; - } - - @Override - protected void paintRowAttributes(PaintTarget target, Object itemId) - throws PaintException { - super.paintRowAttributes(target, itemId); - target.addAttribute("depth", getContainerStrategy().getDepth(itemId)); - if (getContainerDataSource().areChildrenAllowed(itemId)) { - target.addAttribute("ca", true); - target.addAttribute("open", - getContainerStrategy().isNodeOpen(itemId)); - } - } - - @Override - protected void paintRowIcon(PaintTarget target, Object[][] cells, - int indexInRowbuffer) throws PaintException { - // always paint if present (in parent only if row headers visible) - if (getRowHeaderMode() == ROW_HEADER_MODE_HIDDEN) { - Resource itemIcon = getItemIcon( - cells[CELL_ITEMID][indexInRowbuffer]); - if (itemIcon != null) { - target.addAttribute("icon", itemIcon); - } - } else if (cells[CELL_ICON][indexInRowbuffer] != null) { - target.addAttribute("icon", - (Resource) cells[CELL_ICON][indexInRowbuffer]); - } - } - - @Override - protected boolean rowHeadersAreEnabled() { - if (getRowHeaderMode() == RowHeaderMode.ICON_ONLY) { - return false; - } - return super.rowHeadersAreEnabled(); - } - - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - super.changeVariables(source, variables); - - if (variables.containsKey("toggleCollapsed")) { - String object = (String) variables.get("toggleCollapsed"); - Object itemId = itemIdMapper.get(object); - toggledItemId = itemId; - toggleChildVisibility(itemId, false); - if (variables.containsKey("selectCollapsed")) { - // ensure collapsed is selected unless opened with selection - // head - if (isSelectable()) { - select(itemId); - } - } - } else if (variables.containsKey("focusParent")) { - String key = (String) variables.get("focusParent"); - Object refId = itemIdMapper.get(key); - Object itemId = getParent(refId); - focusParent(itemId); - } - } - - private void focusParent(Object itemId) { - boolean inView = false; - Object inPageId = getCurrentPageFirstItemId(); - for (int i = 0; inPageId != null && i < getPageLength(); i++) { - if (inPageId.equals(itemId)) { - inView = true; - break; - } - inPageId = nextItemId(inPageId); - i++; - } - if (!inView) { - setCurrentPageFirstItemId(itemId); - } - // Select the row if it is selectable. - if (isSelectable()) { - if (isMultiSelect()) { - setValue(Collections.singleton(itemId)); - } else { - setValue(itemId); - } - } - setFocusedRow(itemId); - } - - private void setFocusedRow(Object itemId) { - focusedRowId = itemId; - if (focusedRowId == null) { - // Must still inform the client that the focusParent request has - // been processed - clearFocusedRowPending = true; - } - markAsDirty(); - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - if (focusedRowId != null) { - target.addAttribute("focusedRow", itemIdMapper.key(focusedRowId)); - focusedRowId = null; - } else if (clearFocusedRowPending) { - // Must still inform the client that the focusParent request has - // been processed - target.addAttribute("clearFocusPending", true); - clearFocusedRowPending = false; - } - target.addAttribute("animate", animationsEnabled); - if (hierarchyColumnId != null) { - Object[] visibleColumns2 = getVisibleColumns(); - for (int i = 0; i < visibleColumns2.length; i++) { - Object object = visibleColumns2[i]; - if (hierarchyColumnId.equals(object)) { - target.addAttribute( - TreeTableConstants.ATTRIBUTE_HIERARCHY_COLUMN_INDEX, - i); - break; - } - } - } - super.paintContent(target); - toggledItemId = null; - } - - /* - * Override methods for partial row updates and additions when expanding / - * collapsing nodes. - */ - - @Override - protected boolean isPartialRowUpdate() { - return toggledItemId != null && containerSupportsPartialUpdates - && !isRowCacheInvalidated(); - } - - @Override - protected int getFirstAddedItemIndex() { - return indexOfId(toggledItemId) + 1; - } - - @Override - protected int getAddedRowCount() { - return countSubNodesRecursively(getContainerDataSource(), - toggledItemId); - } - - private int countSubNodesRecursively(Hierarchical hc, Object itemId) { - int count = 0; - // we need the number of children for toggledItemId no matter if its - // collapsed or expanded. Other items' children are only counted if the - // item is expanded. - if (getContainerStrategy().isNodeOpen(itemId) - || itemId == toggledItemId) { - Collection<?> children = hc.getChildren(itemId); - if (children != null) { - count += children != null ? children.size() : 0; - for (Object id : children) { - count += countSubNodesRecursively(hc, id); - } - } - } - return count; - } - - @Override - protected int getFirstUpdatedItemIndex() { - return indexOfId(toggledItemId); - } - - @Override - protected int getUpdatedRowCount() { - return 1; - } - - @Override - protected boolean shouldHideAddedRows() { - return !getContainerStrategy().isNodeOpen(toggledItemId); - } - - private void toggleChildVisibility(Object itemId, - boolean forceFullRefresh) { - getContainerStrategy().toggleChildVisibility(itemId); - // ensure that page still has first item in page, DON'T clear the - // caches. - setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false); - - if (isCollapsed(itemId)) { - fireCollapseEvent(itemId); - } else { - fireExpandEvent(itemId); - } - - if (containerSupportsPartialUpdates && !forceFullRefresh) { - markAsDirty(); - } else { - // For containers that do not send item set change events, always do - // full repaint instead of partial row update. - refreshRowCache(); - } - } - - @Override - public int size() { - return getContainerStrategy().size(); - } - - @Override - public Hierarchical getContainerDataSource() { - return (Hierarchical) super.getContainerDataSource(); - } - - @Override - public void setContainerDataSource(Container newDataSource) { - cStrategy = null; - - // FIXME: This disables partial updates until TreeTable is fixed so it - // does not change component hierarchy during paint - containerSupportsPartialUpdates = (newDataSource instanceof ItemSetChangeNotifier) - && false; - - if (newDataSource != null && !(newDataSource instanceof Hierarchical)) { - newDataSource = new ContainerHierarchicalWrapper(newDataSource); - } - - if (newDataSource != null && !(newDataSource instanceof Ordered)) { - newDataSource = new HierarchicalContainerOrderedWrapper( - (Hierarchical) newDataSource); - } - - super.setContainerDataSource(newDataSource); - } - - @Override - public void containerItemSetChange( - com.vaadin.data.Container.ItemSetChangeEvent event) { - // Can't do partial repaints if items are added or removed during the - // expand/collapse request - toggledItemId = null; - getContainerStrategy().containerItemSetChange(event); - super.containerItemSetChange(event); - } - - @Override - protected Object getIdByIndex(int index) { - return getContainerStrategy().getIdByIndex(index); - } - - @Override - protected int indexOfId(Object itemId) { - return getContainerStrategy().indexOfId(itemId); - } - - @Override - public Object nextItemId(Object itemId) { - return getContainerStrategy().nextItemId(itemId); - } - - @Override - public Object lastItemId() { - return getContainerStrategy().lastItemId(); - } - - @Override - public Object prevItemId(Object itemId) { - return getContainerStrategy().prevItemId(itemId); - } - - @Override - public boolean isLastId(Object itemId) { - return getContainerStrategy().isLastId(itemId); - } - - @Override - public Collection<?> getItemIds() { - return getContainerStrategy().getItemIds(); - } - - @Override - public boolean areChildrenAllowed(Object itemId) { - return getContainerDataSource().areChildrenAllowed(itemId); - } - - @Override - public Collection<?> getChildren(Object itemId) { - return getContainerDataSource().getChildren(itemId); - } - - @Override - public Object getParent(Object itemId) { - return getContainerDataSource().getParent(itemId); - } - - @Override - public boolean hasChildren(Object itemId) { - return getContainerDataSource().hasChildren(itemId); - } - - @Override - public boolean isRoot(Object itemId) { - return getContainerDataSource().isRoot(itemId); - } - - @Override - public Collection<?> rootItemIds() { - return getContainerDataSource().rootItemIds(); - } - - @Override - public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) - throws UnsupportedOperationException { - return getContainerDataSource().setChildrenAllowed(itemId, - areChildrenAllowed); - } - - @Override - public boolean setParent(Object itemId, Object newParentId) - throws UnsupportedOperationException { - return getContainerDataSource().setParent(itemId, newParentId); - } - - /** - * Sets the Item specified by given identifier as collapsed or expanded. If - * the Item is collapsed, its children are not displayed to the user. - * - * @param itemId - * the identifier of the Item - * @param collapsed - * true if the Item should be collapsed, false if expanded - */ - public void setCollapsed(Object itemId, boolean collapsed) { - if (isCollapsed(itemId) != collapsed) { - if (null == toggledItemId && !isRowCacheInvalidated() - && getVisibleItemIds().contains(itemId)) { - // optimization: partial refresh if only one item is - // collapsed/expanded - toggledItemId = itemId; - toggleChildVisibility(itemId, false); - } else { - // make sure a full refresh takes place - otherwise neither - // partial nor full repaint of table content is performed - toggledItemId = null; - toggleChildVisibility(itemId, true); - } - } - } - - /** - * Checks if Item with given identifier is collapsed in the UI. - * - * <p> - * - * @param itemId - * the identifier of the checked Item - * @return true if the Item with given id is collapsed - * @see Collapsible#isCollapsed(Object) - */ - public boolean isCollapsed(Object itemId) { - return !getContainerStrategy().isNodeOpen(itemId); - } - - /** - * Explicitly sets the column in which the TreeTable visualizes the - * hierarchy. If hierarchyColumnId is not set, the hierarchy is visualized - * in the first visible column. - * - * @param hierarchyColumnId - */ - public void setHierarchyColumn(Object hierarchyColumnId) { - this.hierarchyColumnId = hierarchyColumnId; - } - - /** - * @return the identifier of column into which the hierarchy will be - * visualized or null if the column is not explicitly defined. - */ - public Object getHierarchyColumnId() { - return hierarchyColumnId; - } - - /** - * Adds an expand listener. - * - * @param listener - * the Listener to be added. - */ - public void addExpandListener(ExpandListener listener) { - addListener(ExpandEvent.class, listener, ExpandListener.EXPAND_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addExpandListener(ExpandListener)} - **/ - @Deprecated - public void addListener(ExpandListener listener) { - addExpandListener(listener); - } - - /** - * Removes an expand listener. - * - * @param listener - * the Listener to be removed. - */ - public void removeExpandListener(ExpandListener listener) { - removeListener(ExpandEvent.class, listener, - ExpandListener.EXPAND_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeExpandListener(ExpandListener)} - **/ - @Deprecated - public void removeListener(ExpandListener listener) { - removeExpandListener(listener); - } - - /** - * Emits an expand event. - * - * @param itemId - * the item id. - */ - protected void fireExpandEvent(Object itemId) { - fireEvent(new ExpandEvent(this, itemId)); - } - - /** - * Adds a collapse listener. - * - * @param listener - * the Listener to be added. - */ - public void addCollapseListener(CollapseListener listener) { - addListener(CollapseEvent.class, listener, - CollapseListener.COLLAPSE_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #addCollapseListener(CollapseListener)} - **/ - @Deprecated - public void addListener(CollapseListener listener) { - addCollapseListener(listener); - } - - /** - * Removes a collapse listener. - * - * @param listener - * the Listener to be removed. - */ - public void removeCollapseListener(CollapseListener listener) { - removeListener(CollapseEvent.class, listener, - CollapseListener.COLLAPSE_METHOD); - } - - /** - * @deprecated As of 7.0, replaced by - * {@link #removeCollapseListener(CollapseListener)} - **/ - @Deprecated - public void removeListener(CollapseListener listener) { - removeCollapseListener(listener); - } - - /** - * Emits a collapse event. - * - * @param itemId - * the item id. - */ - protected void fireCollapseEvent(Object itemId) { - fireEvent(new CollapseEvent(this, itemId)); - } - - /** - * @return true if animations are enabled - */ - public boolean isAnimationsEnabled() { - return animationsEnabled; - } - - /** - * Animations can be enabled by passing true to this method. Currently - * expanding rows slide in from the top and collapsing rows slide out the - * same way. NOTE! not supported in Internet Explorer 6 or 7. - * - * @param animationsEnabled - * true or false whether to enable animations or not. - */ - public void setAnimationsEnabled(boolean animationsEnabled) { - this.animationsEnabled = animationsEnabled; - markAsDirty(); - } - - private static final Logger getLogger() { - return Logger.getLogger(TreeTable.class.getName()); - } - - @Override - protected List<Object> getItemIds(int firstIndex, int rows) { - List<Object> itemIds = new ArrayList<Object>(); - for (int i = firstIndex; i < firstIndex + rows; i++) { - itemIds.add(getIdByIndex(i)); - } - return itemIds; - } - - @Override - protected void readBody(Element design, DesignContext context) { - Element tbody = design.select("> table > tbody").first(); - if (tbody == null) { - return; - } - - Set<String> selected = new HashSet<String>(); - Stack<Object> parents = new Stack<Object>(); - int lastDepth = -1; - - for (Element tr : tbody.children()) { - int depth = DesignAttributeHandler.readAttribute("depth", - tr.attributes(), 0, int.class); - - if (depth < 0 || depth > lastDepth + 1) { - throw new DesignException( - "Malformed TreeTable item hierarchy at " + tr - + ": last depth was " + lastDepth); - } else if (depth <= lastDepth) { - for (int d = depth; d <= lastDepth; d++) { - parents.pop(); - } - } - - Object itemId = readItem(tr, selected, context); - setParent(itemId, !parents.isEmpty() ? parents.peek() : null); - parents.push(itemId); - lastDepth = depth; - } - } - - @Override - protected Object readItem(Element tr, Set<String> selected, - DesignContext context) { - Object itemId = super.readItem(tr, selected, context); - - if (tr.hasAttr("collapsed")) { - boolean collapsed = DesignAttributeHandler - .readAttribute("collapsed", tr.attributes(), boolean.class); - setCollapsed(itemId, collapsed); - } - - return itemId; - } - - @Override - protected void writeItems(Element design, DesignContext context) { - if (getVisibleColumns().length == 0) { - return; - } - Element tbody = design.child(0).appendElement("tbody"); - writeItems(tbody, rootItemIds(), 0, context); - } - - protected void writeItems(Element tbody, Collection<?> itemIds, int depth, - DesignContext context) { - for (Object itemId : itemIds) { - Element tr = writeItem(tbody, itemId, context); - DesignAttributeHandler.writeAttribute("depth", tr.attributes(), - depth, 0, int.class); - - if (getChildren(itemId) != null) { - writeItems(tbody, getChildren(itemId), depth + 1, context); - } - } - } - - @Override - protected Element writeItem(Element tbody, Object itemId, - DesignContext context) { - Element tr = super.writeItem(tbody, itemId, context); - DesignAttributeHandler.writeAttribute("collapsed", tr.attributes(), - isCollapsed(itemId), true, boolean.class); - return tr; - } - - @Override - protected TreeTableState getState() { - return (TreeTableState) super.getState(); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java deleted file mode 100644 index 9c3f6c0eaa..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/AllTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -import com.vaadin.data.util.sqlcontainer.connection.J2EEConnectionPoolTest; -import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPoolTest; -import com.vaadin.data.util.sqlcontainer.filters.BetweenTest; -import com.vaadin.data.util.sqlcontainer.filters.LikeTest; -import com.vaadin.data.util.sqlcontainer.generator.SQLGeneratorsTest; -import com.vaadin.data.util.sqlcontainer.query.FreeformQueryTest; -import com.vaadin.data.util.sqlcontainer.query.QueryBuilderTest; -import com.vaadin.data.util.sqlcontainer.query.TableQueryTest; - -@RunWith(Suite.class) -@SuiteClasses({ SimpleJDBCConnectionPoolTest.class, - J2EEConnectionPoolTest.class, LikeTest.class, QueryBuilderTest.class, - FreeformQueryTest.class, RowIdTest.class, SQLContainerTest.class, - SQLContainerTableQueryTest.class, ColumnPropertyTest.class, - TableQueryTest.class, SQLGeneratorsTest.class, UtilTest.class, - TicketTest.class, BetweenTest.class, ReadOnlyRowIdTest.class }) -public class AllTests { -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java deleted file mode 100644 index edc56035e1..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java +++ /dev/null @@ -1,318 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Property.ReadOnlyException; -import com.vaadin.data.util.sqlcontainer.ColumnProperty.NotNullableException; -import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; - -public class ColumnPropertyTest { - - @Test - public void constructor_legalParameters_shouldSucceed() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - Assert.assertNotNull(cp); - } - - @Test(expected = IllegalArgumentException.class) - public void constructor_missingPropertyId_shouldFail() { - new ColumnProperty(null, false, true, true, false, "Ville", - String.class); - } - - @Test(expected = IllegalArgumentException.class) - public void constructor_missingType_shouldFail() { - new ColumnProperty("NAME", false, true, true, false, "Ville", null); - } - - @Test - public void getValue_defaultValue_returnsVille() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - Assert.assertEquals("Ville", cp.getValue()); - } - - @Test - public void setValue_readWriteNullable_returnsKalle() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - container.itemChangeNotification(owner); - EasyMock.replay(container); - cp.setValue("Kalle"); - Assert.assertEquals("Kalle", cp.getValue()); - EasyMock.verify(container); - } - - @Test(expected = ReadOnlyException.class) - public void setValue_readOnlyNullable_shouldFail() { - ColumnProperty cp = new ColumnProperty("NAME", true, true, true, false, - "Ville", String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - EasyMock.replay(container); - cp.setValue("Kalle"); - EasyMock.verify(container); - } - - @Test - public void setValue_readWriteNullable_nullShouldWork() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - container.itemChangeNotification(owner); - EasyMock.replay(container); - cp.setValue(null); - Assert.assertNull(cp.getValue()); - EasyMock.verify(container); - } - - @Test(expected = NotNullableException.class) - public void setValue_readWriteNotNullable_nullShouldFail() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, false, - false, "Ville", String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - container.itemChangeNotification(owner); - EasyMock.replay(container); - cp.setValue(null); - Assert.assertNotNull(cp.getValue()); - EasyMock.verify(container); - } - - @Test - public void getType_normal_returnsStringClass() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - Assert.assertSame(String.class, cp.getType()); - } - - @Test - public void isReadOnly_readWriteNullable_returnsTrue() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - Assert.assertFalse(cp.isReadOnly()); - } - - @Test - public void isReadOnly_readOnlyNullable_returnsTrue() { - ColumnProperty cp = new ColumnProperty("NAME", true, true, true, false, - "Ville", String.class); - Assert.assertTrue(cp.isReadOnly()); - } - - @Test - public void setReadOnly_readOnlyChangeAllowed_shouldSucceed() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - cp.setReadOnly(true); - Assert.assertTrue(cp.isReadOnly()); - } - - @Test - public void setReadOnly_readOnlyChangeDisallowed_shouldFail() { - ColumnProperty cp = new ColumnProperty("NAME", false, false, true, - false, "Ville", String.class); - cp.setReadOnly(true); - Assert.assertFalse(cp.isReadOnly()); - } - - @Test - public void getPropertyId_normal_returnsNAME() { - ColumnProperty cp = new ColumnProperty("NAME", false, false, true, - false, "Ville", String.class); - Assert.assertEquals("NAME", cp.getPropertyId()); - } - - @Test - public void isModified_valueModified_returnsTrue() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "Ville", String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - container.itemChangeNotification(owner); - EasyMock.replay(container); - cp.setValue("Kalle"); - Assert.assertEquals("Kalle", cp.getValue()); - Assert.assertTrue(cp.isModified()); - EasyMock.verify(container); - } - - @Test - public void isModified_valueNotModified_returnsFalse() { - ColumnProperty cp = new ColumnProperty("NAME", false, false, true, - false, "Ville", String.class); - Assert.assertFalse(cp.isModified()); - } - - @Test - public void setValue_nullOnNullable_shouldWork() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - "asdf", String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - cp.setValue(null); - Assert.assertNull(cp.getValue()); - } - - @Test - public void setValue_resetTonullOnNullable_shouldWork() { - ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false, - null, String.class); - SQLContainer container = EasyMock.createMock(SQLContainer.class); - new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(cp)); - cp.setValue("asdf"); - Assert.assertEquals("asdf", cp.getValue()); - cp.setValue(null); - Assert.assertNull(cp.getValue()); - } - - @Test - public void setValue_sendsItemChangeNotification() throws SQLException { - - class TestContainer extends SQLContainer { - Object value = null; - boolean modified = false; - - public TestContainer(QueryDelegate delegate) throws SQLException { - super(delegate); - } - - @Override - public void itemChangeNotification(RowItem changedItem) { - ColumnProperty cp = (ColumnProperty) changedItem - .getItemProperty("NAME"); - value = cp.getValue(); - modified = cp.isModified(); - } - } - - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - false, "Ville", String.class); - - Statement statement = EasyMock.createNiceMock(Statement.class); - EasyMock.replay(statement); - - ResultSetMetaData metadata = EasyMock - .createNiceMock(ResultSetMetaData.class); - EasyMock.replay(metadata); - - ResultSet resultSet = EasyMock.createNiceMock(ResultSet.class); - EasyMock.expect(resultSet.getStatement()).andReturn(statement); - EasyMock.expect(resultSet.getMetaData()).andReturn(metadata); - EasyMock.replay(resultSet); - - QueryDelegate delegate = EasyMock.createNiceMock(QueryDelegate.class); - EasyMock.expect(delegate.getResults(0, 1)).andReturn(resultSet); - EasyMock.replay(delegate); - - TestContainer container = new TestContainer(delegate); - - new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(property)); - - property.setValue("Kalle"); - Assert.assertEquals("Kalle", container.value); - Assert.assertTrue(container.modified); - } - - @Test - public void versionColumnsShouldNotBeInValueMap_shouldReturnFalse() { - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - false, "Ville", String.class); - property.setVersionColumn(true); - - Assert.assertFalse(property.isPersistent()); - } - - @Test - public void neverWritableColumnsShouldNotBeInValueMap_shouldReturnFalse() { - ColumnProperty property = new ColumnProperty("NAME", true, false, true, - false, "Ville", String.class); - - Assert.assertFalse(property.isPersistent()); - } - - @Test - public void writableColumnsShouldBeInValueMap_shouldReturnTrue() { - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - false, "Ville", String.class); - - Assert.assertTrue(property.isPersistent()); - } - - @Test - public void writableButReadOnlyColumnsShouldNotBeInValueMap_shouldReturnFalse() { - ColumnProperty property = new ColumnProperty("NAME", true, true, true, - false, "Ville", String.class); - - Assert.assertFalse(property.isPersistent()); - } - - @Test - public void primKeysShouldBeRowIdentifiers_shouldReturnTrue() { - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - true, "Ville", String.class); - - Assert.assertTrue(property.isRowIdentifier()); - } - - @Test - public void versionColumnsShouldBeRowIdentifiers_shouldReturnTrue() { - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - false, "Ville", String.class); - property.setVersionColumn(true); - - Assert.assertTrue(property.isRowIdentifier()); - } - - @Test - public void nonPrimKeyOrVersionColumnsShouldBeNotRowIdentifiers_shouldReturnFalse() { - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - false, "Ville", String.class); - - Assert.assertFalse(property.isRowIdentifier()); - } - - @Test - public void getOldValueShouldReturnPreviousValue_shouldReturnVille() { - ColumnProperty property = new ColumnProperty("NAME", false, true, true, - false, "Ville", String.class); - - // Here we really don't care about the container management, but in - // order to set the value for a column the owner (RowItem) must be set - // and to create the owner we must have a container... - ArrayList<ColumnProperty> properties = new ArrayList<ColumnProperty>(); - properties.add(property); - - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - RowItem rowItem = new RowItem(container, new RowId(new Object[] { 1 }), - Arrays.asList(property)); - - property.setValue("Kalle"); - // Just check that the new value was actually set... - Assert.assertEquals("Kalle", property.getValue()); - // Assert that old value is the original value... - Assert.assertEquals("Ville", property.getOldValue()); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java deleted file mode 100644 index 8ce298c065..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/DataGenerator.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; - -public class DataGenerator { - - public static void addPeopleToDatabase(JDBCConnectionPool connectionPool) - throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - try { - statement.execute("drop table PEOPLE"); - if (SQLTestsConstants.db == DB.ORACLE) { - statement.execute("drop sequence people_seq"); - } - } catch (SQLException e) { - // Will fail if table doesn't exist, which is OK. - conn.rollback(); - } - statement.execute(SQLTestsConstants.peopleFirst); - if (SQLTestsConstants.peopleSecond != null) { - statement.execute(SQLTestsConstants.peopleSecond); - } - if (SQLTestsConstants.db == DB.ORACLE) { - statement.execute(SQLTestsConstants.peopleThird); - } - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate("insert into people values('Ville', '23')"); - statement.executeUpdate("insert into people values('Kalle', '7')"); - statement.executeUpdate("insert into people values('Pelle', '18')"); - statement.executeUpdate("insert into people values('Börje', '64')"); - } else { - statement.executeUpdate( - "insert into people values(default, 'Ville', '23')"); - statement.executeUpdate( - "insert into people values(default, 'Kalle', '7')"); - statement.executeUpdate( - "insert into people values(default, 'Pelle', '18')"); - statement.executeUpdate( - "insert into people values(default, 'Börje', '64')"); - } - statement.close(); - statement = conn.createStatement(); - ResultSet rs = statement.executeQuery("select * from PEOPLE"); - Assert.assertTrue(rs.next()); - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - } - - public static void addFiveThousandPeople(JDBCConnectionPool connectionPool) - throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - for (int i = 4; i < 5000; i++) { - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate("insert into people values('Person " + i - + "', '" + i % 99 + "')"); - } else { - statement.executeUpdate( - "insert into people values(default, 'Person " + i - + "', '" + i % 99 + "')"); - } - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - } - - public static void addVersionedData(JDBCConnectionPool connectionPool) - throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - try { - statement.execute("DROP TABLE VERSIONED"); - if (SQLTestsConstants.db == DB.ORACLE) { - statement.execute("drop sequence versioned_seq"); - statement.execute("drop sequence versioned_version"); - } - } catch (SQLException e) { - // Will fail if table doesn't exist, which is OK. - conn.rollback(); - } - for (String stmtString : SQLTestsConstants.versionStatements) { - statement.execute(stmtString); - } - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate( - "insert into VERSIONED values('Junk', default)"); - } else { - statement.executeUpdate( - "insert into VERSIONED values(default, 'Junk', default)"); - } - statement.close(); - statement = conn.createStatement(); - ResultSet rs = statement.executeQuery("select * from VERSIONED"); - Assert.assertTrue(rs.next()); - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - } - - public static void createGarbage(JDBCConnectionPool connectionPool) - throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - try { - statement.execute("drop table GARBAGE"); - if (SQLTestsConstants.db == DB.ORACLE) { - statement.execute("drop sequence garbage_seq"); - } - } catch (SQLException e) { - // Will fail if table doesn't exist, which is OK. - conn.rollback(); - } - statement.execute(SQLTestsConstants.createGarbage); - if (SQLTestsConstants.db == DB.ORACLE) { - statement.execute(SQLTestsConstants.createGarbageSecond); - statement.execute(SQLTestsConstants.createGarbageThird); - } - conn.commit(); - connectionPool.releaseConnection(conn); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java deleted file mode 100644 index 8688c9ae64..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/FreeformQueryUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import java.util.List; - -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -public class FreeformQueryUtil { - - public static StatementHelper getQueryWithFilters(List<Filter> filters, - int offset, int limit) { - StatementHelper sh = new StatementHelper(); - if (SQLTestsConstants.db == DB.MSSQL) { - if (limit > 1) { - offset++; - limit--; - } - StringBuilder query = new StringBuilder(); - query.append("SELECT * FROM (SELECT row_number() OVER ("); - query.append("ORDER BY \"ID\" ASC"); - query.append(") AS rownum, * FROM \"PEOPLE\""); - - if (!filters.isEmpty()) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(") AS a WHERE a.rownum BETWEEN ").append(offset) - .append(" AND ").append(Integer.toString(offset + limit)); - sh.setQueryString(query.toString()); - return sh; - } else if (SQLTestsConstants.db == DB.ORACLE) { - if (limit > 1) { - offset++; - limit--; - } - StringBuilder query = new StringBuilder(); - query.append("SELECT * FROM (SELECT x.*, ROWNUM AS " - + "\"rownum\" FROM (SELECT * FROM \"PEOPLE\""); - if (!filters.isEmpty()) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - query.append(") x) WHERE \"rownum\" BETWEEN ? AND ?"); - sh.addParameterValue(offset); - sh.addParameterValue(offset + limit); - sh.setQueryString(query.toString()); - return sh; - } else { - StringBuilder query = new StringBuilder("SELECT * FROM people"); - if (!filters.isEmpty()) { - query.append( - QueryBuilder.getWhereStringForFilters(filters, sh)); - } - if (limit != 0 || offset != 0) { - query.append(" LIMIT ? OFFSET ?"); - sh.addParameterValue(limit); - sh.addParameterValue(offset); - } - sh.setQueryString(query.toString()); - return sh; - } - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java deleted file mode 100644 index 29968ecf94..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/ReadOnlyRowIdTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import org.junit.Assert; -import org.junit.Test; - -public class ReadOnlyRowIdTest { - - @Test - public void getRowNum_shouldReturnRowNumGivenInConstructor() { - int rowNum = 1337; - ReadOnlyRowId rid = new ReadOnlyRowId(rowNum); - Assert.assertEquals(rowNum, rid.getRowNum()); - } - - @Test - public void hashCode_shouldBeEqualToHashCodeOfRowNum() { - int rowNum = 1337; - ReadOnlyRowId rid = new ReadOnlyRowId(rowNum); - Assert.assertEquals(Integer.valueOf(rowNum).hashCode(), rid.hashCode()); - } - - @Test - public void equals_compareWithNull_shouldBeFalse() { - ReadOnlyRowId rid = new ReadOnlyRowId(1337); - Assert.assertFalse(rid.equals(null)); - } - - @Test - public void equals_compareWithSameInstance_shouldBeTrue() { - ReadOnlyRowId rid = new ReadOnlyRowId(1337); - ReadOnlyRowId rid2 = rid; - Assert.assertTrue(rid.equals(rid2)); - } - - @Test - public void equals_compareWithOtherType_shouldBeFalse() { - ReadOnlyRowId rid = new ReadOnlyRowId(1337); - Assert.assertFalse(rid.equals(new Object())); - } - - @Test - public void equals_compareWithOtherRowId_shouldBeFalse() { - ReadOnlyRowId rid = new ReadOnlyRowId(1337); - ReadOnlyRowId rid2 = new ReadOnlyRowId(42); - Assert.assertFalse(rid.equals(rid2)); - } - - @Test - public void toString_rowNumberIsReturned() { - int i = 1; - ReadOnlyRowId rowId = new ReadOnlyRowId(i); - Assert.assertEquals("Unexpected toString value", String.valueOf(i), - rowId.toString()); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java deleted file mode 100644 index e93048157b..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/RowIdTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import org.junit.Assert; -import org.junit.Test; - -public class RowIdTest { - - @Test - public void constructor_withArrayOfPrimaryKeyColumns_shouldSucceed() { - RowId id = new RowId(new Object[] { "id", "name" }); - Assert.assertArrayEquals(new Object[] { "id", "name" }, id.getId()); - } - - @Test(expected = IllegalArgumentException.class) - public void constructor_withNullParameter_shouldFail() { - new RowId(null); - } - - @Test - public void hashCode_samePrimaryKeys_sameResult() { - RowId id = new RowId(new Object[] { "id", "name" }); - RowId id2 = new RowId(new Object[] { "id", "name" }); - Assert.assertEquals(id.hashCode(), id2.hashCode()); - } - - @Test - public void hashCode_differentPrimaryKeys_differentResult() { - RowId id = new RowId(new Object[] { "id", "name" }); - RowId id2 = new RowId(new Object[] { "id" }); - Assert.assertFalse(id.hashCode() == id2.hashCode()); - } - - @Test - public void equals_samePrimaryKeys_returnsTrue() { - RowId id = new RowId(new Object[] { "id", "name" }); - RowId id2 = new RowId(new Object[] { "id", "name" }); - Assert.assertEquals(id, id2); - } - - @Test - public void equals_differentPrimaryKeys_returnsFalse() { - RowId id = new RowId(new Object[] { "id", "name" }); - RowId id2 = new RowId(new Object[] { "id" }); - Assert.assertFalse(id.equals(id2.hashCode())); - } - - @Test - public void equals_differentDataType_returnsFalse() { - RowId id = new RowId(new Object[] { "id", "name" }); - Assert.assertFalse(id.equals("Tudiluu")); - Assert.assertFalse(id.equals(new Integer(1337))); - } - - @Test - public void toString_defaultCtor_noException() { - RowId rowId = new RowId(); - Assert.assertTrue("Unexpected to string for empty Row Id", - rowId.toString().isEmpty()); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java deleted file mode 100644 index 0bdcc9a3c3..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java +++ /dev/null @@ -1,1353 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNull.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.easymock.EasyMock; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.ItemSetChangeEvent; -import com.vaadin.data.Container.ItemSetChangeListener; -import com.vaadin.data.Item; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; -import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; - -public class SQLContainerTableQueryTest { - - private static final int offset = SQLTestsConstants.offset; - private final int numberOfRowsInContainer = 4; - private final int numberOfPropertiesInContainer = 3; - private final String NAME = "NAME"; - private final String ID = "ID"; - private final String AGE = "AGE"; - private JDBCConnectionPool connectionPool; - private TableQuery query; - private SQLContainer container; - private final RowId existingItemId = getRowId(1); - private final RowId nonExistingItemId = getRowId(1337); - - @Before - public void setUp() throws SQLException { - - try { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - - DataGenerator.addPeopleToDatabase(connectionPool); - - query = getTableQuery("people"); - container = new SQLContainer(query); - } - - private TableQuery getTableQuery(String tableName) { - return new TableQuery(tableName, connectionPool, - SQLTestsConstants.sqlGen); - } - - private SQLContainer getGarbageContainer() throws SQLException { - DataGenerator.createGarbage(connectionPool); - - return new SQLContainer(getTableQuery("garbage")); - } - - private Item getItem(Object id) { - return container.getItem(id); - } - - private RowId getRowId(int id) { - return new RowId(new Object[] { id + offset }); - } - - @After - public void tearDown() { - if (connectionPool != null) { - connectionPool.destroy(); - } - } - - @Test - public void itemWithExistingVersionColumnIsRemoved() throws SQLException { - container.setAutoCommit(true); - query.setVersionColumn(ID); - - assertTrue(container.removeItem(container.lastItemId())); - } - - @Test(expected = SQLException.class) - public void itemWithNonExistingVersionColumnCannotBeRemoved() - throws SQLException { - query.setVersionColumn("version"); - - container.removeItem(container.lastItemId()); - - container.commit(); - } - - @Test - public void containerContainsId() { - assertTrue(container.containsId(existingItemId)); - } - - @Test - public void containerDoesNotContainId() { - assertFalse(container.containsId(nonExistingItemId)); - } - - @Test - public void idPropertyHasCorrectType() { - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(container.getType(ID), BigDecimal.class); - } else { - assertEquals(container.getType(ID), Integer.class); - } - } - - @Test - public void namePropertyHasCorrectType() { - assertEquals(container.getType(NAME), String.class); - } - - @Test - public void nonExistingPropertyDoesNotHaveType() { - assertThat(container.getType("adsf"), is(nullValue())); - } - - @Test - public void sizeIsReturnedCorrectly() { - assertEquals(numberOfRowsInContainer, container.size()); - } - - @Test - public void propertyIsFetchedForExistingItem() { - assertThat(container.getContainerProperty(existingItemId, NAME) - .getValue().toString(), is("Kalle")); - } - - @Test - public void containerDoesNotContainPropertyForExistingItem() { - assertThat(container.getContainerProperty(existingItemId, "asdf"), - is(nullValue())); - } - - @Test - public void containerDoesNotContainExistingPropertyForNonExistingItem() { - assertThat(container.getContainerProperty(nonExistingItemId, NAME), - is(nullValue())); - } - - @Test - public void propertyIdsAreFetched() { - ArrayList<String> propertyIds = new ArrayList<String>( - (Collection<? extends String>) container - .getContainerPropertyIds()); - - assertThat(propertyIds.size(), is(numberOfPropertiesInContainer)); - assertThat(propertyIds, hasItems(ID, NAME, AGE)); - } - - @Test - public void existingItemIsFetched() { - Item item = container.getItem(existingItemId); - - assertThat(item.getItemProperty(NAME).getValue().toString(), - is("Kalle")); - } - - @Test - public void newItemIsAdded() throws SQLException { - Object id = container.addItem(); - getItem(id).getItemProperty(NAME).setValue("foo"); - - container.commit(); - - Item item = getItem(container.lastItemId()); - assertThat(item.getItemProperty(NAME).getValue(), is("foo")); - } - - @Test - public void itemPropertyIsNotRevertedOnRefresh() { - getItem(existingItemId).getItemProperty(NAME).setValue("foo"); - - container.refresh(); - - assertThat(getItem(existingItemId).getItemProperty(NAME).getValue(), - is("foo")); - } - - @Test - public void correctItemIsFetchedFromMultipleRows() throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - Item item = container.getItem(getRowId(1337)); - - assertThat((Integer) item.getItemProperty(ID).getValue(), - is(equalTo(1337 + offset))); - assertThat(item.getItemProperty(NAME).getValue().toString(), - is("Person 1337")); - } - - @Test - public void getItemIds_table_returnsItemIdsWithKeys0through3() - throws SQLException { - Collection<?> itemIds = container.getItemIds(); - assertEquals(4, itemIds.size()); - RowId zero = new RowId(new Object[] { 0 + offset }); - RowId one = new RowId(new Object[] { 1 + offset }); - RowId two = new RowId(new Object[] { 2 + offset }); - RowId three = new RowId(new Object[] { 3 + offset }); - if (SQLTestsConstants.db == DB.ORACLE) { - String[] correct = new String[] { "1", "2", "3", "4" }; - List<String> oracle = new ArrayList<String>(); - for (Object o : itemIds) { - oracle.add(o.toString()); - } - Assert.assertArrayEquals(correct, oracle.toArray()); - } else { - Assert.assertArrayEquals(new Object[] { zero, one, two, three }, - itemIds.toArray()); - } - } - - @Test - public void size_tableOneAddedItem_returnsFive() throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate("insert into people values('Bengt', 30)"); - } else { - statement.executeUpdate( - "insert into people values(default, 'Bengt', 30)"); - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - assertEquals(5, container.size()); - } - - @Test - public void indexOfId_tableWithParameterThree_returnsThree() - throws SQLException { - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(3, container.indexOfId( - new RowId(new Object[] { new BigDecimal(3 + offset) }))); - } else { - assertEquals(3, container - .indexOfId(new RowId(new Object[] { 3 + offset }))); - } - } - - @Test - public void indexOfId_table5000RowsWithParameter1337_returns1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - if (SQLTestsConstants.db == DB.ORACLE) { - container.getItem( - new RowId(new Object[] { new BigDecimal(1337 + offset) })); - assertEquals(1337, container.indexOfId( - new RowId(new Object[] { new BigDecimal(1337 + offset) }))); - } else { - container.getItem(new RowId(new Object[] { 1337 + offset })); - assertEquals(1337, container - .indexOfId(new RowId(new Object[] { 1337 + offset }))); - } - } - - @Test - public void getIdByIndex_table5000rowsIndex1337_returnsRowId1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(new RowId(new Object[] { 1337 + offset }).toString(), - itemId.toString()); - } else { - assertEquals(new RowId(new Object[] { 1337 + offset }), itemId); - } - } - - @Test - public void getIdByIndex_tableWithPaging5000rowsIndex1337_returnsRowId1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(new RowId(new Object[] { 1337 + offset }).toString(), - itemId.toString()); - } else { - assertEquals(new RowId(new Object[] { 1337 + offset }), itemId); - } - } - - @Test - public void nextItemId_tableCurrentItem1337_returnsItem1338() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer(new TableQuery("people", - connectionPool, SQLTestsConstants.sqlGen)); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(new RowId(new Object[] { 1338 + offset }).toString(), - container.nextItemId(itemId).toString()); - } else { - assertEquals(new RowId(new Object[] { 1338 + offset }), - container.nextItemId(itemId)); - } - } - - @Test - public void prevItemId_tableCurrentItem1337_returns1336() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(new RowId(new Object[] { 1336 + offset }).toString(), - container.prevItemId(itemId).toString()); - } else { - assertEquals(new RowId(new Object[] { 1336 + offset }), - container.prevItemId(itemId)); - } - } - - @Test - public void firstItemId_table_returnsItemId0() throws SQLException { - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(new RowId(new Object[] { 0 + offset }).toString(), - container.firstItemId().toString()); - } else { - assertEquals(new RowId(new Object[] { 0 + offset }), - container.firstItemId()); - } - } - - @Test - public void lastItemId_table5000Rows_returnsItemId4999() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - if (SQLTestsConstants.db == DB.ORACLE) { - assertEquals(new RowId(new Object[] { 4999 + offset }).toString(), - container.lastItemId().toString()); - } else { - assertEquals(new RowId(new Object[] { 4999 + offset }), - container.lastItemId()); - } - } - - @Test - public void isFirstId_tableActualFirstId_returnsTrue() throws SQLException { - if (SQLTestsConstants.db == DB.ORACLE) { - assertTrue(container.isFirstId( - new RowId(new Object[] { new BigDecimal(0 + offset) }))); - } else { - assertTrue(container - .isFirstId(new RowId(new Object[] { 0 + offset }))); - } - } - - @Test - public void isFirstId_tableSecondId_returnsFalse() throws SQLException { - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertFalse(container.isFirstId( - new RowId(new Object[] { new BigDecimal(1 + offset) }))); - } else { - Assert.assertFalse(container - .isFirstId(new RowId(new Object[] { 1 + offset }))); - } - } - - @Test - public void isLastId_tableSecondId_returnsFalse() throws SQLException { - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertFalse(container.isLastId( - new RowId(new Object[] { new BigDecimal(1 + offset) }))); - } else { - Assert.assertFalse( - container.isLastId(new RowId(new Object[] { 1 + offset }))); - } - } - - @Test - public void isLastId_tableLastId_returnsTrue() throws SQLException { - if (SQLTestsConstants.db == DB.ORACLE) { - assertTrue(container.isLastId( - new RowId(new Object[] { new BigDecimal(3 + offset) }))); - } else { - assertTrue( - container.isLastId(new RowId(new Object[] { 3 + offset }))); - } - } - - @Test - public void isLastId_table5000RowsLastId_returnsTrue() throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - if (SQLTestsConstants.db == DB.ORACLE) { - assertTrue(container.isLastId( - new RowId(new Object[] { new BigDecimal(4999 + offset) }))); - } else { - assertTrue(container - .isLastId(new RowId(new Object[] { 4999 + offset }))); - } - } - - @Test - public void allIdsFound_table5000RowsLastId_shouldSucceed() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - for (int i = 0; i < 5000; i++) { - assertTrue(container.containsId(container.getIdByIndex(i))); - } - } - - @Test - public void allIdsFound_table5000RowsLastId_autoCommit_shouldSucceed() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - container.setAutoCommit(true); - for (int i = 0; i < 5000; i++) { - assertTrue(container.containsId(container.getIdByIndex(i))); - } - } - - @Test - public void refresh_table_sizeShouldUpdate() throws SQLException { - assertEquals(4, container.size()); - DataGenerator.addFiveThousandPeople(connectionPool); - container.refresh(); - assertEquals(5000, container.size()); - } - - @Test - public void refresh_tableWithoutCallingRefresh_sizeShouldNotUpdate() - throws SQLException { - // Yeah, this is a weird one. We're testing that the size doesn't update - // after adding lots of items unless we call refresh inbetween. This to - // make sure that the refresh method actually refreshes stuff and isn't - // a NOP. - assertEquals(4, container.size()); - DataGenerator.addFiveThousandPeople(connectionPool); - assertEquals(4, container.size()); - } - - @Test - public void setAutoCommit_table_shouldSucceed() throws SQLException { - container.setAutoCommit(true); - assertTrue(container.isAutoCommit()); - container.setAutoCommit(false); - Assert.assertFalse(container.isAutoCommit()); - } - - @Test - public void getPageLength_table_returnsDefault100() throws SQLException { - assertEquals(100, container.getPageLength()); - } - - @Test - public void setPageLength_table_shouldSucceed() throws SQLException { - container.setPageLength(20); - assertEquals(20, container.getPageLength()); - container.setPageLength(200); - assertEquals(200, container.getPageLength()); - } - - @Test(expected = UnsupportedOperationException.class) - public void addContainerProperty_normal_isUnsupported() - throws SQLException { - container.addContainerProperty("asdf", String.class, ""); - } - - @Test(expected = UnsupportedOperationException.class) - public void removeContainerProperty_normal_isUnsupported() - throws SQLException { - container.removeContainerProperty("asdf"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemObject_normal_isUnsupported() throws SQLException { - container.addItem("asdf"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAfterObjectObject_normal_isUnsupported() - throws SQLException { - container.addItemAfter("asdf", "foo"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAtIntObject_normal_isUnsupported() throws SQLException { - container.addItemAt(2, "asdf"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAtInt_normal_isUnsupported() throws SQLException { - container.addItemAt(2); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAfterObject_normal_isUnsupported() throws SQLException { - container.addItemAfter("asdf"); - } - - @Test - public void addItem_tableAddOneNewItem_returnsItemId() throws SQLException { - Object itemId = container.addItem(); - Assert.assertNotNull(itemId); - } - - @Test - public void addItem_tableAddOneNewItem_autoCommit_returnsFinalItemId() - throws SQLException { - container.setAutoCommit(true); - Object itemId = container.addItem(); - Assert.assertNotNull(itemId); - assertTrue(itemId instanceof RowId); - Assert.assertFalse(itemId instanceof TemporaryRowId); - } - - @Test - public void addItem_tableAddOneNewItem_autoCommit_sizeIsIncreased() - throws SQLException { - container.setAutoCommit(true); - int originalSize = container.size(); - container.addItem(); - assertEquals(originalSize + 1, container.size()); - } - - @Test - public void addItem_tableAddOneNewItem_shouldChangeSize() - throws SQLException { - int size = container.size(); - container.addItem(); - assertEquals(size + 1, container.size()); - } - - @Test - public void addItem_tableAddTwoNewItems_shouldChangeSize() - throws SQLException { - int size = container.size(); - Object id1 = container.addItem(); - Object id2 = container.addItem(); - assertEquals(size + 2, container.size()); - Assert.assertNotSame(id1, id2); - Assert.assertFalse(id1.equals(id2)); - } - - @Test - public void nextItemId_tableNewlyAddedItem_returnsNewlyAdded() - throws SQLException { - Object lastId = container.lastItemId(); - Object id = container.addItem(); - assertEquals(id, container.nextItemId(lastId)); - } - - @Test - public void lastItemId_tableNewlyAddedItem_returnsNewlyAdded() - throws SQLException { - Object lastId = container.lastItemId(); - Object id = container.addItem(); - assertEquals(id, container.lastItemId()); - Assert.assertNotSame(lastId, container.lastItemId()); - } - - @Test - public void indexOfId_tableNewlyAddedItem_returnsFour() - throws SQLException { - Object id = container.addItem(); - assertEquals(4, container.indexOfId(id)); - } - - @Test - public void getItem_tableNewlyAddedItem_returnsNewlyAdded() - throws SQLException { - Object id = container.addItem(); - Assert.assertNotNull(container.getItem(id)); - } - - @Test - public void getItemIds_tableNewlyAddedItem_containsNewlyAdded() - throws SQLException { - Object id = container.addItem(); - assertTrue(container.getItemIds().contains(id)); - } - - @Test - public void getContainerProperty_tableNewlyAddedItem_returnsPropertyOfNewlyAddedItem() - throws SQLException { - Object id = container.addItem(); - Item item = container.getItem(id); - item.getItemProperty(NAME).setValue("asdf"); - assertEquals("asdf", - container.getContainerProperty(id, NAME).getValue()); - } - - @Test - public void containsId_tableNewlyAddedItem_returnsTrue() - throws SQLException { - Object id = container.addItem(); - - assertTrue(container.containsId(id)); - } - - @Test - public void prevItemId_tableTwoNewlyAddedItems_returnsFirstAddedItem() - throws SQLException { - Object id1 = container.addItem(); - Object id2 = container.addItem(); - - assertEquals(id1, container.prevItemId(id2)); - } - - @Test - public void firstItemId_tableEmptyResultSet_returnsFirstAddedItem() - throws SQLException { - SQLContainer garbageContainer = getGarbageContainer(); - - Object id = garbageContainer.addItem(); - - Assert.assertSame(id, garbageContainer.firstItemId()); - } - - @Test - public void isFirstId_tableEmptyResultSet_returnsFirstAddedItem() - throws SQLException { - SQLContainer garbageContainer = getGarbageContainer(); - - Object id = garbageContainer.addItem(); - - assertTrue(garbageContainer.isFirstId(id)); - } - - @Test - public void isLastId_tableOneItemAdded_returnsTrueForAddedItem() - throws SQLException { - Object id = container.addItem(); - - assertTrue(container.isLastId(id)); - } - - @Test - public void isLastId_tableTwoItemsAdded_returnsTrueForLastAddedItem() - throws SQLException { - container.addItem(); - - Object id2 = container.addItem(); - - assertTrue(container.isLastId(id2)); - } - - @Test - public void getIdByIndex_tableOneItemAddedLastIndexInContainer_returnsAddedItem() - throws SQLException { - Object id = container.addItem(); - - assertEquals(id, container.getIdByIndex(container.size() - 1)); - } - - @Test - public void removeItem_tableNoAddedItems_removesItemFromContainer() - throws SQLException { - int originalSize = container.size(); - Object id = container.firstItemId(); - - assertTrue(container.removeItem(id)); - - Assert.assertNotSame(id, container.firstItemId()); - assertEquals(originalSize - 1, container.size()); - } - - @Test - public void containsId_tableRemovedItem_returnsFalse() throws SQLException { - Object id = container.firstItemId(); - assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - } - - @Test - public void removeItem_tableOneAddedItem_removesTheAddedItem() - throws SQLException { - Object id = container.addItem(); - int size = container.size(); - - assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - assertEquals(size - 1, container.size()); - } - - @Test - public void getItem_tableItemRemoved_returnsNull() throws SQLException { - Object id = container.firstItemId(); - - assertTrue(container.removeItem(id)); - Assert.assertNull(container.getItem(id)); - } - - @Test - public void getItem_tableAddedItemRemoved_returnsNull() - throws SQLException { - Object id = container.addItem(); - - Assert.assertNotNull(container.getItem(id)); - assertTrue(container.removeItem(id)); - Assert.assertNull(container.getItem(id)); - } - - @Test - public void getItemIds_tableItemRemoved_shouldNotContainRemovedItem() - throws SQLException { - Object id = container.firstItemId(); - - assertTrue(container.getItemIds().contains(id)); - assertTrue(container.removeItem(id)); - Assert.assertFalse(container.getItemIds().contains(id)); - } - - @Test - public void getItemIds_tableAddedItemRemoved_shouldNotContainRemovedItem() - throws SQLException { - Object id = container.addItem(); - - assertTrue(container.getItemIds().contains(id)); - assertTrue(container.removeItem(id)); - Assert.assertFalse(container.getItemIds().contains(id)); - } - - @Test - public void containsId_tableItemRemoved_returnsFalse() throws SQLException { - Object id = container.firstItemId(); - - assertTrue(container.containsId(id)); - assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - } - - @Test - public void containsId_tableAddedItemRemoved_returnsFalse() - throws SQLException { - Object id = container.addItem(); - - assertTrue(container.containsId(id)); - assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - } - - @Test - public void nextItemId_tableItemRemoved_skipsRemovedItem() - throws SQLException { - Object first = container.getIdByIndex(0); - Object second = container.getIdByIndex(1); - Object third = container.getIdByIndex(2); - - assertTrue(container.removeItem(second)); - assertEquals(third, container.nextItemId(first)); - } - - @Test - public void nextItemId_tableAddedItemRemoved_skipsRemovedItem() - throws SQLException { - Object first = container.lastItemId(); - Object second = container.addItem(); - Object third = container.addItem(); - - assertTrue(container.removeItem(second)); - assertEquals(third, container.nextItemId(first)); - } - - @Test - public void prevItemId_tableItemRemoved_skipsRemovedItem() - throws SQLException { - Object first = container.getIdByIndex(0); - Object second = container.getIdByIndex(1); - Object third = container.getIdByIndex(2); - - assertTrue(container.removeItem(second)); - assertEquals(first, container.prevItemId(third)); - } - - @Test - public void prevItemId_tableAddedItemRemoved_skipsRemovedItem() - throws SQLException { - Object first = container.lastItemId(); - Object second = container.addItem(); - Object third = container.addItem(); - - assertTrue(container.removeItem(second)); - assertEquals(first, container.prevItemId(third)); - } - - @Test - public void firstItemId_tableFirstItemRemoved_resultChanges() - throws SQLException { - Object first = container.firstItemId(); - - assertTrue(container.removeItem(first)); - Assert.assertNotSame(first, container.firstItemId()); - } - - @Test - public void firstItemId_tableNewlyAddedFirstItemRemoved_resultChanges() - throws SQLException { - SQLContainer garbageContainer = getGarbageContainer(); - - Object first = garbageContainer.addItem(); - Object second = garbageContainer.addItem(); - - Assert.assertSame(first, garbageContainer.firstItemId()); - assertTrue(garbageContainer.removeItem(first)); - Assert.assertSame(second, garbageContainer.firstItemId()); - } - - @Test - public void lastItemId_tableLastItemRemoved_resultChanges() - throws SQLException { - Object last = container.lastItemId(); - - assertTrue(container.removeItem(last)); - Assert.assertNotSame(last, container.lastItemId()); - } - - @Test - public void lastItemId_tableAddedLastItemRemoved_resultChanges() - throws SQLException { - Object last = container.addItem(); - - Assert.assertSame(last, container.lastItemId()); - assertTrue(container.removeItem(last)); - Assert.assertNotSame(last, container.lastItemId()); - } - - @Test - public void isFirstId_tableFirstItemRemoved_returnsFalse() - throws SQLException { - Object first = container.firstItemId(); - - assertTrue(container.removeItem(first)); - Assert.assertFalse(container.isFirstId(first)); - } - - @Test - public void isFirstId_tableAddedFirstItemRemoved_returnsFalse() - throws SQLException { - SQLContainer garbageContainer = getGarbageContainer(); - - Object first = garbageContainer.addItem(); - garbageContainer.addItem(); - - Assert.assertSame(first, garbageContainer.firstItemId()); - assertTrue(garbageContainer.removeItem(first)); - Assert.assertFalse(garbageContainer.isFirstId(first)); - } - - @Test - public void isLastId_tableLastItemRemoved_returnsFalse() - throws SQLException { - Object last = container.lastItemId(); - - assertTrue(container.removeItem(last)); - Assert.assertFalse(container.isLastId(last)); - } - - @Test - public void isLastId_tableAddedLastItemRemoved_returnsFalse() - throws SQLException { - Object last = container.addItem(); - - Assert.assertSame(last, container.lastItemId()); - assertTrue(container.removeItem(last)); - Assert.assertFalse(container.isLastId(last)); - } - - @Test - public void indexOfId_tableItemRemoved_returnsNegOne() throws SQLException { - Object id = container.getIdByIndex(2); - - assertTrue(container.removeItem(id)); - assertEquals(-1, container.indexOfId(id)); - } - - @Test - public void indexOfId_tableAddedItemRemoved_returnsNegOne() - throws SQLException { - Object id = container.addItem(); - - assertTrue(container.indexOfId(id) != -1); - assertTrue(container.removeItem(id)); - assertEquals(-1, container.indexOfId(id)); - } - - @Test - public void getIdByIndex_tableItemRemoved_resultChanges() - throws SQLException { - Object id = container.getIdByIndex(2); - - assertTrue(container.removeItem(id)); - Assert.assertNotSame(id, container.getIdByIndex(2)); - } - - @Test - public void getIdByIndex_tableAddedItemRemoved_resultChanges() - throws SQLException { - Object id = container.addItem(); - container.addItem(); - int index = container.indexOfId(id); - - assertTrue(container.removeItem(id)); - Assert.assertNotSame(id, container.getIdByIndex(index)); - } - - @Test - public void removeAllItems_table_shouldSucceed() throws SQLException { - assertTrue(container.removeAllItems()); - assertEquals(0, container.size()); - } - - @Test - public void removeAllItems_tableAddedItems_shouldSucceed() - throws SQLException { - container.addItem(); - container.addItem(); - - assertTrue(container.removeAllItems()); - assertEquals(0, container.size()); - } - - // Set timeout to ensure there is no infinite looping (#12882) - @Test(timeout = 1000) - public void removeAllItems_manyItems_commit_shouldSucceed() - throws SQLException { - final int itemNumber = (SQLContainer.CACHE_RATIO + 1) - * SQLContainer.DEFAULT_PAGE_LENGTH + 1; - - container.removeAllItems(); - - assertEquals(container.size(), 0); - for (int i = 0; i < itemNumber; ++i) { - container.addItem(); - } - container.commit(); - assertEquals(container.size(), itemNumber); - assertTrue(container.removeAllItems()); - container.commit(); - assertEquals(container.size(), 0); - } - - @Test - public void commit_tableAddedItem_shouldBeWrittenToDB() - throws SQLException { - Object id = container.addItem(); - container.getContainerProperty(id, NAME).setValue("New Name"); - - assertTrue(id instanceof TemporaryRowId); - Assert.assertSame(id, container.lastItemId()); - container.commit(); - Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); - assertEquals("New Name", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void commit_tableTwoAddedItems_shouldBeWrittenToDB() - throws SQLException { - Object id = container.addItem(); - Object id2 = container.addItem(); - container.getContainerProperty(id, NAME).setValue("Herbert"); - container.getContainerProperty(id2, NAME).setValue("Larry"); - assertTrue(id2 instanceof TemporaryRowId); - Assert.assertSame(id2, container.lastItemId()); - container.commit(); - Object nextToLast = container.getIdByIndex(container.size() - 2); - - Assert.assertFalse(nextToLast instanceof TemporaryRowId); - assertEquals("Herbert", - container.getContainerProperty(nextToLast, NAME).getValue()); - Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); - assertEquals("Larry", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void commit_tableRemovedItem_shouldBeRemovedFromDB() - throws SQLException { - Object last = container.lastItemId(); - container.removeItem(last); - container.commit(); - - Assert.assertFalse(last.equals(container.lastItemId())); - } - - @Test - public void commit_tableLastItemUpdated_shouldUpdateRowInDB() - throws SQLException { - Object last = container.lastItemId(); - container.getContainerProperty(last, NAME).setValue("Donald"); - container.commit(); - - assertEquals("Donald", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void commit_removeModifiedItem_shouldSucceed() throws SQLException { - int size = container.size(); - Object key = container.firstItemId(); - Item row = container.getItem(key); - row.getItemProperty(NAME).setValue("Pekka"); - - assertTrue(container.removeItem(key)); - container.commit(); - assertEquals(size - 1, container.size()); - } - - @Test - public void rollback_tableItemAdded_discardsAddedItem() - throws SQLException { - int size = container.size(); - Object id = container.addItem(); - container.getContainerProperty(id, NAME).setValue("foo"); - assertEquals(size + 1, container.size()); - container.rollback(); - assertEquals(size, container.size()); - Assert.assertFalse("foo".equals( - container.getContainerProperty(container.lastItemId(), NAME) - .getValue())); - } - - @Test - public void rollback_tableItemRemoved_restoresRemovedItem() - throws SQLException { - int size = container.size(); - Object last = container.lastItemId(); - container.removeItem(last); - assertEquals(size - 1, container.size()); - container.rollback(); - assertEquals(size, container.size()); - assertEquals(last, container.lastItemId()); - } - - @Test - public void rollback_tableItemChanged_discardsChanges() - throws SQLException { - Object last = container.lastItemId(); - container.getContainerProperty(last, NAME).setValue("foo"); - container.rollback(); - Assert.assertFalse("foo".equals( - container.getContainerProperty(container.lastItemId(), NAME) - .getValue())); - } - - @Test - public void itemChangeNotification_table_isModifiedReturnsTrue() - throws SQLException { - Assert.assertFalse(container.isModified()); - RowItem last = (RowItem) container.getItem(container.lastItemId()); - container.itemChangeNotification(last); - assertTrue(container.isModified()); - } - - @Test - public void itemSetChangeListeners_table_shouldFire() throws SQLException { - ItemSetChangeListener listener = EasyMock - .createMock(ItemSetChangeListener.class); - listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); - EasyMock.replay(listener); - - container.addListener(listener); - container.addItem(); - - EasyMock.verify(listener); - } - - @Test - public void itemSetChangeListeners_tableItemRemoved_shouldFire() - throws SQLException { - ItemSetChangeListener listener = EasyMock - .createMock(ItemSetChangeListener.class); - listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.replay(listener); - - container.addListener(listener); - container.removeItem(container.lastItemId()); - - EasyMock.verify(listener); - } - - @Test - public void removeListener_table_shouldNotFire() throws SQLException { - ItemSetChangeListener listener = EasyMock - .createMock(ItemSetChangeListener.class); - EasyMock.replay(listener); - - container.addListener(listener); - container.removeListener(listener); - container.addItem(); - - EasyMock.verify(listener); - } - - @Test - public void isModified_tableRemovedItem_returnsTrue() throws SQLException { - Assert.assertFalse(container.isModified()); - container.removeItem(container.lastItemId()); - assertTrue(container.isModified()); - } - - @Test - public void isModified_tableAddedItem_returnsTrue() throws SQLException { - Assert.assertFalse(container.isModified()); - container.addItem(); - assertTrue(container.isModified()); - } - - @Test - public void isModified_tableChangedItem_returnsTrue() throws SQLException { - Assert.assertFalse(container.isModified()); - container.getContainerProperty(container.lastItemId(), NAME) - .setValue("foo"); - assertTrue(container.isModified()); - } - - @Test - public void getSortableContainerPropertyIds_table_returnsAllPropertyIds() - throws SQLException { - Collection<?> sortableIds = container.getSortableContainerPropertyIds(); - assertTrue(sortableIds.contains(ID)); - assertTrue(sortableIds.contains(NAME)); - assertTrue(sortableIds.contains("AGE")); - assertEquals(3, sortableIds.size()); - if (SQLTestsConstants.db == DB.MSSQL - || SQLTestsConstants.db == DB.ORACLE) { - Assert.assertFalse(sortableIds.contains("rownum")); - } - } - - @Test - public void addOrderBy_table_shouldReorderResults() throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals("Ville", - container.getContainerProperty(container.firstItemId(), NAME) - .getValue()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - container.addOrderBy(new OrderBy(NAME, true)); - // Börje, Kalle, Pelle, Ville - assertEquals("Börje", - container.getContainerProperty(container.firstItemId(), NAME) - .getValue()); - assertEquals("Ville", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test(expected = IllegalArgumentException.class) - public void addOrderBy_tableIllegalColumn_shouldFail() throws SQLException { - container.addOrderBy(new OrderBy("asdf", true)); - } - - @Test - public void sort_table_sortsByName() throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals("Ville", - container.getContainerProperty(container.firstItemId(), NAME) - .getValue()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - container.sort(new Object[] { NAME }, new boolean[] { true }); - - // Börje, Kalle, Pelle, Ville - assertEquals("Börje", - container.getContainerProperty(container.firstItemId(), NAME) - .getValue()); - assertEquals("Ville", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void addFilter_table_filtersResults() throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals(4, container.size()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - container.addContainerFilter(new Like(NAME, "%lle")); - // Ville, Kalle, Pelle - assertEquals(3, container.size()); - assertEquals("Pelle", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void addContainerFilter_filtersResults() throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals(4, container.size()); - - container.addContainerFilter(NAME, "Vi", false, false); - - // Ville - assertEquals(1, container.size()); - assertEquals("Ville", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void addContainerFilter_ignoreCase_filtersResults() - throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals(4, container.size()); - - container.addContainerFilter(NAME, "vi", true, false); - - // Ville - assertEquals(1, container.size()); - assertEquals("Ville", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void removeAllContainerFilters_table_noFiltering() - throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals(4, container.size()); - - container.addContainerFilter(NAME, "Vi", false, false); - - // Ville - assertEquals(1, container.size()); - assertEquals("Ville", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - container.removeAllContainerFilters(); - - assertEquals(4, container.size()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void removeContainerFilters_table_noFiltering() throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals(4, container.size()); - - container.addContainerFilter(NAME, "Vi", false, false); - - // Ville - assertEquals(1, container.size()); - assertEquals("Ville", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - container.removeContainerFilters(NAME); - - assertEquals(4, container.size()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - - @Test - public void addFilter_tableBufferedItems_alsoFiltersBufferedItems() - throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals(4, container.size()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - Object id1 = container.addItem(); - container.getContainerProperty(id1, NAME).setValue("Palle"); - Object id2 = container.addItem(); - container.getContainerProperty(id2, NAME).setValue("Bengt"); - - container.addContainerFilter(new Like(NAME, "%lle")); - - // Ville, Kalle, Pelle, Palle - assertEquals(4, container.size()); - assertEquals("Ville", - container.getContainerProperty(container.getIdByIndex(0), NAME) - .getValue()); - assertEquals("Kalle", - container.getContainerProperty(container.getIdByIndex(1), NAME) - .getValue()); - assertEquals("Pelle", - container.getContainerProperty(container.getIdByIndex(2), NAME) - .getValue()); - assertEquals("Palle", - container.getContainerProperty(container.getIdByIndex(3), NAME) - .getValue()); - - try { - container.getIdByIndex(4); - Assert.fail( - "SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container"); - } catch (IndexOutOfBoundsException e) { - // should throw exception - item is filtered out - } - Assert.assertNull(container.nextItemId(container.getIdByIndex(3))); - - Assert.assertFalse(container.containsId(id2)); - Assert.assertFalse(container.getItemIds().contains(id2)); - - Assert.assertNull(container.getItem(id2)); - assertEquals(-1, container.indexOfId(id2)); - - Assert.assertNotSame(id2, container.lastItemId()); - Assert.assertSame(id1, container.lastItemId()); - } - - @Test - public void sort_tableBufferedItems_sortsBufferedItemsLastInOrderAdded() - throws SQLException { - // Ville, Kalle, Pelle, Börje - assertEquals("Ville", - container.getContainerProperty(container.firstItemId(), NAME) - .getValue()); - assertEquals("Börje", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - - Object id1 = container.addItem(); - container.getContainerProperty(id1, NAME).setValue("Wilbert"); - Object id2 = container.addItem(); - container.getContainerProperty(id2, NAME).setValue("Albert"); - - container.sort(new Object[] { NAME }, new boolean[] { true }); - - // Börje, Kalle, Pelle, Ville, Wilbert, Albert - assertEquals("Börje", - container.getContainerProperty(container.firstItemId(), NAME) - .getValue()); - assertEquals("Wilbert", - container.getContainerProperty( - container.getIdByIndex(container.size() - 2), NAME) - .getValue()); - assertEquals("Albert", container - .getContainerProperty(container.lastItemId(), NAME).getValue()); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java deleted file mode 100644 index d499ceed92..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java +++ /dev/null @@ -1,2469 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.logging.Handler; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -import org.easymock.EasyMock; -import org.easymock.IAnswer; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Container.ItemSetChangeEvent; -import com.vaadin.data.Container.ItemSetChangeListener; -import com.vaadin.data.Item; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; -import com.vaadin.data.util.sqlcontainer.query.FreeformQueryDelegate; -import com.vaadin.data.util.sqlcontainer.query.FreeformStatementDelegate; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; - -public class SQLContainerTest { - private static final int offset = SQLTestsConstants.offset; - private JDBCConnectionPool connectionPool; - - @Before - public void setUp() throws SQLException { - - try { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - - DataGenerator.addPeopleToDatabase(connectionPool); - } - - @After - public void tearDown() { - if (connectionPool != null) { - connectionPool.destroy(); - } - } - - @Test - public void constructor_withFreeformQuery_shouldSucceed() - throws SQLException { - new SQLContainer(new FreeformQuery("SELECT * FROM people", - connectionPool, "ID")); - } - - @Test(expected = SQLException.class) - public void constructor_withIllegalFreeformQuery_shouldFail() - throws SQLException { - SQLContainer c = new SQLContainer( - new FreeformQuery("SELECT * FROM asdf", connectionPool, "ID")); - c.getItem(c.firstItemId()); - } - - @Test - public void containsId_withFreeformQueryAndExistingId_returnsTrue() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertTrue(container.containsId(new RowId(new Object[] { 1 }))); - } - - @Test - public void containsId_withFreeformQueryAndNonexistingId_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertFalse( - container.containsId(new RowId(new Object[] { 1337 }))); - } - - @Test - public void getContainerProperty_freeformExistingItemIdAndPropertyId_returnsProperty() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals("Ville", - container.getContainerProperty(new RowId( - new Object[] { new BigDecimal(0 + offset) }), - "NAME").getValue()); - } else { - Assert.assertEquals("Ville", - container.getContainerProperty( - new RowId(new Object[] { 0 + offset }), "NAME") - .getValue()); - } - } - - @Test - public void getContainerProperty_freeformExistingItemIdAndNonexistingPropertyId_returnsNull() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertNull(container.getContainerProperty( - new RowId(new Object[] { 1 + offset }), "asdf")); - } - - @Test - public void getContainerProperty_freeformNonexistingItemId_returnsNull() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertNull(container.getContainerProperty( - new RowId(new Object[] { 1337 + offset }), "NAME")); - } - - @Test - public void getContainerPropertyIds_freeform_returnsIDAndNAME() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Collection<?> propertyIds = container.getContainerPropertyIds(); - Assert.assertEquals(3, propertyIds.size()); - Assert.assertArrayEquals(new String[] { "ID", "NAME", "AGE" }, - propertyIds.toArray()); - } - - @Test - public void getItem_freeformExistingItemId_returnsItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Item item; - if (SQLTestsConstants.db == DB.ORACLE) { - item = container.getItem( - new RowId(new Object[] { new BigDecimal(0 + offset) })); - } else { - item = container.getItem(new RowId(new Object[] { 0 + offset })); - } - Assert.assertNotNull(item); - Assert.assertEquals("Ville", item.getItemProperty("NAME").getValue()); - } - - @Test - public void nextItemNullAtEnd_freeformExistingItem() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object lastItemId = container.lastItemId(); - Object afterLast = container.nextItemId(lastItemId); - Assert.assertNull(afterLast); - } - - @Test - public void prevItemNullAtStart_freeformExistingItem() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object firstItemId = container.firstItemId(); - Object beforeFirst = container.prevItemId(firstItemId); - Assert.assertNull(beforeFirst); - } - - @Test - public void getItem_freeform5000RowsWithParameter1337_returnsItemWithId1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Item item; - if (SQLTestsConstants.db == DB.ORACLE) { - item = container.getItem( - new RowId(new Object[] { new BigDecimal(1337 + offset) })); - Assert.assertNotNull(item); - Assert.assertEquals(new BigDecimal(1337 + offset), - item.getItemProperty("ID").getValue()); - } else { - item = container.getItem(new RowId(new Object[] { 1337 + offset })); - Assert.assertNotNull(item); - Assert.assertEquals(1337 + offset, - item.getItemProperty("ID").getValue()); - } - Assert.assertEquals("Person 1337", - item.getItemProperty("NAME").getValue()); - } - - @Test - public void getItemIds_freeform_returnsItemIdsWithKeys0through3() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Collection<?> itemIds = container.getItemIds(); - Assert.assertEquals(4, itemIds.size()); - RowId zero = new RowId(new Object[] { 0 + offset }); - RowId one = new RowId(new Object[] { 1 + offset }); - RowId two = new RowId(new Object[] { 2 + offset }); - RowId three = new RowId(new Object[] { 3 + offset }); - if (SQLTestsConstants.db == DB.ORACLE) { - String[] correct = new String[] { "1", "2", "3", "4" }; - List<String> oracle = new ArrayList<String>(); - for (Object o : itemIds) { - oracle.add(o.toString()); - } - Assert.assertArrayEquals(correct, oracle.toArray()); - } else { - Assert.assertArrayEquals(new Object[] { zero, one, two, three }, - itemIds.toArray()); - } - } - - @Test - public void getType_freeformNAMEPropertyId_returnsString() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertEquals(String.class, container.getType("NAME")); - } - - @Test - public void getType_freeformIDPropertyId_returnsInteger() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals(BigDecimal.class, container.getType("ID")); - } else { - Assert.assertEquals(Integer.class, container.getType("ID")); - } - } - - @Test - public void getType_freeformNonexistingPropertyId_returnsNull() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertNull(container.getType("asdf")); - } - - @Test - public void size_freeform_returnsFour() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertEquals(4, container.size()); - } - - @Test - public void size_freeformOneAddedItem_returnsFive() throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate("insert into people values('Bengt', '42')"); - } else { - statement.executeUpdate( - "insert into people values(default, 'Bengt', '42')"); - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertEquals(5, container.size()); - } - - @Test - public void indexOfId_freeformWithParameterThree_returnsThree() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals(3, container.indexOfId( - new RowId(new Object[] { new BigDecimal(3 + offset) }))); - } else { - Assert.assertEquals(3, container - .indexOfId(new RowId(new Object[] { 3 + offset }))); - } - } - - @Test - public void indexOfId_freeform5000RowsWithParameter1337_returns1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer( - new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", - connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - container.getItem( - new RowId(new Object[] { new BigDecimal(1337 + offset) })); - Assert.assertEquals(1337, container.indexOfId( - new RowId(new Object[] { new BigDecimal(1337 + offset) }))); - } else { - container.getItem(new RowId(new Object[] { 1337 + offset })); - Assert.assertEquals(1337, container - .indexOfId(new RowId(new Object[] { 1337 + offset }))); - } - } - - @Test - public void getIdByIndex_freeform5000rowsIndex1337_returnsRowId1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer( - new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", - connectionPool, "ID")); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals( - new RowId(new Object[] { new BigDecimal(1337 + offset) }), - itemId); - } else { - Assert.assertEquals(new RowId(new Object[] { 1337 + offset }), - itemId); - } - } - - @SuppressWarnings("unchecked") - @Test - public void getIdByIndex_freeformWithPaging5000rowsIndex1337_returnsRowId1337() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT row_number() OVER" - + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN " + start - + " AND " + end; - return q; - } else if (SQLTestsConstants.db == DB.ORACLE) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " - + " WHERE r BETWEEN " + start + " AND " - + end; - return q; - } else { - return "SELECT * FROM people LIMIT " + limit - + " OFFSET " + offset; - } - } - }).anyTimes(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals( - new RowId(new Object[] { 1337 + offset }).toString(), - itemId.toString()); - } else { - Assert.assertEquals(new RowId(new Object[] { 1337 + offset }), - itemId); - } - } - - @Test - public void nextItemId_freeformCurrentItem1337_returnsItem1338() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer( - new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", - connectionPool, "ID")); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals( - new RowId(new Object[] { 1338 + offset }).toString(), - container.nextItemId(itemId).toString()); - } else { - Assert.assertEquals(new RowId(new Object[] { 1338 + offset }), - container.nextItemId(itemId)); - } - } - - @Test - public void prevItemId_freeformCurrentItem1337_returns1336() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer( - new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", - connectionPool, "ID")); - Object itemId = container.getIdByIndex(1337); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals( - new RowId(new Object[] { 1336 + offset }).toString(), - container.prevItemId(itemId).toString()); - } else { - Assert.assertEquals(new RowId(new Object[] { 1336 + offset }), - container.prevItemId(itemId)); - } - } - - @Test - public void firstItemId_freeform_returnsItemId0() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals( - new RowId(new Object[] { 0 + offset }).toString(), - container.firstItemId().toString()); - } else { - Assert.assertEquals(new RowId(new Object[] { 0 + offset }), - container.firstItemId()); - } - } - - @Test - public void lastItemId_freeform5000Rows_returnsItemId4999() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - SQLContainer container = new SQLContainer( - new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", - connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals( - new RowId(new Object[] { 4999 + offset }).toString(), - container.lastItemId().toString()); - } else { - Assert.assertEquals(new RowId(new Object[] { 4999 + offset }), - container.lastItemId()); - } - } - - @Test - public void isFirstId_freeformActualFirstId_returnsTrue() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertTrue(container.isFirstId( - new RowId(new Object[] { new BigDecimal(0 + offset) }))); - } else { - Assert.assertTrue(container - .isFirstId(new RowId(new Object[] { 0 + offset }))); - } - } - - @Test - public void isFirstId_freeformSecondId_returnsFalse() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertFalse(container.isFirstId( - new RowId(new Object[] { new BigDecimal(1 + offset) }))); - } else { - Assert.assertFalse(container - .isFirstId(new RowId(new Object[] { 1 + offset }))); - } - } - - @Test - public void isLastId_freeformSecondId_returnsFalse() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertFalse(container.isLastId( - new RowId(new Object[] { new BigDecimal(1 + offset) }))); - } else { - Assert.assertFalse( - container.isLastId(new RowId(new Object[] { 1 + offset }))); - } - } - - @Test - public void isLastId_freeformLastId_returnsTrue() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertTrue(container.isLastId( - new RowId(new Object[] { new BigDecimal(3 + offset) }))); - } else { - Assert.assertTrue( - container.isLastId(new RowId(new Object[] { 3 + offset }))); - } - } - - @Test - public void isLastId_freeform5000RowsLastId_returnsTrue() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - SQLContainer container = new SQLContainer( - new FreeformQuery("SELECT * FROM people ORDER BY \"ID\" ASC", - connectionPool, "ID")); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertTrue(container.isLastId( - new RowId(new Object[] { new BigDecimal(4999 + offset) }))); - } else { - Assert.assertTrue(container - .isLastId(new RowId(new Object[] { 4999 + offset }))); - } - } - - @Test - public void refresh_freeform_sizeShouldUpdate() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertEquals(4, container.size()); - DataGenerator.addFiveThousandPeople(connectionPool); - container.refresh(); - Assert.assertEquals(5000, container.size()); - } - - @Test - public void refresh_freeformWithoutCallingRefresh_sizeShouldNotUpdate() - throws SQLException { - // Yeah, this is a weird one. We're testing that the size doesn't update - // after adding lots of items unless we call refresh inbetween. This to - // make sure that the refresh method actually refreshes stuff and isn't - // a NOP. - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertEquals(4, container.size()); - DataGenerator.addFiveThousandPeople(connectionPool); - Assert.assertEquals(4, container.size()); - } - - @Test - public void setAutoCommit_freeform_shouldSucceed() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.setAutoCommit(true); - Assert.assertTrue(container.isAutoCommit()); - container.setAutoCommit(false); - Assert.assertFalse(container.isAutoCommit()); - } - - @Test - public void getPageLength_freeform_returnsDefault100() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertEquals(100, container.getPageLength()); - } - - @Test - public void setPageLength_freeform_shouldSucceed() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.setPageLength(20); - Assert.assertEquals(20, container.getPageLength()); - container.setPageLength(200); - Assert.assertEquals(200, container.getPageLength()); - } - - @Test(expected = UnsupportedOperationException.class) - public void addContainerProperty_normal_isUnsupported() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addContainerProperty("asdf", String.class, ""); - } - - @Test(expected = UnsupportedOperationException.class) - public void removeContainerProperty_normal_isUnsupported() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.removeContainerProperty("asdf"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemObject_normal_isUnsupported() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItem("asdf"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAfterObjectObject_normal_isUnsupported() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItemAfter("asdf", "foo"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAtIntObject_normal_isUnsupported() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItemAt(2, "asdf"); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAtInt_normal_isUnsupported() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItemAt(2); - } - - @Test(expected = UnsupportedOperationException.class) - public void addItemAfterObject_normal_isUnsupported() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItemAfter("asdf"); - } - - @Test - public void addItem_freeformAddOneNewItem_returnsItemId() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object itemId = container.addItem(); - Assert.assertNotNull(itemId); - } - - @Test - public void addItem_freeformAddOneNewItem_shouldChangeSize() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - int size = container.size(); - container.addItem(); - Assert.assertEquals(size + 1, container.size()); - } - - @Test - public void addItem_freeformAddTwoNewItems_shouldChangeSize() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - int size = container.size(); - Object id1 = container.addItem(); - Object id2 = container.addItem(); - Assert.assertEquals(size + 2, container.size()); - Assert.assertNotSame(id1, id2); - Assert.assertFalse(id1.equals(id2)); - } - - @Test - public void nextItemId_freeformNewlyAddedItem_returnsNewlyAdded() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object lastId = container.lastItemId(); - Object id = container.addItem(); - Assert.assertEquals(id, container.nextItemId(lastId)); - } - - @Test - public void lastItemId_freeformNewlyAddedItem_returnsNewlyAdded() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object lastId = container.lastItemId(); - Object id = container.addItem(); - Assert.assertEquals(id, container.lastItemId()); - Assert.assertNotSame(lastId, container.lastItemId()); - } - - @Test - public void indexOfId_freeformNewlyAddedItem_returnsFour() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertEquals(4, container.indexOfId(id)); - } - - @Test - public void getItem_freeformNewlyAddedItem_returnsNewlyAdded() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertNotNull(container.getItem(id)); - } - - @Test - public void getItem_freeformNewlyAddedItemAndFiltered_returnsNull() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addContainerFilter(new Equal("NAME", "asdf")); - Object id = container.addItem(); - Assert.assertNull(container.getItem(id)); - } - - @Test - public void getItemUnfiltered_freeformNewlyAddedItemAndFiltered_returnsNewlyAdded() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addContainerFilter(new Equal("NAME", "asdf")); - Object id = container.addItem(); - Assert.assertNotNull(container.getItemUnfiltered(id)); - } - - @Test - public void getItemIds_freeformNewlyAddedItem_containsNewlyAdded() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.getItemIds().contains(id)); - } - - @Test - public void getContainerProperty_freeformNewlyAddedItem_returnsPropertyOfNewlyAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Item item = container.getItem(id); - item.getItemProperty("NAME").setValue("asdf"); - Assert.assertEquals("asdf", - container.getContainerProperty(id, "NAME").getValue()); - } - - @Test - public void containsId_freeformNewlyAddedItem_returnsTrue() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.containsId(id)); - } - - @Test - public void prevItemId_freeformTwoNewlyAddedItems_returnsFirstAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id1 = container.addItem(); - Object id2 = container.addItem(); - Assert.assertEquals(id1, container.prevItemId(id2)); - } - - @Test - public void firstItemId_freeformEmptyResultSet_returnsFirstAddedItem() - throws SQLException { - DataGenerator.createGarbage(connectionPool); - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM GARBAGE", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertSame(id, container.firstItemId()); - } - - @Test - public void isFirstId_freeformEmptyResultSet_returnsFirstAddedItem() - throws SQLException { - DataGenerator.createGarbage(connectionPool); - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM GARBAGE", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.isFirstId(id)); - } - - @Test - public void isLastId_freeformOneItemAdded_returnsTrueForAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.isLastId(id)); - } - - @Test - public void isLastId_freeformTwoItemsAdded_returnsTrueForLastAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItem(); - Object id2 = container.addItem(); - Assert.assertTrue(container.isLastId(id2)); - } - - @Test - public void getIdByIndex_freeformOneItemAddedLastIndexInContainer_returnsAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertEquals(id, container.getIdByIndex(container.size() - 1)); - } - - @Test - public void removeItem_freeformNoAddedItems_removesItemFromContainer() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - int size = container.size(); - Object id = container.firstItemId(); - Assert.assertTrue(container.removeItem(id)); - Assert.assertNotSame(id, container.firstItemId()); - Assert.assertEquals(size - 1, container.size()); - } - - @Test - public void containsId_freeformRemovedItem_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.firstItemId(); - Assert.assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - } - - @Test - public void containsId_unknownObject() throws SQLException { - - Handler ensureNoLogging = new Handler() { - - @Override - public void publish(LogRecord record) { - Assert.fail("No messages should be logged"); - - } - - @Override - public void flush() { - } - - @Override - public void close() throws SecurityException { - } - }; - - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Logger logger = Logger.getLogger(SQLContainer.class.getName()); - - logger.addHandler(ensureNoLogging); - try { - Assert.assertFalse(container.containsId(new Object())); - } finally { - logger.removeHandler(ensureNoLogging); - } - } - - @Test - public void removeItem_freeformOneAddedItem_removesTheAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - int size = container.size(); - Assert.assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - Assert.assertEquals(size - 1, container.size()); - } - - @Test - public void getItem_freeformItemRemoved_returnsNull() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.firstItemId(); - Assert.assertTrue(container.removeItem(id)); - Assert.assertNull(container.getItem(id)); - } - - @Test - public void getItem_freeformAddedItemRemoved_returnsNull() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertNotNull(container.getItem(id)); - Assert.assertTrue(container.removeItem(id)); - Assert.assertNull(container.getItem(id)); - } - - @Test - public void getItemIds_freeformItemRemoved_shouldNotContainRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.firstItemId(); - Assert.assertTrue(container.getItemIds().contains(id)); - Assert.assertTrue(container.removeItem(id)); - Assert.assertFalse(container.getItemIds().contains(id)); - } - - @Test - public void getItemIds_freeformAddedItemRemoved_shouldNotContainRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.getItemIds().contains(id)); - Assert.assertTrue(container.removeItem(id)); - Assert.assertFalse(container.getItemIds().contains(id)); - } - - @Test - public void containsId_freeformItemRemoved_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.firstItemId(); - Assert.assertTrue(container.containsId(id)); - Assert.assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - } - - @Test - public void containsId_freeformAddedItemRemoved_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.containsId(id)); - Assert.assertTrue(container.removeItem(id)); - Assert.assertFalse(container.containsId(id)); - } - - @Test - public void nextItemId_freeformItemRemoved_skipsRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object first = container.getIdByIndex(0); - Object second = container.getIdByIndex(1); - Object third = container.getIdByIndex(2); - Assert.assertTrue(container.removeItem(second)); - Assert.assertEquals(third, container.nextItemId(first)); - } - - @Test - public void nextItemId_freeformAddedItemRemoved_skipsRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object first = container.lastItemId(); - Object second = container.addItem(); - Object third = container.addItem(); - Assert.assertTrue(container.removeItem(second)); - Assert.assertEquals(third, container.nextItemId(first)); - } - - @Test - public void prevItemId_freeformItemRemoved_skipsRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object first = container.getIdByIndex(0); - Object second = container.getIdByIndex(1); - Object third = container.getIdByIndex(2); - Assert.assertTrue(container.removeItem(second)); - Assert.assertEquals(first, container.prevItemId(third)); - } - - @Test - public void prevItemId_freeformAddedItemRemoved_skipsRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object first = container.lastItemId(); - Object second = container.addItem(); - Object third = container.addItem(); - Assert.assertTrue(container.removeItem(second)); - Assert.assertEquals(first, container.prevItemId(third)); - } - - @Test - public void firstItemId_freeformFirstItemRemoved_resultChanges() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object first = container.firstItemId(); - Assert.assertTrue(container.removeItem(first)); - Assert.assertNotSame(first, container.firstItemId()); - } - - @Test - public void firstItemId_freeformNewlyAddedFirstItemRemoved_resultChanges() - throws SQLException { - DataGenerator.createGarbage(connectionPool); - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM GARBAGE", connectionPool, "ID")); - Object first = container.addItem(); - Object second = container.addItem(); - Assert.assertSame(first, container.firstItemId()); - Assert.assertTrue(container.removeItem(first)); - Assert.assertSame(second, container.firstItemId()); - } - - @Test - public void lastItemId_freeformLastItemRemoved_resultChanges() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object last = container.lastItemId(); - Assert.assertTrue(container.removeItem(last)); - Assert.assertNotSame(last, container.lastItemId()); - } - - @Test - public void lastItemId_freeformAddedLastItemRemoved_resultChanges() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object last = container.addItem(); - Assert.assertSame(last, container.lastItemId()); - Assert.assertTrue(container.removeItem(last)); - Assert.assertNotSame(last, container.lastItemId()); - } - - @Test - public void isFirstId_freeformFirstItemRemoved_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object first = container.firstItemId(); - Assert.assertTrue(container.removeItem(first)); - Assert.assertFalse(container.isFirstId(first)); - } - - @Test - public void isFirstId_freeformAddedFirstItemRemoved_returnsFalse() - throws SQLException { - DataGenerator.createGarbage(connectionPool); - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM GARBAGE", connectionPool, "ID")); - Object first = container.addItem(); - container.addItem(); - Assert.assertSame(first, container.firstItemId()); - Assert.assertTrue(container.removeItem(first)); - Assert.assertFalse(container.isFirstId(first)); - } - - @Test - public void isLastId_freeformLastItemRemoved_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object last = container.lastItemId(); - Assert.assertTrue(container.removeItem(last)); - Assert.assertFalse(container.isLastId(last)); - } - - @Test - public void isLastId_freeformAddedLastItemRemoved_returnsFalse() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object last = container.addItem(); - Assert.assertSame(last, container.lastItemId()); - Assert.assertTrue(container.removeItem(last)); - Assert.assertFalse(container.isLastId(last)); - } - - @Test - public void indexOfId_freeformItemRemoved_returnsNegOne() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.getIdByIndex(2); - Assert.assertTrue(container.removeItem(id)); - Assert.assertEquals(-1, container.indexOfId(id)); - } - - @Test - public void indexOfId_freeformAddedItemRemoved_returnsNegOne() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - Assert.assertTrue(container.indexOfId(id) != -1); - Assert.assertTrue(container.removeItem(id)); - Assert.assertEquals(-1, container.indexOfId(id)); - } - - @Test - public void getIdByIndex_freeformItemRemoved_resultChanges() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.getIdByIndex(2); - Assert.assertTrue(container.removeItem(id)); - Assert.assertNotSame(id, container.getIdByIndex(2)); - } - - @Test - public void getIdByIndex_freeformAddedItemRemoved_resultChanges() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object id = container.addItem(); - container.addItem(); - int index = container.indexOfId(id); - Assert.assertTrue(container.removeItem(id)); - Assert.assertNotSame(id, container.getIdByIndex(index)); - } - - @Test - public void removeAllItems_freeform_shouldSucceed() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertTrue(container.removeAllItems()); - Assert.assertEquals(0, container.size()); - } - - @Test - public void removeAllItems_freeformAddedItems_shouldSucceed() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addItem(); - container.addItem(); - Assert.assertTrue(container.removeAllItems()); - Assert.assertEquals(0, container.size()); - } - - @SuppressWarnings("unchecked") - @Test - public void commit_freeformAddedItem_shouldBeWrittenToDB() - throws SQLException { - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Integer>() { - @Override - public Integer answer() throws Throwable { - Connection conn = (Connection) EasyMock - .getCurrentArguments()[0]; - RowItem item = (RowItem) EasyMock - .getCurrentArguments()[1]; - Statement statement = conn.createStatement(); - if (SQLTestsConstants.db == DB.MSSQL) { - statement - .executeUpdate("insert into people values('" - + item.getItemProperty("NAME") - .getValue() - + "', '" - + item.getItemProperty("AGE") - .getValue() - + "')"); - } else { - statement.executeUpdate( - "insert into people values(default, '" - + item.getItemProperty("NAME") - .getValue() - + "', '" - + item.getItemProperty("AGE") - .getValue() - + "')"); - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - return 1; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT row_number() OVER" - + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN " + start - + " AND " + end; - return q; - } else if (SQLTestsConstants.db == DB.ORACLE) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " - + " WHERE r BETWEEN " + start + " AND " - + end; - return q; - } else { - return "SELECT * FROM people LIMIT " + limit - + " OFFSET " + offset; - } - } - }).anyTimes(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - query.setDelegate(delegate); - EasyMock.replay(delegate); - SQLContainer container = new SQLContainer(query); - Object id = container.addItem(); - container.getContainerProperty(id, "NAME").setValue("New Name"); - container.getContainerProperty(id, "AGE").setValue(30); - Assert.assertTrue(id instanceof TemporaryRowId); - Assert.assertSame(id, container.lastItemId()); - container.commit(); - Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); - Assert.assertEquals("New Name", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void commit_freeformTwoAddedItems_shouldBeWrittenToDB() - throws SQLException { - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Integer>() { - @Override - public Integer answer() throws Throwable { - Connection conn = (Connection) EasyMock - .getCurrentArguments()[0]; - RowItem item = (RowItem) EasyMock - .getCurrentArguments()[1]; - Statement statement = conn.createStatement(); - if (SQLTestsConstants.db == DB.MSSQL) { - statement - .executeUpdate("insert into people values('" - + item.getItemProperty("NAME") - .getValue() - + "', '" - + item.getItemProperty("AGE") - .getValue() - + "')"); - } else { - statement.executeUpdate( - "insert into people values(default, '" - + item.getItemProperty("NAME") - .getValue() - + "', '" - + item.getItemProperty("AGE") - .getValue() - + "')"); - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - return 1; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT row_number() OVER" - + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN " + start - + " AND " + end; - return q; - } else if (SQLTestsConstants.db == DB.ORACLE) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " - + " WHERE r BETWEEN " + start + " AND " - + end; - return q; - } else { - return "SELECT * FROM people LIMIT " + limit - + " OFFSET " + offset; - } - } - }).anyTimes(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - query.setDelegate(delegate); - EasyMock.replay(delegate); - SQLContainer container = new SQLContainer(query); - Object id = container.addItem(); - Object id2 = container.addItem(); - container.getContainerProperty(id, "NAME").setValue("Herbert"); - container.getContainerProperty(id, "AGE").setValue(30); - container.getContainerProperty(id2, "NAME").setValue("Larry"); - container.getContainerProperty(id2, "AGE").setValue(50); - Assert.assertTrue(id2 instanceof TemporaryRowId); - Assert.assertSame(id2, container.lastItemId()); - container.commit(); - Object nextToLast = container.getIdByIndex(container.size() - 2); - Assert.assertFalse(nextToLast instanceof TemporaryRowId); - Assert.assertEquals("Herbert", - container.getContainerProperty(nextToLast, "NAME").getValue()); - Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId); - Assert.assertEquals("Larry", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void commit_freeformRemovedItem_shouldBeRemovedFromDB() - throws SQLException { - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.removeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Boolean>() { - @Override - public Boolean answer() throws Throwable { - Connection conn = (Connection) EasyMock - .getCurrentArguments()[0]; - RowItem item = (RowItem) EasyMock - .getCurrentArguments()[1]; - Statement statement = conn.createStatement(); - statement.executeUpdate( - "DELETE FROM people WHERE \"ID\"=" + item - .getItemProperty("ID").getValue()); - statement.close(); - return true; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT row_number() OVER" - + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN " + start - + " AND " + end; - return q; - } else if (SQLTestsConstants.db == DB.ORACLE) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " - + " WHERE r BETWEEN " + start + " AND " - + end; - return q; - } else { - return "SELECT * FROM people LIMIT " + limit - + " OFFSET " + offset; - } - } - }).anyTimes(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - query.setDelegate(delegate); - EasyMock.replay(delegate); - SQLContainer container = new SQLContainer(query); - Object last = container.lastItemId(); - container.removeItem(last); - container.commit(); - Assert.assertFalse(last.equals(container.lastItemId())); - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void commit_freeformLastItemUpdated_shouldUpdateRowInDB() - throws SQLException { - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))).andAnswer(new IAnswer<Integer>() { - @Override - public Integer answer() throws Throwable { - Connection conn = (Connection) EasyMock - .getCurrentArguments()[0]; - RowItem item = (RowItem) EasyMock - .getCurrentArguments()[1]; - Statement statement = conn.createStatement(); - statement.executeUpdate("UPDATE people SET \"NAME\"='" - + item.getItemProperty("NAME").getValue() - + "' WHERE \"ID\"=" - + item.getItemProperty("ID").getValue()); - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - return 1; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT row_number() OVER" - + " ( ORDER BY \"ID\" ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN " + start - + " AND " + end; - return q; - } else if (SQLTestsConstants.db == DB.ORACLE) { - int start = offset + 1; - int end = offset + limit + 1; - String q = "SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people ORDER BY \"ID\" ASC) x) " - + " WHERE r BETWEEN " + start + " AND " - + end; - return q; - } else { - return "SELECT * FROM people LIMIT " + limit - + " OFFSET " + offset; - } - } - }).anyTimes(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - query.setDelegate(delegate); - EasyMock.replay(delegate); - SQLContainer container = new SQLContainer(query); - Object last = container.lastItemId(); - container.getContainerProperty(last, "NAME").setValue("Donald"); - container.commit(); - Assert.assertEquals("Donald", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - EasyMock.verify(delegate); - } - - @Test - public void rollback_freeformItemAdded_discardsAddedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - int size = container.size(); - Object id = container.addItem(); - container.getContainerProperty(id, "NAME").setValue("foo"); - Assert.assertEquals(size + 1, container.size()); - container.rollback(); - Assert.assertEquals(size, container.size()); - Assert.assertFalse("foo".equals( - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue())); - } - - @Test - public void rollback_freeformItemRemoved_restoresRemovedItem() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - int size = container.size(); - Object last = container.lastItemId(); - container.removeItem(last); - Assert.assertEquals(size - 1, container.size()); - container.rollback(); - Assert.assertEquals(size, container.size()); - Assert.assertEquals(last, container.lastItemId()); - } - - @Test - public void rollback_freeformItemChanged_discardsChanges() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Object last = container.lastItemId(); - container.getContainerProperty(last, "NAME").setValue("foo"); - container.rollback(); - Assert.assertFalse("foo".equals( - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue())); - } - - @Test - public void itemChangeNotification_freeform_isModifiedReturnsTrue() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertFalse(container.isModified()); - RowItem last = (RowItem) container.getItem(container.lastItemId()); - container.itemChangeNotification(last); - Assert.assertTrue(container.isModified()); - } - - @Test - public void itemSetChangeListeners_freeform_shouldFire() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - ItemSetChangeListener listener = EasyMock - .createMock(ItemSetChangeListener.class); - listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); - EasyMock.replay(listener); - - container.addListener(listener); - container.addItem(); - - EasyMock.verify(listener); - } - - @Test - public void itemSetChangeListeners_freeformItemRemoved_shouldFire() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - ItemSetChangeListener listener = EasyMock - .createMock(ItemSetChangeListener.class); - listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class)); - EasyMock.expectLastCall().anyTimes(); - EasyMock.replay(listener); - - container.addListener(listener); - container.removeItem(container.lastItemId()); - - EasyMock.verify(listener); - } - - @Test - public void removeListener_freeform_shouldNotFire() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - ItemSetChangeListener listener = EasyMock - .createMock(ItemSetChangeListener.class); - EasyMock.replay(listener); - - container.addListener(listener); - container.removeListener(listener); - container.addItem(); - - EasyMock.verify(listener); - } - - @Test - public void isModified_freeformRemovedItem_returnsTrue() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertFalse(container.isModified()); - container.removeItem(container.lastItemId()); - Assert.assertTrue(container.isModified()); - } - - @Test - public void isModified_freeformAddedItem_returnsTrue() throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertFalse(container.isModified()); - container.addItem(); - Assert.assertTrue(container.isModified()); - } - - @Test - public void isModified_freeformChangedItem_returnsTrue() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Assert.assertFalse(container.isModified()); - container.getContainerProperty(container.lastItemId(), "NAME") - .setValue("foo"); - Assert.assertTrue(container.isModified()); - } - - @Test - public void getSortableContainerPropertyIds_freeform_returnsAllPropertyIds() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - Collection<?> sortableIds = container.getSortableContainerPropertyIds(); - Assert.assertTrue(sortableIds.contains("ID")); - Assert.assertTrue(sortableIds.contains("NAME")); - Assert.assertTrue(sortableIds.contains("AGE")); - Assert.assertEquals(3, sortableIds.size()); - } - - @SuppressWarnings("unchecked") - @Test - public void addOrderBy_freeform_shouldReorderResults() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<OrderBy> orders = (List<OrderBy>) EasyMock - .getCurrentArguments()[0]; - orderBys.clear(); - orderBys.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - SQLGenerator gen = new MSSQLGenerator(); - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy("ID", true)); - return gen - .generateSelectQuery("people", null, ob, - offset, limit, null) - .getQueryString(); - } else { - return gen - .generateSelectQuery("people", null, - orderBys, offset, limit, null) - .getQueryString(); - } - } else if (SQLTestsConstants.db == DB.ORACLE) { - SQLGenerator gen = new OracleGenerator(); - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy("ID", true)); - return gen - .generateSelectQuery("people", null, ob, - offset, limit, null) - .getQueryString(); - } else { - return gen - .generateSelectQuery("people", null, - orderBys, offset, limit, null) - .getQueryString(); - } - } else { - StringBuffer query = new StringBuffer( - "SELECT * FROM people"); - if (!orderBys.isEmpty()) { - query.append(" ORDER BY "); - for (OrderBy orderBy : orderBys) { - query.append( - "\"" + orderBy.getColumn() + "\""); - if (orderBy.isAscending()) { - query.append(" ASC"); - } else { - query.append(" DESC"); - } - } - } - query.append(" LIMIT ").append(limit) - .append(" OFFSET ").append(offset); - return query.toString(); - } - } - }).anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals("Ville", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - container.addOrderBy(new OrderBy("NAME", true)); - // Börje, Kalle, Pelle, Ville - Assert.assertEquals("Börje", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - Assert.assertEquals("Ville", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @Test(expected = IllegalArgumentException.class) - public void addOrderBy_freeformIllegalColumn_shouldFail() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", connectionPool, "ID")); - container.addOrderBy(new OrderBy("asdf", true)); - } - - @SuppressWarnings("unchecked") - @Test - public void sort_freeform_sortsByName() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<OrderBy> orders = (List<OrderBy>) EasyMock - .getCurrentArguments()[0]; - orderBys.clear(); - orderBys.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - SQLGenerator gen = new MSSQLGenerator(); - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy("ID", true)); - return gen - .generateSelectQuery("people", null, ob, - offset, limit, null) - .getQueryString(); - } else { - return gen - .generateSelectQuery("people", null, - orderBys, offset, limit, null) - .getQueryString(); - } - } else if (SQLTestsConstants.db == DB.ORACLE) { - SQLGenerator gen = new OracleGenerator(); - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy("ID", true)); - return gen - .generateSelectQuery("people", null, ob, - offset, limit, null) - .getQueryString(); - } else { - return gen - .generateSelectQuery("people", null, - orderBys, offset, limit, null) - .getQueryString(); - } - } else { - StringBuffer query = new StringBuffer( - "SELECT * FROM people"); - if (!orderBys.isEmpty()) { - query.append(" ORDER BY "); - for (OrderBy orderBy : orderBys) { - query.append( - "\"" + orderBy.getColumn() + "\""); - if (orderBy.isAscending()) { - query.append(" ASC"); - } else { - query.append(" DESC"); - } - } - } - query.append(" LIMIT ").append(limit) - .append(" OFFSET ").append(offset); - return query.toString(); - } - } - }).anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - EasyMock.replay(delegate); - - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals("Ville", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - container.sort(new Object[] { "NAME" }, new boolean[] { true }); - - // Börje, Kalle, Pelle, Ville - Assert.assertEquals("Börje", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - Assert.assertEquals("Ville", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void addFilter_freeform_filtersResults() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - container.addContainerFilter(new Like("NAME", "%lle")); - // Ville, Kalle, Pelle - Assert.assertEquals(3, container.size()); - Assert.assertEquals("Pelle", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void addContainerFilter_filtersResults() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - - container.addContainerFilter("NAME", "Vi", false, false); - - // Ville - Assert.assertEquals(1, container.size()); - Assert.assertEquals("Ville", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void addContainerFilter_ignoreCase_filtersResults() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - - // FIXME LIKE %asdf% doesn't match a string that begins with asdf - container.addContainerFilter("NAME", "vi", true, true); - - // Ville - Assert.assertEquals(1, container.size()); - Assert.assertEquals("Ville", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void removeAllContainerFilters_freeform_noFiltering() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - - container.addContainerFilter("NAME", "Vi", false, false); - - // Ville - Assert.assertEquals(1, container.size()); - Assert.assertEquals("Ville", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - container.removeAllContainerFilters(); - - Assert.assertEquals(4, container.size()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void removeContainerFilters_freeform_noFiltering() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - - container.addContainerFilter("NAME", "Vi", false, true); - - // Ville - Assert.assertEquals(1, container.size()); - Assert.assertEquals("Ville", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - container.removeContainerFilters("NAME"); - - Assert.assertEquals(4, container.size()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void addFilter_freeformBufferedItems_alsoFiltersBufferedItems() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - Object id1 = container.addItem(); - container.getContainerProperty(id1, "NAME").setValue("Palle"); - Object id2 = container.addItem(); - container.getContainerProperty(id2, "NAME").setValue("Bengt"); - - container.addContainerFilter(new Like("NAME", "%lle")); - - // Ville, Kalle, Pelle, Palle - Assert.assertEquals(4, container.size()); - Assert.assertEquals("Ville", - container - .getContainerProperty(container.getIdByIndex(0), "NAME") - .getValue()); - Assert.assertEquals("Kalle", - container - .getContainerProperty(container.getIdByIndex(1), "NAME") - .getValue()); - Assert.assertEquals("Pelle", - container - .getContainerProperty(container.getIdByIndex(2), "NAME") - .getValue()); - Assert.assertEquals("Palle", - container - .getContainerProperty(container.getIdByIndex(3), "NAME") - .getValue()); - - try { - container.getIdByIndex(4); - Assert.fail( - "SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container"); - } catch (IndexOutOfBoundsException e) { - // should throw exception - item is filtered out - } - container.nextItemId(container.getIdByIndex(3)); - - Assert.assertFalse(container.containsId(id2)); - Assert.assertFalse(container.getItemIds().contains(id2)); - - Assert.assertNull(container.getItem(id2)); - Assert.assertEquals(-1, container.indexOfId(id2)); - - Assert.assertNotSame(id2, container.lastItemId()); - Assert.assertSame(id1, container.lastItemId()); - - EasyMock.verify(delegate); - } - - @SuppressWarnings("unchecked") - @Test - public void sort_freeformBufferedItems_sortsBufferedItemsLastInOrderAdded() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - connectionPool, "ID"); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - final ArrayList<OrderBy> orderBys = new ArrayList<OrderBy>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<OrderBy> orders = (List<OrderBy>) EasyMock - .getCurrentArguments()[0]; - orderBys.clear(); - orderBys.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect( - delegate.getQueryString(EasyMock.anyInt(), EasyMock.anyInt())) - .andAnswer(new IAnswer<String>() { - @Override - public String answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - if (SQLTestsConstants.db == DB.MSSQL) { - SQLGenerator gen = new MSSQLGenerator(); - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy("ID", true)); - return gen - .generateSelectQuery("people", null, ob, - offset, limit, null) - .getQueryString(); - } else { - return gen - .generateSelectQuery("people", null, - orderBys, offset, limit, null) - .getQueryString(); - } - } else if (SQLTestsConstants.db == DB.ORACLE) { - SQLGenerator gen = new OracleGenerator(); - if (orderBys == null || orderBys.isEmpty()) { - List<OrderBy> ob = new ArrayList<OrderBy>(); - ob.add(new OrderBy("ID", true)); - return gen - .generateSelectQuery("people", null, ob, - offset, limit, null) - .getQueryString(); - } else { - return gen - .generateSelectQuery("people", null, - orderBys, offset, limit, null) - .getQueryString(); - } - } else { - StringBuffer query = new StringBuffer( - "SELECT * FROM people"); - if (!orderBys.isEmpty()) { - query.append(" ORDER BY "); - for (OrderBy orderBy : orderBys) { - query.append( - "\"" + orderBy.getColumn() + "\""); - if (orderBy.isAscending()) { - query.append(" ASC"); - } else { - query.append(" DESC"); - } - } - } - query.append(" LIMIT ").append(limit) - .append(" OFFSET ").append(offset); - return query.toString(); - } - } - }).anyTimes(); - EasyMock.expect(delegate.getCountQuery()) - .andThrow(new UnsupportedOperationException()).anyTimes(); - EasyMock.replay(delegate); - - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals("Ville", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - Object id1 = container.addItem(); - container.getContainerProperty(id1, "NAME").setValue("Wilbert"); - Object id2 = container.addItem(); - container.getContainerProperty(id2, "NAME").setValue("Albert"); - - container.sort(new Object[] { "NAME" }, new boolean[] { true }); - - // Börje, Kalle, Pelle, Ville, Wilbert, Albert - Assert.assertEquals("Börje", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - Assert.assertEquals("Wilbert", - container.getContainerProperty( - container.getIdByIndex(container.size() - 2), "NAME") - .getValue()); - Assert.assertEquals("Albert", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - EasyMock.verify(delegate); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java deleted file mode 100755 index 3718cf756d..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.data.util.sqlcontainer; - -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.OracleGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; - -public class SQLTestsConstants { - - /* Set the DB used for testing here! */ - public enum DB { - HSQLDB, MYSQL, POSTGRESQL, MSSQL, ORACLE; - } - - /* 0 = HSQLDB, 1 = MYSQL, 2 = POSTGRESQL, 3 = MSSQL, 4 = ORACLE */ - public static final DB db = DB.HSQLDB; - - /* Auto-increment column offset (HSQLDB = 0, MYSQL = 1, POSTGRES = 1) */ - public static int offset; - /* Garbage table creation query (=three queries for oracle) */ - public static String createGarbage; - public static String createGarbageSecond; - public static String createGarbageThird; - /* DB Drivers, urls, usernames and passwords */ - public static String dbDriver; - public static String dbURL; - public static String dbUser; - public static String dbPwd; - /* People -test table creation statement(s) */ - public static String peopleFirst; - public static String peopleSecond; - public static String peopleThird; - /* Schema test creation statement(s) */ - public static String createSchema; - public static String createProductTable; - public static String dropSchema; - /* Versioned -test table createion statement(s) */ - public static String[] versionStatements; - /* SQL Generator used during the testing */ - public static SQLGenerator sqlGen; - - /* Set DB-specific settings based on selected DB */ - static { - sqlGen = new DefaultSQLGenerator(); - switch (db) { - case HSQLDB: - offset = 0; - createGarbage = "create table garbage (id integer generated always as identity, type varchar(32), PRIMARY KEY(id))"; - dbDriver = "org.hsqldb.jdbc.JDBCDriver"; - dbURL = "jdbc:hsqldb:mem:sqlcontainer"; - dbUser = "SA"; - dbPwd = ""; - peopleFirst = "create table people (id integer generated always as identity, name varchar(32), AGE INTEGER)"; - peopleSecond = "alter table people add primary key (id)"; - versionStatements = new String[] { - "create table versioned (id integer generated always as identity, text varchar(255), version tinyint default 0)", - "alter table versioned add primary key (id)" }; - // TODO these should ideally exist for all databases - createSchema = "create schema oaas authorization DBA"; - createProductTable = "create table oaas.product (\"ID\" integer generated always as identity primary key, \"NAME\" VARCHAR(32))"; - dropSchema = "drop schema if exists oaas cascade"; - break; - case MYSQL: - offset = 1; - createGarbage = "create table GARBAGE (ID integer auto_increment, type varchar(32), PRIMARY KEY(ID))"; - dbDriver = "com.mysql.jdbc.Driver"; - dbURL = "jdbc:mysql:///sqlcontainer"; - dbUser = "sqlcontainer"; - dbPwd = "sqlcontainer"; - peopleFirst = "create table PEOPLE (ID integer auto_increment not null, NAME varchar(32), AGE INTEGER, primary key(ID))"; - peopleSecond = null; - versionStatements = new String[] { - "create table VERSIONED (ID integer auto_increment not null, TEXT varchar(255), VERSION tinyint default 0, primary key(ID))", - "CREATE TRIGGER upd_version BEFORE UPDATE ON VERSIONED" - + " FOR EACH ROW SET NEW.VERSION = OLD.VERSION+1" }; - break; - case POSTGRESQL: - offset = 1; - createGarbage = "create table GARBAGE (\"ID\" serial PRIMARY KEY, \"TYPE\" varchar(32))"; - dbDriver = "org.postgresql.Driver"; - dbURL = "jdbc:postgresql://localhost:5432/test"; - dbUser = "postgres"; - dbPwd = "postgres"; - peopleFirst = "create table PEOPLE (\"ID\" serial primary key, \"NAME\" VARCHAR(32), \"AGE\" INTEGER)"; - peopleSecond = null; - versionStatements = new String[] { - "create table VERSIONED (\"ID\" serial primary key, \"TEXT\" VARCHAR(255), \"VERSION\" INTEGER DEFAULT 0)", - "CREATE OR REPLACE FUNCTION zz_row_version() RETURNS TRIGGER AS $$" - + "BEGIN" + " IF TG_OP = 'UPDATE'" - + " AND NEW.\"VERSION\" = old.\"VERSION\"" - + " AND ROW(NEW.*) IS DISTINCT FROM ROW (old.*)" - + " THEN" - + " NEW.\"VERSION\" := NEW.\"VERSION\" + 1;" - + " END IF;" + " RETURN NEW;" + "END;" - + "$$ LANGUAGE plpgsql;", - "CREATE TRIGGER \"mytable_modify_dt_tr\" BEFORE UPDATE" - + " ON VERSIONED FOR EACH ROW" - + " EXECUTE PROCEDURE \"public\".\"zz_row_version\"();" }; - createSchema = "create schema oaas"; - createProductTable = "create table oaas.product (\"ID\" serial primary key, \"NAME\" VARCHAR(32))"; - dropSchema = "drop schema oaas cascade"; - break; - case MSSQL: - offset = 1; - createGarbage = "create table GARBAGE (\"ID\" int identity(1,1) primary key, \"TYPE\" varchar(32))"; - dbDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; - dbURL = "jdbc:sqlserver://localhost:1433;databaseName=tempdb;"; - dbUser = "sa"; - dbPwd = "sa"; - peopleFirst = "create table PEOPLE (\"ID\" int identity(1,1) primary key, \"NAME\" VARCHAR(32), \"AGE\" INTEGER)"; - peopleSecond = null; - versionStatements = new String[] { - "create table VERSIONED (\"ID\" int identity(1,1) primary key, \"TEXT\" VARCHAR(255), \"VERSION\" rowversion not null)" }; - sqlGen = new MSSQLGenerator(); - break; - case ORACLE: - offset = 1; - createGarbage = "create table GARBAGE (\"ID\" integer primary key, \"TYPE\" varchar2(32))"; - createGarbageSecond = "create sequence garbage_seq start with 1 increment by 1 nomaxvalue"; - createGarbageThird = "create trigger garbage_trigger before insert on GARBAGE for each row begin select garbage_seq.nextval into :new.ID from dual; end;"; - dbDriver = "oracle.jdbc.OracleDriver"; - dbURL = "jdbc:oracle:thin:test/test@localhost:1521:XE"; - dbUser = "test"; - dbPwd = "test"; - peopleFirst = "create table PEOPLE (\"ID\" integer primary key, \"NAME\" VARCHAR2(32), \"AGE\" INTEGER)"; - peopleSecond = "create sequence people_seq start with 1 increment by 1 nomaxvalue"; - peopleThird = "create trigger people_trigger before insert on PEOPLE for each row begin select people_seq.nextval into :new.ID from dual; end;"; - versionStatements = new String[] { - "create table VERSIONED (\"ID\" integer primary key, \"TEXT\" VARCHAR(255), \"VERSION\" INTEGER DEFAULT 0)", - "create sequence versioned_seq start with 1 increment by 1 nomaxvalue", - "create trigger versioned_trigger before insert on VERSIONED for each row begin select versioned_seq.nextval into :new.ID from dual; end;", - "create sequence versioned_version start with 1 increment by 1 nomaxvalue", - "create trigger versioned_version_trigger before insert or update on VERSIONED for each row begin select versioned_version.nextval into :new.VERSION from dual; end;" }; - sqlGen = new OracleGenerator(); - break; - } - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTest.java deleted file mode 100644 index 1a19eda542..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/TicketTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import java.math.BigDecimal; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.easymock.EasyMock; -import org.easymock.IAnswer; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.Item; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; -import com.vaadin.data.util.sqlcontainer.query.FreeformStatementDelegate; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; -import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; -import com.vaadin.ui.Table; -import com.vaadin.ui.Window; - -public class TicketTest { - - private JDBCConnectionPool connectionPool; - - @Before - public void setUp() throws SQLException { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - DataGenerator.addPeopleToDatabase(connectionPool); - } - - @Test - public void ticket5867_throwsIllegalState_transactionAlreadyActive() - throws SQLException { - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people", Arrays.asList("ID"), connectionPool)); - Table table = new Table(); - Window w = new Window(); - w.setContent(table); - table.setContainerDataSource(container); - } - - @SuppressWarnings("unchecked") - @Test - public void ticket6136_freeform_ageIs18() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformStatementDelegate delegate = EasyMock - .createMock(FreeformStatementDelegate.class); - final ArrayList<Filter> filters = new ArrayList<Filter>(); - delegate.setFilters(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(EasyMock.isA(List.class)); - EasyMock.expectLastCall().anyTimes(); - delegate.setOrderBy(null); - EasyMock.expectLastCall().anyTimes(); - delegate.setFilters(EasyMock.isA(List.class)); - EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { - @Override - public Object answer() throws Throwable { - List<Filter> orders = (List<Filter>) EasyMock - .getCurrentArguments()[0]; - filters.clear(); - filters.addAll(orders); - return null; - } - }).anyTimes(); - EasyMock.expect(delegate.getQueryStatement(EasyMock.anyInt(), - EasyMock.anyInt())).andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - Object[] args = EasyMock.getCurrentArguments(); - int offset = (Integer) (args[0]); - int limit = (Integer) (args[1]); - return FreeformQueryUtil.getQueryWithFilters(filters, - offset, limit); - } - }).anyTimes(); - EasyMock.expect(delegate.getCountStatement()) - .andAnswer(new IAnswer<StatementHelper>() { - @Override - public StatementHelper answer() throws Throwable { - StatementHelper sh = new StatementHelper(); - StringBuffer query = new StringBuffer( - "SELECT COUNT(*) FROM people"); - if (!filters.isEmpty()) { - query.append(QueryBuilder - .getWhereStringForFilters(filters, sh)); - } - sh.setQueryString(query.toString()); - return sh; - } - }).anyTimes(); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - Assert.assertEquals("Börje", - container.getContainerProperty(container.lastItemId(), "NAME") - .getValue()); - - container.addContainerFilter(new Equal("AGE", 18)); - // Pelle - Assert.assertEquals(1, container.size()); - Assert.assertEquals("Pelle", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals(new BigDecimal(18), container - .getContainerProperty(container.firstItemId(), "AGE") - .getValue()); - } else { - Assert.assertEquals(18, container - .getContainerProperty(container.firstItemId(), "AGE") - .getValue()); - } - - EasyMock.verify(delegate); - } - - @Test - public void ticket6136_table_ageIs18() throws SQLException { - TableQuery query = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - SQLContainer container = new SQLContainer(query); - // Ville, Kalle, Pelle, Börje - Assert.assertEquals(4, container.size()); - - container.addContainerFilter(new Equal("AGE", 18)); - - // Pelle - Assert.assertEquals(1, container.size()); - Assert.assertEquals("Pelle", - container.getContainerProperty(container.firstItemId(), "NAME") - .getValue()); - if (SQLTestsConstants.db == DB.ORACLE) { - Assert.assertEquals(new BigDecimal(18), container - .getContainerProperty(container.firstItemId(), "AGE") - .getValue()); - } else { - Assert.assertEquals(18, container - .getContainerProperty(container.firstItemId(), "AGE") - .getValue()); - } - } - - @Test - public void ticket7434_getItem_Modified_Changed_Unchanged() - throws SQLException { - SQLContainer container = new SQLContainer(new TableQuery("people", - connectionPool, SQLTestsConstants.sqlGen)); - - Object id = container.firstItemId(); - Item item = container.getItem(id); - String name = (String) item.getItemProperty("NAME").getValue(); - - // set a different name - item.getItemProperty("NAME").setValue("otherName"); - Assert.assertEquals("otherName", - item.getItemProperty("NAME").getValue()); - - // access the item and reset the name to its old value - Item item2 = container.getItem(id); - item2.getItemProperty("NAME").setValue(name); - Assert.assertEquals(name, item2.getItemProperty("NAME").getValue()); - - Item item3 = container.getItem(id); - String name3 = (String) item3.getItemProperty("NAME").getValue(); - - Assert.assertEquals(name, name3); - } - - @Test - public void ticket10032_empty_set_metadata_correctly_handled() - throws SQLException { - // If problem exists will break when method getPropertyIds() - // is called in constructor SQLContainer(QueryDelegate delegate). - SQLContainer container = new SQLContainer(new FreeformQuery( - "SELECT * FROM people WHERE name='does_not_exist'", - Arrays.asList("ID"), connectionPool)); - Assert.assertTrue("Got items while expected empty set", - container.size() == 0); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java deleted file mode 100644 index a575d649f1..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/UtilTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.vaadin.data.util.sqlcontainer; - -import org.junit.Assert; -import org.junit.Test; - -public class UtilTest { - - @Test - public void escapeSQL_noQuotes_returnsSameString() { - Assert.assertEquals("asdf", SQLUtil.escapeSQL("asdf")); - } - - @Test - public void escapeSQL_singleQuotes_returnsEscapedString() { - Assert.assertEquals("O''Brien", SQLUtil.escapeSQL("O'Brien")); - } - - @Test - public void escapeSQL_severalQuotes_returnsEscapedString() { - Assert.assertEquals("asdf''ghjk''qwerty", - SQLUtil.escapeSQL("asdf'ghjk'qwerty")); - } - - @Test - public void escapeSQL_doubleQuotes_returnsEscapedString() { - Assert.assertEquals("asdf\\\"foo", SQLUtil.escapeSQL("asdf\"foo")); - } - - @Test - public void escapeSQL_multipleDoubleQuotes_returnsEscapedString() { - Assert.assertEquals("asdf\\\"foo\\\"bar", - SQLUtil.escapeSQL("asdf\"foo\"bar")); - } - - @Test - public void escapeSQL_backslashes_returnsEscapedString() { - Assert.assertEquals("foo\\\\nbar\\\\r", - SQLUtil.escapeSQL("foo\\nbar\\r")); - } - - @Test - public void escapeSQL_x00_removesX00() { - Assert.assertEquals("foobar", SQLUtil.escapeSQL("foo\\x00bar")); - } - - @Test - public void escapeSQL_x1a_removesX1a() { - Assert.assertEquals("foobar", SQLUtil.escapeSQL("foo\\x1abar")); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java deleted file mode 100644 index 1463a27217..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPoolTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.connection; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.naming.Context; -import javax.naming.NamingException; -import javax.sql.DataSource; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; - -public class J2EEConnectionPoolTest { - - @Test - public void reserveConnection_dataSourceSpecified_shouldReturnValidConnection() - throws SQLException { - Connection connection = EasyMock.createMock(Connection.class); - connection.setAutoCommit(false); - EasyMock.expectLastCall(); - DataSource ds = EasyMock.createMock(DataSource.class); - ds.getConnection(); - EasyMock.expectLastCall().andReturn(connection); - EasyMock.replay(connection, ds); - - J2EEConnectionPool pool = new J2EEConnectionPool(ds); - Connection c = pool.reserveConnection(); - Assert.assertEquals(connection, c); - EasyMock.verify(connection, ds); - } - - @Test - public void releaseConnection_shouldCloseConnection() throws SQLException { - Connection connection = EasyMock.createMock(Connection.class); - connection.setAutoCommit(false); - EasyMock.expectLastCall(); - connection.close(); - EasyMock.expectLastCall(); - DataSource ds = EasyMock.createMock(DataSource.class); - ds.getConnection(); - EasyMock.expectLastCall().andReturn(connection); - EasyMock.replay(connection, ds); - - J2EEConnectionPool pool = new J2EEConnectionPool(ds); - Connection c = pool.reserveConnection(); - Assert.assertEquals(connection, c); - pool.releaseConnection(c); - EasyMock.verify(connection, ds); - } - - @Test - public void reserveConnection_dataSourceLookedUp_shouldReturnValidConnection() - throws SQLException, NamingException { - Connection connection = EasyMock.createMock(Connection.class); - connection.setAutoCommit(false); - EasyMock.expectLastCall(); - connection.close(); - EasyMock.expectLastCall(); - - DataSource ds = EasyMock.createMock(DataSource.class); - ds.getConnection(); - EasyMock.expectLastCall().andReturn(connection); - - System.setProperty("java.naming.factory.initial", - "com.vaadin.data.util.sqlcontainer.connection.MockInitialContextFactory"); - Context context = EasyMock.createMock(Context.class); - context.lookup("testDataSource"); - EasyMock.expectLastCall().andReturn(ds); - MockInitialContextFactory.setMockContext(context); - - EasyMock.replay(context, connection, ds); - - J2EEConnectionPool pool = new J2EEConnectionPool("testDataSource"); - Connection c = pool.reserveConnection(); - Assert.assertEquals(connection, c); - pool.releaseConnection(c); - EasyMock.verify(context, connection, ds); - } - - @Test(expected = SQLException.class) - public void reserveConnection_nonExistantDataSourceLookedUp_shouldFail() - throws SQLException, NamingException { - System.setProperty("java.naming.factory.initial", - "com.vaadin.addon.sqlcontainer.connection.MockInitialContextFactory"); - Context context = EasyMock.createMock(Context.class); - context.lookup("foo"); - EasyMock.expectLastCall().andThrow(new NamingException("fail")); - MockInitialContextFactory.setMockContext(context); - - EasyMock.replay(context); - - J2EEConnectionPool pool = new J2EEConnectionPool("foo"); - pool.reserveConnection(); - EasyMock.verify(context); - } - - @Test - public void releaseConnection_null_shouldSucceed() throws SQLException { - DataSource ds = EasyMock.createMock(DataSource.class); - EasyMock.replay(ds); - - J2EEConnectionPool pool = new J2EEConnectionPool(ds); - pool.releaseConnection(null); - EasyMock.verify(ds); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java deleted file mode 100644 index 1c70c8dad7..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/MockInitialContextFactory.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.connection; - -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.spi.InitialContextFactory; - -import org.junit.Test; - -/** - * Provides a JNDI initial context factory for the MockContext. - */ -public class MockInitialContextFactory implements InitialContextFactory { - private static Context mockCtx = null; - - public static void setMockContext(Context ctx) { - mockCtx = ctx; - } - - @Override - public Context getInitialContext(java.util.Hashtable<?, ?> environment) - throws NamingException { - if (mockCtx == null) { - throw new IllegalStateException("mock context was not set."); - } - return mockCtx; - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java deleted file mode 100644 index 5a6ae78aeb..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPoolTest.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.connection; - -import java.sql.Connection; -import java.sql.SQLException; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; -import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; - -public class SimpleJDBCConnectionPoolTest { - private JDBCConnectionPool connectionPool; - - @Before - public void setUp() throws SQLException { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - } - - @Test - public void reserveConnection_reserveNewConnection_returnsConnection() - throws SQLException { - Connection conn = connectionPool.reserveConnection(); - Assert.assertNotNull(conn); - } - - @Test - public void releaseConnection_releaseUnused_shouldNotThrowException() - throws SQLException { - Connection conn = connectionPool.reserveConnection(); - connectionPool.releaseConnection(conn); - Assert.assertFalse(conn.isClosed()); - } - - @Test(expected = SQLException.class) - public void reserveConnection_noConnectionsLeft_shouldFail() - throws SQLException { - try { - connectionPool.reserveConnection(); - connectionPool.reserveConnection(); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail( - "Exception before all connections used! " + e.getMessage()); - } - - connectionPool.reserveConnection(); - Assert.fail( - "Reserving connection didn't fail even though no connections are available!"); - } - - @Test - public void reserveConnection_oneConnectionLeft_returnsConnection() - throws SQLException { - try { - connectionPool.reserveConnection(); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail( - "Exception before all connections used! " + e.getMessage()); - } - - Connection conn = connectionPool.reserveConnection(); - Assert.assertNotNull(conn); - } - - @Test - public void reserveConnection_oneConnectionJustReleased_returnsConnection() - throws SQLException { - Connection conn2 = null; - try { - connectionPool.reserveConnection(); - conn2 = connectionPool.reserveConnection(); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail( - "Exception before all connections used! " + e.getMessage()); - } - - connectionPool.releaseConnection(conn2); - - connectionPool.reserveConnection(); - } - - @Test(expected = IllegalArgumentException.class) - public void construct_allParametersNull_shouldFail() throws SQLException { - SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool(null, null, - null, null); - } - - @Test(expected = IllegalArgumentException.class) - public void construct_onlyDriverNameGiven_shouldFail() throws SQLException { - SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, null, null, null); - } - - @Test(expected = IllegalArgumentException.class) - public void construct_onlyDriverNameAndUrlGiven_shouldFail() - throws SQLException { - SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, null, - null); - } - - @Test(expected = IllegalArgumentException.class) - public void construct_onlyDriverNameAndUrlAndUserGiven_shouldFail() - throws SQLException { - SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, null); - } - - @Test(expected = RuntimeException.class) - public void construct_nonExistingDriver_shouldFail() throws SQLException { - SimpleJDBCConnectionPool cp = new SimpleJDBCConnectionPool("foo", - SQLTestsConstants.dbURL, SQLTestsConstants.dbUser, - SQLTestsConstants.dbPwd); - } - - @Test - public void reserveConnection_newConnectionOpened_shouldSucceed() - throws SQLException { - connectionPool = new SimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 0, 2); - Connection c = connectionPool.reserveConnection(); - Assert.assertNotNull(c); - } - - @Test - public void releaseConnection_nullConnection_shouldDoNothing() { - connectionPool.releaseConnection(null); - } - - @Test - public void releaseConnection_failingRollback_shouldCallClose() - throws SQLException { - Connection c = EasyMock.createMock(Connection.class); - c.getAutoCommit(); - EasyMock.expectLastCall().andReturn(false); - c.rollback(); - EasyMock.expectLastCall().andThrow(new SQLException("Rollback failed")); - c.close(); - EasyMock.expectLastCall().atLeastOnce(); - EasyMock.replay(c); - // make sure the connection pool is initialized - // Bypass validation - JDBCConnectionPool realPool = ((ValidatingSimpleJDBCConnectionPool) connectionPool) - .getRealPool(); - realPool.reserveConnection(); - realPool.releaseConnection(c); - EasyMock.verify(c); - } - - @Test - public void destroy_shouldCloseAllConnections() throws SQLException { - Connection c1 = connectionPool.reserveConnection(); - Connection c2 = connectionPool.reserveConnection(); - try { - connectionPool.destroy(); - } catch (RuntimeException e) { - // The test connection pool throws an exception when the pool was - // not empty but only after cleanup of the real pool has been done - } - - Assert.assertTrue(c1.isClosed()); - Assert.assertTrue(c2.isClosed()); - } - - @Test - public void destroy_shouldCloseAllConnections2() throws SQLException { - Connection c1 = connectionPool.reserveConnection(); - Connection c2 = connectionPool.reserveConnection(); - connectionPool.releaseConnection(c1); - connectionPool.releaseConnection(c2); - connectionPool.destroy(); - Assert.assertTrue(c1.isClosed()); - Assert.assertTrue(c2.isClosed()); - } - -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java deleted file mode 100644 index 41db88b881..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/BetweenTest.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.filters; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.filter.Between; - -public class BetweenTest { - - private Item itemWithPropertyValue(Object propertyId, Object value) { - Property<?> property = EasyMock.createMock(Property.class); - property.getValue(); - EasyMock.expectLastCall().andReturn(value).anyTimes(); - EasyMock.replay(property); - - Item item = EasyMock.createMock(Item.class); - item.getItemProperty(propertyId); - EasyMock.expectLastCall().andReturn(property).anyTimes(); - EasyMock.replay(item); - return item; - } - - @Test - public void passesFilter_valueIsInRange_shouldBeTrue() { - Item item = itemWithPropertyValue("foo", 15); - Between between = new Between("foo", 1, 30); - Assert.assertTrue(between.passesFilter("foo", item)); - } - - @Test - public void passesFilter_valueIsOutOfRange_shouldBeFalse() { - Item item = itemWithPropertyValue("foo", 15); - Between between = new Between("foo", 0, 2); - Assert.assertFalse(between.passesFilter("foo", item)); - } - - @Test - public void passesFilter_valueNotComparable_shouldBeFalse() { - Item item = itemWithPropertyValue("foo", new Object()); - Between between = new Between("foo", 0, 2); - Assert.assertFalse(between.passesFilter("foo", item)); - } - - @Test - public void appliesToProperty_differentProperties_shoudlBeFalse() { - Between between = new Between("foo", 0, 2); - Assert.assertFalse(between.appliesToProperty("bar")); - } - - @Test - public void appliesToProperty_sameProperties_shouldBeTrue() { - Between between = new Between("foo", 0, 2); - Assert.assertTrue(between.appliesToProperty("foo")); - } - - @Test - public void hashCode_equalInstances_shouldBeEqual() { - Between b1 = new Between("foo", 0, 2); - Between b2 = new Between("foo", 0, 2); - Assert.assertEquals(b1.hashCode(), b2.hashCode()); - } - - @Test - public void equals_differentObjects_shouldBeFalse() { - Between b1 = new Between("foo", 0, 2); - Object obj = new Object(); - Assert.assertFalse(b1.equals(obj)); - } - - @Test - public void equals_sameInstance_shouldBeTrue() { - Between b1 = new Between("foo", 0, 2); - Between b2 = b1; - Assert.assertTrue(b1.equals(b2)); - } - - @Test - public void equals_equalInstances_shouldBeTrue() { - Between b1 = new Between("foo", 0, 2); - Between b2 = new Between("foo", 0, 2); - Assert.assertTrue(b1.equals(b2)); - } - - @Test - public void equals_equalInstances2_shouldBeTrue() { - Between b1 = new Between(null, null, null); - Between b2 = new Between(null, null, null); - Assert.assertTrue(b1.equals(b2)); - } - - @Test - public void equals_secondValueDiffers_shouldBeFalse() { - Between b1 = new Between("foo", 0, 1); - Between b2 = new Between("foo", 0, 2); - Assert.assertFalse(b1.equals(b2)); - } - - @Test - public void equals_firstAndSecondValueDiffers_shouldBeFalse() { - Between b1 = new Between("foo", 0, null); - Between b2 = new Between("foo", 1, 2); - Assert.assertFalse(b1.equals(b2)); - } - - @Test - public void equals_propertyAndFirstAndSecondValueDiffers_shouldBeFalse() { - Between b1 = new Between("foo", null, 1); - Between b2 = new Between("bar", 1, 2); - Assert.assertFalse(b1.equals(b2)); - } - - @Test - public void equals_propertiesDiffer_shouldBeFalse() { - Between b1 = new Between(null, 0, 1); - Between b2 = new Between("bar", 0, 1); - Assert.assertFalse(b1.equals(b2)); - } - - @Test - public void hashCode_nullStartValue_shouldBeEqual() { - Between b1 = new Between("foo", null, 2); - Between b2 = new Between("foo", null, 2); - Assert.assertEquals(b1.hashCode(), b2.hashCode()); - } - - @Test - public void hashCode_nullEndValue_shouldBeEqual() { - Between b1 = new Between("foo", 0, null); - Between b2 = new Between("foo", 0, null); - Assert.assertEquals(b1.hashCode(), b2.hashCode()); - } - - @Test - public void hashCode_nullPropertyId_shouldBeEqual() { - Between b1 = new Between(null, 0, 2); - Between b2 = new Between(null, 0, 2); - Assert.assertEquals(b1.hashCode(), b2.hashCode()); - } - - @Test - public void passesFilter_nullValue_filterIsPassed() { - String id = "id"; - Between between = new Between(id, null, null); - Assert.assertTrue( - between.passesFilter(id, itemWithPropertyValue(id, null))); - } - - @Test - public void passesFilter_nullStartValue_filterIsPassed() { - String id = "id"; - Between between = new Between(id, null, 2); - Assert.assertTrue( - between.passesFilter(id, itemWithPropertyValue(id, 1))); - } - - @Test - public void passesFilter_nullEndValue_filterIsPassed() { - String id = "id"; - Between between = new Between(id, 0, null); - Assert.assertTrue( - between.passesFilter(id, itemWithPropertyValue(id, 1))); - } - - @Test - public void passesFilter_nullStartValueAndEndValue_filterIsPassed() { - String id = "id"; - Between between = new Between(id, null, null); - Assert.assertTrue( - between.passesFilter(id, itemWithPropertyValue(id, 1))); - } - - @Test - public void passesFilter_nullStartValueAndEndValueAndValueIsNotComparable_filterIsNotPassed() { - String id = "id"; - Between between = new Between(id, null, null); - Assert.assertFalse(between.passesFilter(id, - itemWithPropertyValue(id, new Object()))); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java deleted file mode 100644 index a6b6f4b55c..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.data.util.sqlcontainer.filters; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.util.filter.Compare; - -public class CompareTest { - - @Test - public void testEquals() { - Compare c1 = new Compare.Equal("prop1", "val1"); - Compare c2 = new Compare.Equal("prop1", "val1"); - Assert.assertTrue(c1.equals(c2)); - } - - @Test - public void testDifferentTypeEquals() { - Compare c1 = new Compare.Equal("prop1", "val1"); - Compare c2 = new Compare.Greater("prop1", "val1"); - Assert.assertFalse(c1.equals(c2)); - } - - @Test - public void testEqualsNull() { - Compare c1 = new Compare.Equal("prop1", "val1"); - Assert.assertFalse(c1.equals(null)); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java deleted file mode 100644 index f1130aad80..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/filters/LikeTest.java +++ /dev/null @@ -1,229 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.filters; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Item; -import com.vaadin.data.util.ObjectProperty; -import com.vaadin.data.util.PropertysetItem; -import com.vaadin.data.util.filter.Like; - -public class LikeTest { - - @Test - public void passesFilter_valueIsNotStringType_shouldFail() { - Like like = new Like("test", "%foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<Integer>(5)); - - Assert.assertFalse(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_containsLikeQueryOnStringContainingValue_shouldSucceed() { - Like like = new Like("test", "%foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("asdfooghij")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_containsLikeQueryOnStringContainingValueCaseInsensitive_shouldSucceed() { - Like like = new Like("test", "%foo%"); - like.setCaseSensitive(false); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("asdfOOghij")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_containsLikeQueryOnStringContainingValueConstructedCaseInsensitive_shouldSucceed() { - Like like = new Like("test", "%foo%", false); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("asdfOOghij")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_containsLikeQueryOnStringNotContainingValue_shouldFail() { - Like like = new Like("test", "%foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("asdbarghij")); - - Assert.assertFalse(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_containsLikeQueryOnStringExactlyEqualToValue_shouldSucceed() { - Like like = new Like("test", "%foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("foo")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_containsLikeQueryOnStringEqualToValueMinusOneCharAtTheEnd_shouldFail() { - Like like = new Like("test", "%foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("fo")); - - Assert.assertFalse(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_beginsWithLikeQueryOnStringBeginningWithValue_shouldSucceed() { - Like like = new Like("test", "foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("foobar")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_beginsWithLikeQueryOnStringNotBeginningWithValue_shouldFail() { - Like like = new Like("test", "foo%"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("barfoo")); - - Assert.assertFalse(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_endsWithLikeQueryOnStringEndingWithValue_shouldSucceed() { - Like like = new Like("test", "%foo"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("barfoo")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_endsWithLikeQueryOnStringNotEndingWithValue_shouldFail() { - Like like = new Like("test", "%foo"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("foobar")); - - Assert.assertFalse(like.passesFilter("id", item)); - } - - @Test - public void passesFilter_startsWithAndEndsWithOnMatchingValue_shouldSucceed() { - Like like = new Like("test", "foo%bar"); - - Item item = new PropertysetItem(); - item.addItemProperty("test", new ObjectProperty<String>("fooASDFbar")); - - Assert.assertTrue(like.passesFilter("id", item)); - } - - @Test - public void appliesToProperty_valueIsProperty_shouldBeTrue() { - Like like = new Like("test", "%foo"); - Assert.assertTrue(like.appliesToProperty("test")); - } - - @Test - public void appliesToProperty_valueIsNotProperty_shouldBeFalse() { - Like like = new Like("test", "%foo"); - Assert.assertFalse(like.appliesToProperty("bar")); - } - - @Test - public void equals_sameInstances_shouldBeTrue() { - Like like1 = new Like("test", "%foo"); - Like like2 = like1; - Assert.assertTrue(like1.equals(like2)); - } - - @Test - public void equals_twoEqualInstances_shouldBeTrue() { - Like like1 = new Like("test", "foo"); - Like like2 = new Like("test", "foo"); - Assert.assertTrue(like1.equals(like2)); - } - - @Test - public void equals_differentValues_shouldBeFalse() { - Like like1 = new Like("test", "foo"); - Like like2 = new Like("test", "bar"); - Assert.assertFalse(like1.equals(like2)); - } - - @Test - public void equals_differentProperties_shouldBeFalse() { - Like like1 = new Like("foo", "test"); - Like like2 = new Like("bar", "test"); - Assert.assertFalse(like1.equals(like2)); - } - - @Test - public void equals_differentPropertiesAndValues_shouldBeFalse() { - Like like1 = new Like("foo", "bar"); - Like like2 = new Like("baz", "zomg"); - Assert.assertFalse(like1.equals(like2)); - } - - @Test - public void equals_differentClasses_shouldBeFalse() { - Like like1 = new Like("foo", "bar"); - Object obj = new Object(); - Assert.assertFalse(like1.equals(obj)); - } - - @Test - public void equals_bothHaveNullProperties_shouldBeTrue() { - Like like1 = new Like(null, "foo"); - Like like2 = new Like(null, "foo"); - Assert.assertTrue(like1.equals(like2)); - } - - @Test - public void equals_bothHaveNullValues_shouldBeTrue() { - Like like1 = new Like("foo", null); - Like like2 = new Like("foo", null); - Assert.assertTrue(like1.equals(like2)); - } - - @Test - public void equals_onePropertyIsNull_shouldBeFalse() { - Like like1 = new Like(null, "bar"); - Like like2 = new Like("foo", "baz"); - Assert.assertFalse(like1.equals(like2)); - } - - @Test - public void equals_oneValueIsNull_shouldBeFalse() { - Like like1 = new Like("foo", null); - Like like2 = new Like("baz", "bar"); - Assert.assertFalse(like1.equals(like2)); - } - - @Test - public void hashCode_equalInstances_shouldBeEqual() { - Like like1 = new Like("test", "foo"); - Like like2 = new Like("test", "foo"); - Assert.assertEquals(like1.hashCode(), like2.hashCode()); - } - - @Test - public void hashCode_differentPropertiesAndValues_shouldNotEqual() { - Like like1 = new Like("foo", "bar"); - Like like2 = new Like("baz", "zomg"); - Assert.assertTrue(like1.hashCode() != like2.hashCode()); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java deleted file mode 100644 index dd1db30b72..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/SQLGeneratorsTest.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.generator; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.filter.Or; -import com.vaadin.data.util.sqlcontainer.DataGenerator; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLContainer; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.OrderBy; -import com.vaadin.data.util.sqlcontainer.query.TableQuery; -import com.vaadin.data.util.sqlcontainer.query.ValidatingSimpleJDBCConnectionPool; -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.OracleGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class SQLGeneratorsTest { - private JDBCConnectionPool connectionPool; - - @Before - public void setUp() throws SQLException { - - try { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - - DataGenerator.addPeopleToDatabase(connectionPool); - } - - @After - public void tearDown() { - if (connectionPool != null) { - connectionPool.destroy(); - } - } - - @Test - public void generateSelectQuery_basicQuery_shouldSucceed() { - SQLGenerator sg = new DefaultSQLGenerator(); - StatementHelper sh = sg.generateSelectQuery("TABLE", null, null, 0, 0, - null); - Assert.assertEquals(sh.getQueryString(), "SELECT * FROM TABLE"); - } - - @Test - public void generateSelectQuery_pagingAndColumnsSet_shouldSucceed() { - SQLGenerator sg = new DefaultSQLGenerator(); - StatementHelper sh = sg.generateSelectQuery("TABLE", null, null, 4, 8, - "COL1, COL2, COL3"); - Assert.assertEquals(sh.getQueryString(), - "SELECT COL1, COL2, COL3 FROM TABLE LIMIT 8 OFFSET 4"); - } - - /** - * Note: Only tests one kind of filter and ordering. - */ - @Test - public void generateSelectQuery_filtersAndOrderingSet_shouldSucceed() { - SQLGenerator sg = new DefaultSQLGenerator(); - List<com.vaadin.data.Container.Filter> f = new ArrayList<Filter>(); - f.add(new Like("name", "%lle")); - List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); - StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 0, 0, null); - Assert.assertEquals(sh.getQueryString(), - "SELECT * FROM TABLE WHERE \"name\" LIKE ? ORDER BY \"name\" ASC"); - } - - @Test - public void generateSelectQuery_filtersAndOrderingSet_exclusiveFilteringMode_shouldSucceed() { - SQLGenerator sg = new DefaultSQLGenerator(); - List<Filter> f = new ArrayList<Filter>(); - f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%"))); - List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); - StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 0, 0, null); - // TODO - Assert.assertEquals(sh.getQueryString(), - "SELECT * FROM TABLE WHERE (\"name\" LIKE ? " - + "OR \"name\" LIKE ?) ORDER BY \"name\" ASC"); - } - - @Test - public void generateDeleteQuery_basicQuery_shouldSucceed() - throws SQLException { - /* - * No need to run this for Oracle/MSSQL generators since the - * DefaultSQLGenerator method would be called anyway. - */ - if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator - || SQLTestsConstants.sqlGen instanceof OracleGenerator) { - return; - } - SQLGenerator sg = SQLTestsConstants.sqlGen; - TableQuery query = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - SQLContainer container = new SQLContainer(query); - - StatementHelper sh = sg.generateDeleteQuery("people", - query.getPrimaryKeyColumns(), null, (RowItem) container - .getItem(container.getItemIds().iterator().next())); - Assert.assertEquals("DELETE FROM people WHERE \"ID\" = ?", - sh.getQueryString()); - } - - @Test - public void generateUpdateQuery_basicQuery_shouldSucceed() - throws SQLException { - /* - * No need to run this for Oracle/MSSQL generators since the - * DefaultSQLGenerator method would be called anyway. - */ - if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator - || SQLTestsConstants.sqlGen instanceof OracleGenerator) { - return; - } - SQLGenerator sg = new DefaultSQLGenerator(); - TableQuery query = new TableQuery("people", connectionPool); - SQLContainer container = new SQLContainer(query); - - RowItem ri = (RowItem) container - .getItem(container.getItemIds().iterator().next()); - ri.getItemProperty("NAME").setValue("Viljami"); - - StatementHelper sh = sg.generateUpdateQuery("people", ri); - Assert.assertTrue( - "UPDATE people SET \"NAME\" = ?, \"AGE\" = ? WHERE \"ID\" = ?" - .equals(sh.getQueryString()) - || "UPDATE people SET \"AGE\" = ?, \"NAME\" = ? WHERE \"ID\" = ?" - .equals(sh.getQueryString())); - } - - @Test - public void generateInsertQuery_basicQuery_shouldSucceed() - throws SQLException { - /* - * No need to run this for Oracle/MSSQL generators since the - * DefaultSQLGenerator method would be called anyway. - */ - if (SQLTestsConstants.sqlGen instanceof MSSQLGenerator - || SQLTestsConstants.sqlGen instanceof OracleGenerator) { - return; - } - SQLGenerator sg = new DefaultSQLGenerator(); - TableQuery query = new TableQuery("people", connectionPool); - SQLContainer container = new SQLContainer(query); - - RowItem ri = (RowItem) container.getItem(container.addItem()); - ri.getItemProperty("NAME").setValue("Viljami"); - - StatementHelper sh = sg.generateInsertQuery("people", ri); - - Assert.assertTrue("INSERT INTO people (\"NAME\", \"AGE\") VALUES (?, ?)" - .equals(sh.getQueryString()) - || "INSERT INTO people (\"AGE\", \"NAME\") VALUES (?, ?)" - .equals(sh.getQueryString())); - } - - @Test - public void generateComplexSelectQuery_forOracle_shouldSucceed() - throws SQLException { - SQLGenerator sg = new OracleGenerator(); - List<Filter> f = new ArrayList<Filter>(); - f.add(new Like("name", "%lle")); - List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); - StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, - "NAME, ID"); - Assert.assertEquals( - "SELECT * FROM (SELECT x.*, ROWNUM AS \"rownum\" FROM" - + " (SELECT NAME, ID FROM TABLE WHERE \"name\" LIKE ?" - + " ORDER BY \"name\" ASC) x) WHERE \"rownum\" BETWEEN 5 AND 12", - sh.getQueryString()); - } - - @Test - public void generateComplexSelectQuery_forMSSQL_shouldSucceed() - throws SQLException { - SQLGenerator sg = new MSSQLGenerator(); - List<Filter> f = new ArrayList<Filter>(); - f.add(new Like("name", "%lle")); - List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); - StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, - "NAME, ID"); - Assert.assertEquals(sh.getQueryString(), - "SELECT * FROM (SELECT row_number() OVER " - + "( ORDER BY \"name\" ASC) AS rownum, NAME, ID " - + "FROM TABLE WHERE \"name\" LIKE ?) " - + "AS a WHERE a.rownum BETWEEN 5 AND 12"); - } - - @Test - public void generateComplexSelectQuery_forOracle_exclusiveFilteringMode_shouldSucceed() - throws SQLException { - SQLGenerator sg = new OracleGenerator(); - List<Filter> f = new ArrayList<Filter>(); - f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%"))); - List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); - StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, - "NAME, ID"); - Assert.assertEquals(sh.getQueryString(), - "SELECT * FROM (SELECT x.*, ROWNUM AS \"rownum\" FROM" - + " (SELECT NAME, ID FROM TABLE WHERE (\"name\" LIKE ?" - + " OR \"name\" LIKE ?) " - + "ORDER BY \"name\" ASC) x) WHERE \"rownum\" BETWEEN 5 AND 12"); - } - - @Test - public void generateComplexSelectQuery_forMSSQL_exclusiveFilteringMode_shouldSucceed() - throws SQLException { - SQLGenerator sg = new MSSQLGenerator(); - List<Filter> f = new ArrayList<Filter>(); - f.add(new Or(new Like("name", "%lle"), new Like("name", "vi%"))); - List<OrderBy> ob = Arrays.asList(new OrderBy("name", true)); - StatementHelper sh = sg.generateSelectQuery("TABLE", f, ob, 4, 8, - "NAME, ID"); - Assert.assertEquals(sh.getQueryString(), - "SELECT * FROM (SELECT row_number() OVER " - + "( ORDER BY \"name\" ASC) AS rownum, NAME, ID " - + "FROM TABLE WHERE (\"name\" LIKE ? " - + "OR \"name\" LIKE ?)) " - + "AS a WHERE a.rownum BETWEEN 5 AND 12"); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java deleted file mode 100644 index 7201ec7ad8..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/generator/StatementHelperTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.data.util.sqlcontainer.generator; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -/** - * - * @author Vaadin Ltd - */ -public class StatementHelperTest { - - @Test - public void testSetValueNullParameter() throws SQLException { - StatementHelper helper = new StatementHelper(); - helper.addParameterValue(null, StatementHelper.class); - PreparedStatement statement = EasyMock - .createMock(PreparedStatement.class); - // should throw SQLException, not NPE - try { - helper.setParameterValuesToStatement(statement); - Assert.fail("Expected SQLExecption for unsupported type"); - } catch (SQLException e) { - // Exception should contain info about which parameter and the type - // which was unsupported - Assert.assertTrue(e.getMessage().contains("parameter 0")); - Assert.assertTrue( - e.getMessage().contains(StatementHelper.class.getName())); - } - } - - @Test - public void testSetByteArrayValue() throws SQLException { - StatementHelper helper = new StatementHelper(); - helper.addParameterValue(null, byte[].class); - PreparedStatement statement = EasyMock - .createMock(PreparedStatement.class); - // should not throw SQLException - helper.setParameterValuesToStatement(statement); - - EasyMock.replay(statement); - statement.setBytes(1, null); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java deleted file mode 100644 index 1b9e14b0d8..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java +++ /dev/null @@ -1,1005 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.query; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.easymock.EasyMock; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.sqlcontainer.DataGenerator; -import com.vaadin.data.util.sqlcontainer.RowId; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLContainer; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; - -public class FreeformQueryTest { - - private static final int offset = SQLTestsConstants.offset; - private JDBCConnectionPool connectionPool; - - @Before - public void setUp() throws SQLException { - - try { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - - DataGenerator.addPeopleToDatabase(connectionPool); - } - - @After - public void tearDown() { - if (connectionPool != null) { - connectionPool.destroy(); - } - } - - @Test - public void construction_legalParameters_shouldSucceed() { - FreeformQuery ffQuery = new FreeformQuery("SELECT * FROM foo", - Arrays.asList("ID"), connectionPool); - Assert.assertArrayEquals(new Object[] { "ID" }, - ffQuery.getPrimaryKeyColumns().toArray()); - - Assert.assertEquals("SELECT * FROM foo", ffQuery.getQueryString()); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_emptyQueryString_shouldFail() { - new FreeformQuery("", Arrays.asList("ID"), connectionPool); - } - - @Test - public void construction_nullPrimaryKeys_shouldSucceed() { - new FreeformQuery("SELECT * FROM foo", null, connectionPool); - } - - @Test - public void construction_nullPrimaryKeys2_shouldSucceed() { - new FreeformQuery("SELECT * FROM foo", connectionPool); - } - - @Test - public void construction_emptyPrimaryKeys_shouldSucceed() { - new FreeformQuery("SELECT * FROM foo", connectionPool); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_emptyStringsInPrimaryKeys_shouldFail() { - new FreeformQuery("SELECT * FROM foo", Arrays.asList(""), - connectionPool); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_nullConnectionPool_shouldFail() { - new FreeformQuery("SELECT * FROM foo", Arrays.asList("ID"), null); - } - - @Test - public void getCount_simpleQuery_returnsFour() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - Assert.assertEquals(4, query.getCount()); - } - - @Test(expected = SQLException.class) - public void getCount_illegalQuery_shouldThrowSQLException() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM asdf", - Arrays.asList("ID"), connectionPool); - query.getResults(0, 50); - } - - @Test - public void getCount_simpleQueryTwoMorePeopleAdded_returnsSix() - throws SQLException { - // Add some people - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate("insert into people values('Bengt', 30)"); - statement.executeUpdate("insert into people values('Ingvar', 50)"); - } else { - statement.executeUpdate( - "insert into people values(default, 'Bengt', 30)"); - statement.executeUpdate( - "insert into people values(default, 'Ingvar', 50)"); - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - - Assert.assertEquals(6, query.getCount()); - } - - @Test - public void getCount_moreComplexQuery_returnsThree() throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", - connectionPool, new String[] { "ID" }); - Assert.assertEquals(3, query.getCount()); - } - - @Test - public void getCount_normalState_releasesConnection() throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", - connectionPool, "ID"); - query.getCount(); - query.getCount(); - Connection c = connectionPool.reserveConnection(); - Assert.assertNotNull(c); - // Cleanup to make test connection pool happy - connectionPool.releaseConnection(c); - } - - @Test - public void getCount_delegateRegistered_shouldUseDelegate() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.getCountQuery()).andReturn( - "SELECT COUNT(*) FROM people WHERE \"NAME\" LIKE '%lle'"); - EasyMock.replay(delegate); - query.setDelegate(delegate); - Assert.assertEquals(3, query.getCount()); - EasyMock.verify(delegate); - } - - @Test - public void getCount_delegateRegisteredZeroRows_returnsZero() - throws SQLException { - DataGenerator.createGarbage(connectionPool); - FreeformQuery query = new FreeformQuery("SELECT * FROM GARBAGE", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.getCountQuery()) - .andReturn("SELECT COUNT(*) FROM GARBAGE"); - EasyMock.replay(delegate); - query.setDelegate(delegate); - Assert.assertEquals(0, query.getCount()); - EasyMock.verify(delegate); - } - - @Test - public void getResults_simpleQuery_returnsFourRecords() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT \"ID\",\"NAME\" FROM people", Arrays.asList("ID"), - connectionPool); - query.beginTransaction(); - ResultSet rs = query.getResults(0, 0); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(0 + offset, rs.getInt(1)); - Assert.assertEquals("Ville", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(1 + offset, rs.getInt(1)); - Assert.assertEquals("Kalle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(2 + offset, rs.getInt(1)); - Assert.assertEquals("Pelle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(3 + offset, rs.getInt(1)); - Assert.assertEquals("Börje", rs.getString(2)); - - Assert.assertFalse(rs.next()); - query.commit(); - } - - @Test - public void getResults_moreComplexQuery_returnsThreeRecords() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", - Arrays.asList("ID"), connectionPool); - query.beginTransaction(); - ResultSet rs = query.getResults(0, 0); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(0 + offset, rs.getInt(1)); - Assert.assertEquals("Ville", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(1 + offset, rs.getInt(1)); - Assert.assertEquals("Kalle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(2 + offset, rs.getInt(1)); - Assert.assertEquals("Pelle", rs.getString(2)); - - Assert.assertFalse(rs.next()); - query.commit(); - } - - @Test - public void getResults_noDelegate5000Rows_returns5000rows() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.beginTransaction(); - ResultSet rs = query.getResults(0, 0); - for (int i = 0; i < 5000; i++) { - Assert.assertTrue(rs.next()); - } - Assert.assertFalse(rs.next()); - query.commit(); - } - - @Test(expected = UnsupportedOperationException.class) - public void setFilters_noDelegate_shouldFail() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Like("name", "%lle")); - query.setFilters(filters); - } - - @Test(expected = UnsupportedOperationException.class) - public void setOrderBy_noDelegate_shouldFail() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.setOrderBy(Arrays.asList(new OrderBy("name", true))); - } - - @Test(expected = IllegalStateException.class) - public void storeRow_noDelegateNoTransactionActive_shouldFail() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.storeRow(new RowItem(new SQLContainer(query), - new RowId(new Object[] { 1 }), null)); - } - - @Test - public void storeRow_noDelegate_shouldFail() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - EasyMock.replay(container); - query.beginTransaction(); - try { - query.storeRow(new RowItem(container, new RowId(new Object[] { 1 }), - null)); - Assert.fail("storeRow should fail when there is no delegate"); - } catch (UnsupportedOperationException e) { - // Cleanup to make test connection pool happy - query.rollback(); - } - } - - @Test - public void removeRow_noDelegate_shouldFail() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - EasyMock.replay(container); - query.beginTransaction(); - try { - query.removeRow(new RowItem(container, - new RowId(new Object[] { 1 }), null)); - Assert.fail("removeRow should fail when there is no delgate"); - } catch (UnsupportedOperationException e) { - // Cleanup to make test connection pool happy - query.rollback(); - } - } - - @Test - public void commit_readOnly_shouldSucceed() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.beginTransaction(); - query.commit(); - } - - @Test - public void rollback_readOnly_shouldSucceed() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.beginTransaction(); - query.rollback(); - } - - @Test(expected = SQLException.class) - public void commit_noActiveTransaction_shouldFail() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.commit(); - } - - @Test(expected = SQLException.class) - public void rollback_noActiveTransaction_shouldFail() throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.rollback(); - } - - @Test - public void containsRowWithKeys_simpleQueryWithExistingKeys_returnsTrue() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - Assert.assertTrue(query.containsRowWithKey(1)); - } - - @Test - public void containsRowWithKeys_simpleQueryWithNonexistingKeys_returnsTrue() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - Assert.assertFalse(query.containsRowWithKey(1337)); - } - - // (expected = SQLException.class) - @Test - public void containsRowWithKeys_simpleQueryWithInvalidKeys_shouldFail() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - Assert.assertFalse(query.containsRowWithKey(38796)); - } - - @Test - public void containsRowWithKeys_queryContainingWhereClauseAndExistingKeys_returnsTrue() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", - Arrays.asList("ID"), connectionPool); - Assert.assertTrue(query.containsRowWithKey(1)); - } - - @Test - public void containsRowWithKeys_queryContainingLowercaseWhereClauseAndExistingKeys_returnsTrue() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "select * from people where \"NAME\" like '%lle'", - Arrays.asList("ID"), connectionPool); - Assert.assertTrue(query.containsRowWithKey(1)); - } - - @Test - public void containsRowWithKeys_nullKeys_shouldFailAndReleaseConnections() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "select * from people where \"NAME\" like '%lle'", - Arrays.asList("ID"), connectionPool); - try { - query.containsRowWithKey(new Object[] { null }); - } catch (SQLException e) { - // We should now be able to reserve two connections - connectionPool.reserveConnection(); - connectionPool.reserveConnection(); - } - } - - /* - * -------- Tests with a delegate --------- - */ - - @Test - public void setDelegate_noExistingDelegate_shouldRegisterNewDelegate() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - query.setDelegate(delegate); - Assert.assertEquals(delegate, query.getDelegate()); - } - - @Test - public void getResults_hasDelegate_shouldCallDelegate() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - if (SQLTestsConstants.db == DB.MSSQL) { - EasyMock.expect(delegate.getQueryString(0, 2)) - .andReturn("SELECT * FROM (SELECT row_number()" - + "OVER (ORDER BY id ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN 0 AND 2"); - } else if (SQLTestsConstants.db == DB.ORACLE) { - EasyMock.expect(delegate.getQueryString(0, 2)) - .andReturn("SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people) x) WHERE r BETWEEN 1 AND 2"); - } else { - EasyMock.expect(delegate.getQueryString(0, 2)) - .andReturn("SELECT * FROM people LIMIT 2 OFFSET 0"); - } - EasyMock.replay(delegate); - - query.setDelegate(delegate); - query.beginTransaction(); - query.getResults(0, 2); - EasyMock.verify(delegate); - query.commit(); - } - - @Test - public void getResults_delegateImplementsGetQueryString_shouldHonorOffsetAndPagelength() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - if (SQLTestsConstants.db == DB.MSSQL) { - EasyMock.expect(delegate.getQueryString(0, 2)) - .andReturn("SELECT * FROM (SELECT row_number()" - + "OVER (ORDER BY id ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN 0 AND 2"); - } else if (SQLTestsConstants.db == DB.ORACLE) { - EasyMock.expect(delegate.getQueryString(0, 2)) - .andReturn("SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people) x) WHERE r BETWEEN 1 AND 2"); - } else { - EasyMock.expect(delegate.getQueryString(0, 2)) - .andReturn("SELECT * FROM people LIMIT 2 OFFSET 0"); - } - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - ResultSet rs = query.getResults(0, 2); - int rsoffset = 0; - if (SQLTestsConstants.db == DB.MSSQL) { - rsoffset++; - } - Assert.assertTrue(rs.next()); - Assert.assertEquals(0 + offset, rs.getInt(1 + rsoffset)); - Assert.assertEquals("Ville", rs.getString(2 + rsoffset)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(1 + offset, rs.getInt(1 + rsoffset)); - Assert.assertEquals("Kalle", rs.getString(2 + rsoffset)); - - Assert.assertFalse(rs.next()); - - EasyMock.verify(delegate); - query.commit(); - } - - @Test - public void getResults_delegateRegistered5000Rows_returns100rows() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - if (SQLTestsConstants.db == DB.MSSQL) { - EasyMock.expect(delegate.getQueryString(200, 100)) - .andReturn("SELECT * FROM (SELECT row_number()" - + "OVER (ORDER BY id ASC) AS rownum, * FROM people)" - + " AS a WHERE a.rownum BETWEEN 201 AND 300"); - } else if (SQLTestsConstants.db == DB.ORACLE) { - EasyMock.expect(delegate.getQueryString(200, 100)) - .andReturn("SELECT * FROM (SELECT x.*, ROWNUM AS r FROM" - + " (SELECT * FROM people ORDER BY ID ASC) x) WHERE r BETWEEN 201 AND 300"); - } else { - EasyMock.expect(delegate.getQueryString(200, 100)) - .andReturn("SELECT * FROM people LIMIT 100 OFFSET 200"); - } - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - ResultSet rs = query.getResults(200, 100); - for (int i = 0; i < 100; i++) { - Assert.assertTrue(rs.next()); - Assert.assertEquals(200 + i + offset, rs.getInt("ID")); - } - Assert.assertFalse(rs.next()); - query.commit(); - } - - @Test - public void setFilters_delegateImplementsSetFilters_shouldPassFiltersToDelegate() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - List<Filter> filters = new ArrayList<Filter>(); - filters.add(new Like("name", "%lle")); - delegate.setFilters(filters); - - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.setFilters(filters); - - EasyMock.verify(delegate); - } - - @Test(expected = UnsupportedOperationException.class) - public void setFilters_delegateDoesNotImplementSetFilters_shouldFail() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - List<Filter> filters = new ArrayList<Filter>(); - filters.add(new Like("name", "%lle")); - delegate.setFilters(filters); - EasyMock.expectLastCall().andThrow(new UnsupportedOperationException()); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.setFilters(filters); - - EasyMock.verify(delegate); - } - - @Test - public void setOrderBy_delegateImplementsSetOrderBy_shouldPassArgumentsToDelegate() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - List<OrderBy> orderBys = Arrays.asList(new OrderBy("name", false)); - delegate.setOrderBy(orderBys); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.setOrderBy(orderBys); - - EasyMock.verify(delegate); - } - - @Test(expected = UnsupportedOperationException.class) - public void setOrderBy_delegateDoesNotImplementSetOrderBy_shouldFail() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - List<OrderBy> orderBys = Arrays.asList(new OrderBy("name", false)); - delegate.setOrderBy(orderBys); - EasyMock.expectLastCall().andThrow(new UnsupportedOperationException()); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.setOrderBy(orderBys); - - EasyMock.verify(delegate); - } - - @Test - public void setFilters_noDelegateAndNullParameter_shouldSucceed() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.setFilters(null); - } - - @Test - public void setOrderBy_noDelegateAndNullParameter_shouldSucceed() { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - query.setOrderBy(null); - } - - @Test - public void storeRow_delegateImplementsStoreRow_shouldPassToDelegate() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))).andReturn(1); - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - EasyMock.replay(delegate, container); - query.setDelegate(delegate); - - query.beginTransaction(); - RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), - null); - query.storeRow(row); - query.commit(); - - EasyMock.verify(delegate, container); - } - - @Test - public void storeRow_delegateDoesNotImplementStoreRow_shouldFail() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.storeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))) - .andThrow(new UnsupportedOperationException()); - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - EasyMock.replay(delegate, container); - query.setDelegate(delegate); - - query.beginTransaction(); - RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), - null); - try { - query.storeRow(row); - Assert.fail( - "storeRow should fail when delgate does not implement storeRow"); - } catch (UnsupportedOperationException e) { - // Cleanup to make test connection pool happy - query.rollback(); - } - } - - @Test - public void removeRow_delegateImplementsRemoveRow_shouldPassToDelegate() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.removeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))).andReturn(true); - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - EasyMock.replay(delegate, container); - query.setDelegate(delegate); - - query.beginTransaction(); - RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), - null); - query.removeRow(row); - query.commit(); - - EasyMock.verify(delegate, container); - } - - @Test - public void removeRow_delegateDoesNotImplementRemoveRow_shouldFail() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.removeRow(EasyMock.isA(Connection.class), - EasyMock.isA(RowItem.class))) - .andThrow(new UnsupportedOperationException()); - SQLContainer container = EasyMock.createNiceMock(SQLContainer.class); - EasyMock.replay(delegate, container); - query.setDelegate(delegate); - - query.beginTransaction(); - RowItem row = new RowItem(container, new RowId(new Object[] { 1 }), - null); - try { - query.removeRow(row); - Assert.fail( - "removeRow should fail when delegate does not implement removeRow"); - } catch (UnsupportedOperationException e) { - // Cleanup to make test connection pool happy - query.rollback(); - } - } - - @Test - public void beginTransaction_delegateRegistered_shouldSucceed() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - // Cleanup to make test connection pool happy - query.rollback(); - } - - @Test - public void beginTransaction_transactionAlreadyActive_shouldFail() - throws SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - - query.beginTransaction(); - try { - query.beginTransaction(); - Assert.fail( - "Should throw exception when starting a transaction while already in a transaction"); - } catch (IllegalStateException e) { - // Cleanup to make test connection pool happy - query.rollback(); - } - } - - @Test(expected = SQLException.class) - public void commit_delegateRegisteredNoActiveTransaction_shouldFail() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.commit(); - } - - @Test - public void commit_delegateRegisteredActiveTransaction_shouldSucceed() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - query.commit(); - } - - @Test(expected = SQLException.class) - public void commit_delegateRegisteredActiveTransactionDoubleCommit_shouldFail() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - query.commit(); - query.commit(); - } - - @Test(expected = SQLException.class) - public void rollback_delegateRegisteredNoActiveTransaction_shouldFail() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.rollback(); - } - - @Test - public void rollback_delegateRegisteredActiveTransaction_shouldSucceed() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - query.rollback(); - } - - @Test(expected = SQLException.class) - public void rollback_delegateRegisteredActiveTransactionDoubleRollback_shouldFail() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - query.rollback(); - query.rollback(); - } - - @Test(expected = SQLException.class) - public void rollback_delegateRegisteredCommittedTransaction_shouldFail() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - query.commit(); - query.rollback(); - } - - @Test(expected = SQLException.class) - public void commit_delegateRegisteredRollbackedTransaction_shouldFail() - throws UnsupportedOperationException, SQLException { - FreeformQuery query = new FreeformQuery("SELECT * FROM people", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.beginTransaction(); - query.rollback(); - query.commit(); - } - - @Test(expected = SQLException.class) - public void containsRowWithKeys_delegateRegistered_shouldCallGetContainsRowQueryString() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE name LIKE '%lle'", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.getContainsRowQueryString(1)).andReturn(""); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - query.containsRowWithKey(1); - - EasyMock.verify(delegate); - } - - @Test - public void containsRowWithKeys_delegateRegistered_shouldUseResultFromGetContainsRowQueryString() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - // In order to test that this is the query that is actually used, we use - // a non-existing id in place of the existing one. - EasyMock.expect(delegate.getContainsRowQueryString(1)).andReturn( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle' AND \"ID\" = 1337"); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - // The id (key) used should be 1337 as above, for the call with key = 1 - Assert.assertFalse(query.containsRowWithKey(1)); - - EasyMock.verify(delegate); - } - - public static class NonMatchingDelegateWithGroupBy - implements FreeformQueryDelegate { - - private String fromWhere = "FROM people p1 LEFT JOIN people p2 ON p2.id = p1.id WHERE p1.\"NAME\" LIKE 'notfound' GROUP BY p1.ID"; - - @Override - public int storeRow(Connection conn, RowItem row) - throws UnsupportedOperationException, SQLException { - // Not used in this test - return 0; - } - - @Override - public void setOrderBy(List<OrderBy> orderBys) - throws UnsupportedOperationException { - // Not used in this test - } - - @Override - public void setFilters(List<Filter> filters) - throws UnsupportedOperationException { - // Not used in this test - } - - @Override - public boolean removeRow(Connection conn, RowItem row) - throws UnsupportedOperationException, SQLException { - // Not used in this test - return false; - } - - @Override - public String getQueryString(int offset, int limit) - throws UnsupportedOperationException { - return "SELECT * " + fromWhere; - } - - @Override - public String getCountQuery() throws UnsupportedOperationException { - return "SELECT COUNT(*) " + fromWhere; - } - - @Override - public String getContainsRowQueryString(Object... keys) - throws UnsupportedOperationException { - // Not used in this test - return null; - } - } - - public static class NonMatchingStatementDelegateWithGroupBy - extends NonMatchingDelegateWithGroupBy - implements FreeformStatementDelegate { - - @Override - public StatementHelper getQueryStatement(int offset, int limit) - throws UnsupportedOperationException { - StatementHelper sh = new StatementHelper(); - sh.setQueryString(getQueryString(offset, limit)); - return sh; - } - - @Override - public StatementHelper getCountStatement() - throws UnsupportedOperationException { - StatementHelper sh = new StatementHelper(); - sh.setQueryString(getCountQuery()); - return sh; - } - - @Override - public StatementHelper getContainsRowQueryStatement(Object... keys) - throws UnsupportedOperationException { - // Not used in this test - return null; - } - } - - @Test - public void containsRowWithKeys_delegateRegisteredGetContainsRowQueryStringNotImplemented_shouldBuildQueryString() - throws SQLException { - FreeformQuery query = new FreeformQuery( - "SELECT * FROM people WHERE \"NAME\" LIKE '%lle'", - Arrays.asList("ID"), connectionPool); - FreeformQueryDelegate delegate = EasyMock - .createMock(FreeformQueryDelegate.class); - EasyMock.expect(delegate.getContainsRowQueryString(1)) - .andThrow(new UnsupportedOperationException()); - EasyMock.replay(delegate); - query.setDelegate(delegate); - - Assert.assertTrue(query.containsRowWithKey(1)); - - EasyMock.verify(delegate); - } - - @Test - public void delegateStatementCountWithGroupBy() throws SQLException { - String dummyNotUsed = "foo"; - FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool, - "p1.ID"); - query.setDelegate(new NonMatchingStatementDelegateWithGroupBy()); - - Assert.assertEquals(0, query.getCount()); - } - - @Test - public void delegateCountWithGroupBy() throws SQLException { - String dummyNotUsed = "foo"; - FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool, - "p1.ID"); - query.setDelegate(new NonMatchingDelegateWithGroupBy()); - - Assert.assertEquals(0, query.getCount()); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java deleted file mode 100644 index 7974582147..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/QueryBuilderTest.java +++ /dev/null @@ -1,315 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.query; - -import java.util.ArrayList; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.And; -import com.vaadin.data.util.filter.Between; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Compare.Greater; -import com.vaadin.data.util.filter.Compare.GreaterOrEqual; -import com.vaadin.data.util.filter.Compare.Less; -import com.vaadin.data.util.filter.Compare.LessOrEqual; -import com.vaadin.data.util.filter.IsNull; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.filter.Not; -import com.vaadin.data.util.filter.Or; -import com.vaadin.data.util.filter.SimpleStringFilter; -import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder; -import com.vaadin.data.util.sqlcontainer.query.generator.filter.StringDecorator; - -public class QueryBuilderTest { - - private StatementHelper mockedStatementHelper(Object... values) { - StatementHelper sh = EasyMock.createMock(StatementHelper.class); - for (Object val : values) { - sh.addParameterValue(val); - EasyMock.expectLastCall(); - } - EasyMock.replay(sh); - return sh; - } - - // escape bad characters and wildcards - - @Test - public void getWhereStringForFilter_equals() { - StatementHelper sh = mockedStatementHelper("Fido"); - Equal f = new Equal("NAME", "Fido"); - Assert.assertEquals("\"NAME\" = ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_greater() { - StatementHelper sh = mockedStatementHelper(18); - Greater f = new Greater("AGE", 18); - Assert.assertEquals("\"AGE\" > ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_less() { - StatementHelper sh = mockedStatementHelper(65); - Less f = new Less("AGE", 65); - Assert.assertEquals("\"AGE\" < ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_greaterOrEqual() { - StatementHelper sh = mockedStatementHelper(18); - GreaterOrEqual f = new GreaterOrEqual("AGE", 18); - Assert.assertEquals("\"AGE\" >= ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_lessOrEqual() { - StatementHelper sh = mockedStatementHelper(65); - LessOrEqual f = new LessOrEqual("AGE", 65); - Assert.assertEquals("\"AGE\" <= ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_simpleStringFilter() { - StatementHelper sh = mockedStatementHelper("Vi%"); - SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", false, - true); - Assert.assertEquals("\"NAME\" LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_simpleStringFilterMatchAnywhere() { - StatementHelper sh = mockedStatementHelper("%Vi%"); - SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", false, - false); - Assert.assertEquals("\"NAME\" LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_simpleStringFilterMatchAnywhereIgnoreCase() { - StatementHelper sh = mockedStatementHelper("%VI%"); - SimpleStringFilter f = new SimpleStringFilter("NAME", "Vi", true, - false); - Assert.assertEquals("UPPER(\"NAME\") LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_startsWith() { - StatementHelper sh = mockedStatementHelper("Vi%"); - Like f = new Like("NAME", "Vi%"); - Assert.assertEquals("\"NAME\" LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_startsWithNumber() { - StatementHelper sh = mockedStatementHelper("1%"); - Like f = new Like("AGE", "1%"); - Assert.assertEquals("\"AGE\" LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_endsWith() { - StatementHelper sh = mockedStatementHelper("%lle"); - Like f = new Like("NAME", "%lle"); - Assert.assertEquals("\"NAME\" LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_contains() { - StatementHelper sh = mockedStatementHelper("%ill%"); - Like f = new Like("NAME", "%ill%"); - Assert.assertEquals("\"NAME\" LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_between() { - StatementHelper sh = mockedStatementHelper(18, 65); - Between f = new Between("AGE", 18, 65); - Assert.assertEquals("\"AGE\" BETWEEN ? AND ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_caseInsensitive_equals() { - StatementHelper sh = mockedStatementHelper("FIDO"); - Like f = new Like("NAME", "Fido"); - f.setCaseSensitive(false); - Assert.assertEquals("UPPER(\"NAME\") LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_caseInsensitive_startsWith() { - StatementHelper sh = mockedStatementHelper("VI%"); - Like f = new Like("NAME", "Vi%"); - f.setCaseSensitive(false); - Assert.assertEquals("UPPER(\"NAME\") LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_caseInsensitive_endsWith() { - StatementHelper sh = mockedStatementHelper("%LLE"); - Like f = new Like("NAME", "%lle"); - f.setCaseSensitive(false); - Assert.assertEquals("UPPER(\"NAME\") LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilter_caseInsensitive_contains() { - StatementHelper sh = mockedStatementHelper("%ILL%"); - Like f = new Like("NAME", "%ill%"); - f.setCaseSensitive(false); - Assert.assertEquals("UPPER(\"NAME\") LIKE ?", - QueryBuilder.getWhereStringForFilter(f, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_listOfFilters() { - StatementHelper sh = mockedStatementHelper("%lle", 18); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Like("NAME", "%lle")); - filters.add(new Greater("AGE", 18)); - Assert.assertEquals(" WHERE \"NAME\" LIKE ? AND \"AGE\" > ?", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_oneAndFilter() { - StatementHelper sh = mockedStatementHelper("%lle", 18); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new And(new Like("NAME", "%lle"), new Greater("AGE", 18))); - Assert.assertEquals(" WHERE (\"NAME\" LIKE ? AND \"AGE\" > ?)", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_oneOrFilter() { - StatementHelper sh = mockedStatementHelper("%lle", 18); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Or(new Like("NAME", "%lle"), new Greater("AGE", 18))); - Assert.assertEquals(" WHERE (\"NAME\" LIKE ? OR \"AGE\" > ?)", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_complexCompoundFilters() { - StatementHelper sh = mockedStatementHelper("%lle", 18, 65, "Pelle"); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Or( - new And(new Like("NAME", "%lle"), - new Or(new Less("AGE", 18), new Greater("AGE", 65))), - new Equal("NAME", "Pelle"))); - Assert.assertEquals( - " WHERE ((\"NAME\" LIKE ? AND (\"AGE\" < ? OR \"AGE\" > ?)) OR \"NAME\" = ?)", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_complexCompoundFiltersAndSingleFilter() { - StatementHelper sh = mockedStatementHelper("%lle", 18, 65, "Pelle", - "Virtanen"); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Or( - new And(new Like("NAME", "%lle"), - new Or(new Less("AGE", 18), new Greater("AGE", 65))), - new Equal("NAME", "Pelle"))); - filters.add(new Equal("LASTNAME", "Virtanen")); - Assert.assertEquals( - " WHERE ((\"NAME\" LIKE ? AND (\"AGE\" < ? OR \"AGE\" > ?)) OR \"NAME\" = ?) AND \"LASTNAME\" = ?", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_emptyList_shouldReturnEmptyString() { - ArrayList<Filter> filters = new ArrayList<Filter>(); - Assert.assertEquals("", QueryBuilder.getWhereStringForFilters(filters, - new StatementHelper())); - } - - @Test - public void getWhereStringForFilters_NotFilter() { - StatementHelper sh = mockedStatementHelper(18); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Not(new Equal("AGE", 18))); - Assert.assertEquals(" WHERE NOT \"AGE\" = ?", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_complexNegatedFilter() { - StatementHelper sh = mockedStatementHelper(65, 18); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add( - new Not(new Or(new Equal("AGE", 65), new Equal("AGE", 18)))); - Assert.assertEquals(" WHERE NOT (\"AGE\" = ? OR \"AGE\" = ?)", - QueryBuilder.getWhereStringForFilters(filters, sh)); - EasyMock.verify(sh); - } - - @Test - public void getWhereStringForFilters_isNull() { - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new IsNull("NAME")); - Assert.assertEquals(" WHERE \"NAME\" IS NULL", QueryBuilder - .getWhereStringForFilters(filters, new StatementHelper())); - } - - @Test - public void getWhereStringForFilters_isNotNull() { - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Not(new IsNull("NAME"))); - Assert.assertEquals(" WHERE \"NAME\" IS NOT NULL", QueryBuilder - .getWhereStringForFilters(filters, new StatementHelper())); - } - - @Test - public void getWhereStringForFilters_customStringDecorator() { - QueryBuilder.setStringDecorator(new StringDecorator("[", "]")); - ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new Not(new IsNull("NAME"))); - Assert.assertEquals(" WHERE [NAME] IS NOT NULL", QueryBuilder - .getWhereStringForFilters(filters, new StatementHelper())); - // Reset the default string decorator - QueryBuilder.setStringDecorator(new StringDecorator("\"", "\"")); - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java deleted file mode 100644 index d2067a85b4..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java +++ /dev/null @@ -1,746 +0,0 @@ -package com.vaadin.data.util.sqlcontainer.query; - -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.List; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container.Filter; -import com.vaadin.data.util.filter.Compare.Equal; -import com.vaadin.data.util.filter.Like; -import com.vaadin.data.util.sqlcontainer.DataGenerator; -import com.vaadin.data.util.sqlcontainer.OptimisticLockException; -import com.vaadin.data.util.sqlcontainer.RowItem; -import com.vaadin.data.util.sqlcontainer.SQLContainer; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; -import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator; - -public class TableQueryTest { - private static final int offset = SQLTestsConstants.offset; - private JDBCConnectionPool connectionPool; - - @Before - public void setUp() throws SQLException { - try { - connectionPool = new ValidatingSimpleJDBCConnectionPool( - SQLTestsConstants.dbDriver, SQLTestsConstants.dbURL, - SQLTestsConstants.dbUser, SQLTestsConstants.dbPwd, 2, 2); - } catch (SQLException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - DataGenerator.addPeopleToDatabase(connectionPool); - } - - @After - public void tearDown() { - if (connectionPool != null) { - connectionPool.destroy(); - } - } - - /********************************************************************** - * TableQuery construction tests - **********************************************************************/ - @Test - public void construction_legalParameters_shouldSucceed() { - TableQuery tQuery = new TableQuery("people", connectionPool, - new DefaultSQLGenerator()); - Assert.assertArrayEquals(new Object[] { "ID" }, - tQuery.getPrimaryKeyColumns().toArray()); - boolean correctTableName = "people" - .equalsIgnoreCase(tQuery.getTableName()); - Assert.assertTrue(correctTableName); - } - - @Test - public void construction_legalParameters_defaultGenerator_shouldSucceed() { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - Assert.assertArrayEquals(new Object[] { "ID" }, - tQuery.getPrimaryKeyColumns().toArray()); - boolean correctTableName = "people" - .equalsIgnoreCase(tQuery.getTableName()); - Assert.assertTrue(correctTableName); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_nonExistingTableName_shouldFail() { - new TableQuery("skgwaguhsd", connectionPool, new DefaultSQLGenerator()); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_emptyTableName_shouldFail() { - new TableQuery("", connectionPool, new DefaultSQLGenerator()); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_nullSqlGenerator_shouldFail() { - new TableQuery("people", connectionPool, null); - } - - @Test(expected = IllegalArgumentException.class) - public void construction_nullConnectionPool_shouldFail() { - new TableQuery("people", null, new DefaultSQLGenerator()); - } - - /********************************************************************** - * TableQuery row count tests - **********************************************************************/ - @Test - public void getCount_simpleQuery_returnsFour() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - Assert.assertEquals(4, tQuery.getCount()); - } - - @Test - public void getCount_simpleQueryTwoMorePeopleAdded_returnsSix() - throws SQLException { - // Add some people - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - if (SQLTestsConstants.db == DB.MSSQL) { - statement.executeUpdate("insert into people values('Bengt', 30)"); - statement.executeUpdate("insert into people values('Ingvar', 50)"); - } else { - statement.executeUpdate( - "insert into people values(default, 'Bengt', 30)"); - statement.executeUpdate( - "insert into people values(default, 'Ingvar', 50)"); - } - statement.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - Assert.assertEquals(6, tQuery.getCount()); - } - - @Test - public void getCount_normalState_releasesConnection() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.getCount(); - tQuery.getCount(); - Connection c = connectionPool.reserveConnection(); - Assert.assertNotNull(c); - connectionPool.releaseConnection(c); - } - - /********************************************************************** - * TableQuery get results tests - **********************************************************************/ - @Test - public void getResults_simpleQuery_returnsFourRecords() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.beginTransaction(); - ResultSet rs = tQuery.getResults(0, 0); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(0 + offset, rs.getInt(1)); - Assert.assertEquals("Ville", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(1 + offset, rs.getInt(1)); - Assert.assertEquals("Kalle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(2 + offset, rs.getInt(1)); - Assert.assertEquals("Pelle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(3 + offset, rs.getInt(1)); - Assert.assertEquals("Börje", rs.getString(2)); - - Assert.assertFalse(rs.next()); - tQuery.commit(); - } - - @Test - public void getResults_noDelegate5000Rows_returns5000rows() - throws SQLException { - DataGenerator.addFiveThousandPeople(connectionPool); - - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - tQuery.beginTransaction(); - ResultSet rs = tQuery.getResults(0, 0); - for (int i = 0; i < 5000; i++) { - Assert.assertTrue(rs.next()); - } - Assert.assertFalse(rs.next()); - tQuery.commit(); - } - - /********************************************************************** - * TableQuery transaction management tests - **********************************************************************/ - @Test - public void beginTransaction_transactionAlreadyActive_shouldFail() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - tQuery.beginTransaction(); - try { - tQuery.beginTransaction(); - Assert.fail( - "Should throw exception when starting a transaction while already in a transaction"); - } catch (IllegalStateException e) { - // Cleanup to make test connection pool happy - tQuery.rollback(); - } - } - - @Test - public void commit_readOnly_shouldSucceed() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.beginTransaction(); - tQuery.commit(); - } - - @Test - public void rollback_readOnly_shouldSucceed() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.beginTransaction(); - tQuery.rollback(); - } - - @Test(expected = SQLException.class) - public void commit_noActiveTransaction_shouldFail() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.commit(); - } - - @Test(expected = SQLException.class) - public void rollback_noActiveTransaction_shouldFail() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.rollback(); - } - - /********************************************************************** - * TableQuery row query with given keys tests - **********************************************************************/ - @Test - public void containsRowWithKeys_existingKeys_returnsTrue() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - Assert.assertTrue(tQuery.containsRowWithKey(1)); - } - - @Test - public void containsRowWithKeys_nonexistingKeys_returnsTrue() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - Assert.assertFalse(tQuery.containsRowWithKey(1337)); - } - - @Test - public void containsRowWithKeys_invalidKeys_shouldFail() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - boolean b = true; - try { - b = tQuery.containsRowWithKey("foo"); - } catch (SQLException se) { - return; - } - Assert.assertFalse(b); - } - - @Test - public void containsRowWithKeys_nullKeys_shouldFailAndReleaseConnections() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - try { - tQuery.containsRowWithKey(new Object[] { null }); - org.junit.Assert.fail( - "null should throw an IllegalArgumentException from StatementHelper"); - } catch (IllegalArgumentException e) { - // We should now be able to reserve two connections - Connection c1 = connectionPool.reserveConnection(); - Connection c2 = connectionPool.reserveConnection(); - - // Cleanup to make test connection pool happy - connectionPool.releaseConnection(c1); - connectionPool.releaseConnection(c2); - - } - } - - /********************************************************************** - * TableQuery filtering and ordering tests - **********************************************************************/ - @Test - public void setFilters_shouldReturnCorrectCount() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - List<Filter> filters = new ArrayList<Filter>(); - filters.add(new Like("NAME", "%lle")); - tQuery.setFilters(filters); - Assert.assertEquals(3, tQuery.getCount()); - } - - @Test - public void setOrderByNameAscending_shouldReturnCorrectOrder() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - List<OrderBy> orderBys = Arrays.asList(new OrderBy("NAME", true)); - tQuery.setOrderBy(orderBys); - - tQuery.beginTransaction(); - ResultSet rs; - rs = tQuery.getResults(0, 0); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(3 + offset, rs.getInt(1)); - Assert.assertEquals("Börje", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(1 + offset, rs.getInt(1)); - Assert.assertEquals("Kalle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(2 + offset, rs.getInt(1)); - Assert.assertEquals("Pelle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(0 + offset, rs.getInt(1)); - Assert.assertEquals("Ville", rs.getString(2)); - - Assert.assertFalse(rs.next()); - tQuery.commit(); - } - - @Test - public void setOrderByNameDescending_shouldReturnCorrectOrder() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - List<OrderBy> orderBys = Arrays.asList(new OrderBy("NAME", false)); - tQuery.setOrderBy(orderBys); - - tQuery.beginTransaction(); - ResultSet rs; - rs = tQuery.getResults(0, 0); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(0 + offset, rs.getInt(1)); - Assert.assertEquals("Ville", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(2 + offset, rs.getInt(1)); - Assert.assertEquals("Pelle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(1 + offset, rs.getInt(1)); - Assert.assertEquals("Kalle", rs.getString(2)); - - Assert.assertTrue(rs.next()); - Assert.assertEquals(3 + offset, rs.getInt(1)); - Assert.assertEquals("Börje", rs.getString(2)); - - Assert.assertFalse(rs.next()); - tQuery.commit(); - } - - @Test - public void setFilters_nullParameter_shouldSucceed() { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setFilters(null); - } - - @Test - public void setOrderBy_nullParameter_shouldSucceed() { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setOrderBy(null); - } - - /********************************************************************** - * TableQuery row removal tests - **********************************************************************/ - @Test - public void removeRowThroughContainer_legalRowItem_shouldSucceed() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - SQLContainer container = new SQLContainer(tQuery); - container.setAutoCommit(false); - Assert.assertTrue( - container.removeItem(container.getItemIds().iterator().next())); - - Assert.assertEquals(4, tQuery.getCount()); - Assert.assertEquals(3, container.size()); - container.commit(); - - Assert.assertEquals(3, tQuery.getCount()); - Assert.assertEquals(3, container.size()); - } - - @Test - public void removeRowThroughContainer_nonexistingRowId_shouldFail() - throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - SQLContainer container = new SQLContainer(tQuery); - container.setAutoCommit(true); - Assert.assertFalse(container.removeItem("foo")); - } - - /********************************************************************** - * TableQuery row adding / modification tests - **********************************************************************/ - @Test - public void insertRowThroughContainer_shouldSucceed() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setVersionColumn("ID"); - - SQLContainer container = new SQLContainer(tQuery); - container.setAutoCommit(false); - - Object item = container.addItem(); - Assert.assertNotNull(item); - - Assert.assertEquals(4, tQuery.getCount()); - Assert.assertEquals(5, container.size()); - container.commit(); - - Assert.assertEquals(5, tQuery.getCount()); - Assert.assertEquals(5, container.size()); - } - - @Test - public void modifyRowThroughContainer_shouldSucceed() throws SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - - // In this test the primary key is used as a version column - tQuery.setVersionColumn("ID"); - SQLContainer container = new SQLContainer(tQuery); - container.setAutoCommit(false); - - /* Check that the container size is correct and there is no 'Viljami' */ - Assert.assertEquals(4, container.size()); - List<Filter> filters = new ArrayList<Filter>(); - filters.add(new Equal("NAME", "Viljami")); - tQuery.setFilters(filters); - Assert.assertEquals(0, tQuery.getCount()); - tQuery.setFilters(null); - - /* Fetch first item, modify and commit */ - Object item = container - .getItem(container.getItemIds().iterator().next()); - Assert.assertNotNull(item); - - RowItem ri = (RowItem) item; - Assert.assertNotNull(ri.getItemProperty("NAME")); - ri.getItemProperty("NAME").setValue("Viljami"); - - container.commit(); - - // Check that the size is still correct and only 1 'Viljami' is found - Assert.assertEquals(4, tQuery.getCount()); - Assert.assertEquals(4, container.size()); - tQuery.setFilters(filters); - Assert.assertEquals(1, tQuery.getCount()); - } - - @Test - public void storeRow_noVersionColumn_shouldSucceed() - throws UnsupportedOperationException, SQLException { - TableQuery tQuery = new TableQuery("people", connectionPool, - SQLTestsConstants.sqlGen); - SQLContainer container = new SQLContainer(tQuery); - Object id = container.addItem(); - RowItem row = (RowItem) container.getItem(id); - row.getItemProperty("NAME").setValue("R2D2"); - row.getItemProperty("AGE").setValue(123); - tQuery.beginTransaction(); - tQuery.storeRow(row); - tQuery.commit(); - - Connection conn = connectionPool.reserveConnection(); - PreparedStatement stmt = conn - .prepareStatement("SELECT * FROM PEOPLE WHERE \"NAME\" = ?"); - stmt.setString(1, "R2D2"); - ResultSet rs = stmt.executeQuery(); - Assert.assertTrue(rs.next()); - rs.close(); - stmt.close(); - connectionPool.releaseConnection(conn); - } - - @Test - public void storeRow_versionSetAndEqualToDBValue_shouldSucceed() - throws SQLException { - DataGenerator.addVersionedData(connectionPool); - - TableQuery tQuery = new TableQuery("versioned", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setVersionColumn("VERSION"); - SQLContainer container = new SQLContainer(tQuery); - RowItem row = (RowItem) container.getItem(container.firstItemId()); - Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); - - row.getItemProperty("TEXT").setValue("asdf"); - container.commit(); - - Connection conn = connectionPool.reserveConnection(); - PreparedStatement stmt = conn - .prepareStatement("SELECT * FROM VERSIONED WHERE \"TEXT\" = ?"); - stmt.setString(1, "asdf"); - ResultSet rs = stmt.executeQuery(); - Assert.assertTrue(rs.next()); - rs.close(); - stmt.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - } - - @Test(expected = OptimisticLockException.class) - public void storeRow_versionSetAndLessThanDBValue_shouldThrowException() - throws SQLException { - if (SQLTestsConstants.db == DB.HSQLDB) { - throw new OptimisticLockException( - "HSQLDB doesn't support row versioning for optimistic locking - don't run this test.", - null); - } - DataGenerator.addVersionedData(connectionPool); - - TableQuery tQuery = new TableQuery("versioned", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setVersionColumn("VERSION"); - SQLContainer container = new SQLContainer(tQuery); - RowItem row = (RowItem) container.getItem(container.firstItemId()); - Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); - - row.getItemProperty("TEXT").setValue("asdf"); - - // Update the version using another connection. - Connection conn = connectionPool.reserveConnection(); - PreparedStatement stmt = conn.prepareStatement( - "UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?"); - stmt.setString(1, "foo"); - stmt.setObject(2, row.getItemProperty("ID").getValue()); - stmt.executeUpdate(); - stmt.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - container.commit(); - } - - @Test - public void removeRow_versionSetAndEqualToDBValue_shouldSucceed() - throws SQLException { - DataGenerator.addVersionedData(connectionPool); - - TableQuery tQuery = new TableQuery("versioned", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setVersionColumn("VERSION"); - SQLContainer container = new SQLContainer(tQuery); - RowItem row = (RowItem) container.getItem(container.firstItemId()); - Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); - - container.removeItem(container.firstItemId()); - container.commit(); - - Connection conn = connectionPool.reserveConnection(); - PreparedStatement stmt = conn - .prepareStatement("SELECT * FROM VERSIONED WHERE \"TEXT\" = ?"); - stmt.setString(1, "Junk"); - ResultSet rs = stmt.executeQuery(); - Assert.assertFalse(rs.next()); - rs.close(); - stmt.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - } - - @Test(expected = OptimisticLockException.class) - public void removeRow_versionSetAndLessThanDBValue_shouldThrowException() - throws SQLException { - if (SQLTestsConstants.db == SQLTestsConstants.DB.HSQLDB) { - // HSQLDB doesn't support versioning, so this is to make the test - // green. - throw new OptimisticLockException(null); - } - DataGenerator.addVersionedData(connectionPool); - - TableQuery tQuery = new TableQuery("versioned", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setVersionColumn("VERSION"); - SQLContainer container = new SQLContainer(tQuery); - RowItem row = (RowItem) container.getItem(container.firstItemId()); - Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); - - // Update the version using another connection. - Connection conn = connectionPool.reserveConnection(); - PreparedStatement stmt = conn.prepareStatement( - "UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?"); - stmt.setString(1, "asdf"); - stmt.setObject(2, row.getItemProperty("ID").getValue()); - stmt.executeUpdate(); - stmt.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - container.removeItem(container.firstItemId()); - container.commit(); - } - - @Test - public void removeRow_throwsOptimisticLockException_shouldStillWork() - throws SQLException { - if (SQLTestsConstants.db == SQLTestsConstants.DB.HSQLDB) { - // HSQLDB doesn't support versioning, so this is to make the test - // green. - return; - } - DataGenerator.addVersionedData(connectionPool); - - TableQuery tQuery = new TableQuery("versioned", connectionPool, - SQLTestsConstants.sqlGen); - tQuery.setVersionColumn("VERSION"); - SQLContainer container = new SQLContainer(tQuery); - RowItem row = (RowItem) container.getItem(container.firstItemId()); - Assert.assertEquals("Junk", row.getItemProperty("TEXT").getValue()); - - // Update the version using another connection. - Connection conn = connectionPool.reserveConnection(); - PreparedStatement stmt = conn.prepareStatement( - "UPDATE VERSIONED SET \"TEXT\" = ? WHERE \"ID\" = ?"); - stmt.setString(1, "asdf"); - stmt.setObject(2, row.getItemProperty("ID").getValue()); - stmt.executeUpdate(); - stmt.close(); - conn.commit(); - connectionPool.releaseConnection(conn); - - Object itemToRemove = container.firstItemId(); - try { - container.removeItem(itemToRemove); - container.commit(); - } catch (OptimisticLockException e) { - // This is expected, refresh and try again. - container.rollback(); - container.removeItem(itemToRemove); - container.commit(); - } - Object id = container.addItem(); - RowItem item = (RowItem) container.getItem(id); - item.getItemProperty("TEXT").setValue("foo"); - container.commit(); - } - - @Test - public void construction_explicitSchema_shouldSucceed() - throws SQLException { - if (SQLTestsConstants.createSchema == null - || SQLTestsConstants.createProductTable == null - || SQLTestsConstants.dropSchema == null) { - // only perform the test on the databases for which the setup and - // cleanup statements are available - return; - } - - // create schema "oaas" and table "product" in it - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - try { - statement.execute(SQLTestsConstants.dropSchema); - } catch (SQLException e) { - // May fail if schema doesn't exist, which is OK. - conn.rollback(); - } - statement.execute(SQLTestsConstants.createSchema); - statement.execute(SQLTestsConstants.createProductTable); - conn.commit(); - - try { - // metadata scanning at query creation time should not fail - TableQuery tq1 = new TableQuery(null, "oaas", "product", - connectionPool, SQLTestsConstants.sqlGen); - Assert.assertNotNull(tq1); - } finally { - // cleanup - might not be an in-memory DB - statement.execute(SQLTestsConstants.dropSchema); - } - - // Cleanup to make test connection pool happy - connectionPool.releaseConnection(conn); - } - - @Test - public void construction_explicitCatalogAndSchema_shouldSucceed() - throws SQLException { - // not all databases support explicit catalogs, test with PostgreSQL - // using database name as catalog - if (SQLTestsConstants.db != SQLTestsConstants.DB.POSTGRESQL - || SQLTestsConstants.createSchema == null - || SQLTestsConstants.createProductTable == null - || SQLTestsConstants.dropSchema == null) { - // only perform the test on the databases for which the setup and - // cleanup statements are available - return; - } - - // create schema "oaas" and table "product" in it - Connection conn = connectionPool.reserveConnection(); - Statement statement = conn.createStatement(); - try { - statement.execute(SQLTestsConstants.dropSchema); - } catch (SQLException e) { - // May fail if schema doesn't exist, which is OK. - conn.rollback(); - } - statement.execute(SQLTestsConstants.createSchema); - statement.execute(SQLTestsConstants.createProductTable); - conn.commit(); - - try { - // metadata scanning at query creation time should not fail - // note that for most DBMS, catalog is just an optional database - // name - TableQuery tq1 = new TableQuery("sqlcontainer", "oaas", "product", - connectionPool, SQLTestsConstants.sqlGen); - Assert.assertNotNull(tq1); - } finally { - // cleanup - might not be an in-memory DB - statement.execute(SQLTestsConstants.dropSchema); - } - } -} diff --git a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java b/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java deleted file mode 100644 index 8a6ee0aa45..0000000000 --- a/server/src/test/java/com/vaadin/data/util/sqlcontainer/query/ValidatingSimpleJDBCConnectionPool.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.data.util.sqlcontainer.query; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.HashSet; -import java.util.Set; -import java.util.logging.Logger; - -import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; -import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool; - -/** - * Connection pool for testing SQLContainer. Ensures that only reserved - * connections are released and that all connections are released before the - * pool is destroyed. - * - * @author Vaadin Ltd - */ -public class ValidatingSimpleJDBCConnectionPool implements JDBCConnectionPool { - - private JDBCConnectionPool realPool; - private Set<Connection> reserved = new HashSet<Connection>(); - private Set<Connection> alreadyReleased = new HashSet<Connection>(); - - public ValidatingSimpleJDBCConnectionPool(String driverName, - String connectionUri, String userName, String password, - int initialConnections, int maxConnections) throws SQLException { - realPool = new SimpleJDBCConnectionPool(driverName, connectionUri, - userName, password, initialConnections, maxConnections); - } - - @Deprecated - public JDBCConnectionPool getRealPool() { - return realPool; - } - - @Override - public Connection reserveConnection() throws SQLException { - Connection c = realPool.reserveConnection(); - reserved.add(c); - return c; - } - - @Override - public void releaseConnection(Connection conn) { - if (conn != null && !reserved.remove(conn)) { - if (alreadyReleased.contains(conn)) { - getLogger().severe("Tried to release connection (" + conn - + ") which has already been released"); - } else { - throw new RuntimeException("Tried to release connection (" - + conn + ") not reserved using reserveConnection"); - } - } - realPool.releaseConnection(conn); - alreadyReleased.add(conn); - - } - - @Override - public void destroy() { - realPool.destroy(); - if (!reserved.isEmpty()) { - throw new RuntimeException( - reserved.size() + " connections never released"); - } - } - - private static Logger getLogger() { - return Logger - .getLogger(ValidatingSimpleJDBCConnectionPool.class.getName()); - } -}
\ No newline at end of file diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/LegacyAbstractFieldListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractfield/LegacyAbstractFieldListenersTest.java deleted file mode 100644 index 5843bd901f..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/abstractfield/LegacyAbstractFieldListenersTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.vaadin.tests.server.component.abstractfield; - -import org.junit.Test; - -import com.vaadin.data.Property.ReadOnlyStatusChangeEvent; -import com.vaadin.data.Property.ReadOnlyStatusChangeListener; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; -import com.vaadin.ui.Table; - -public class LegacyAbstractFieldListenersTest - extends AbstractListenerMethodsTestBase { - - @Test - public void testReadOnlyStatusChangeListenerAddGetRemove() - throws Exception { - testListenerAddGetRemove(Table.class, ReadOnlyStatusChangeEvent.class, - ReadOnlyStatusChangeListener.class); - } - - @Test - public void testValueChangeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Table.class, ValueChangeEvent.class, - ValueChangeListener.class); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java index c7b4fb374c..958b8c4aae 100644 --- a/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java +++ b/server/src/test/java/com/vaadin/tests/server/component/abstractsplitpanel/AbstractSplitPanelDeclarativeTest.java @@ -21,8 +21,8 @@ import com.vaadin.server.Sizeable.Unit; import com.vaadin.tests.design.DeclarativeTestBase; import com.vaadin.ui.AbstractSplitPanel; import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalSplitPanel; -import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.VerticalSplitPanel; @@ -39,14 +39,14 @@ public class AbstractSplitPanelDeclarativeTest public void testWithBothChildren() { String design = "<vaadin-horizontal-split-panel split-position=20.5% " + "min-split-position=20% max-split-position=50px locked " - + "reversed> <vaadin-table /> <vaadin-vertical-layout />" + + "reversed> <vaadin-horizontal-layout /> <vaadin-vertical-layout />" + "</vaadin-horizontal-split-panel>"; AbstractSplitPanel sp = new HorizontalSplitPanel(); sp.setSplitPosition(20.5f, Unit.PERCENTAGE, true); sp.setMinSplitPosition(20, Unit.PERCENTAGE); sp.setMaxSplitPosition(50, Unit.PIXELS); sp.setLocked(true); - sp.addComponent(new Table()); + sp.addComponent(new HorizontalLayout()); sp.addComponent(new VerticalLayout()); testRead(design, sp); testWrite(design, sp); @@ -54,10 +54,10 @@ public class AbstractSplitPanelDeclarativeTest @Test public void testWithFirstChild() { - String design = "<vaadin-vertical-split-panel><vaadin-table caption=\"First slot\"/>" + String design = "<vaadin-vertical-split-panel><vaadin-horizontal-layout caption=\"First slot\"/>" + "</vaadin-vertical-split-panel>"; AbstractSplitPanel sp = new VerticalSplitPanel(); - Table t = new Table(); + HorizontalLayout t = new HorizontalLayout(); t.setCaption("First slot"); sp.addComponent(t); testRead(design, sp); diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java deleted file mode 100644 index 86bb34145f..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/CacheUpdateExceptionCausesTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.tests.server.component.table; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.CacheUpdateException; - -public class CacheUpdateExceptionCausesTest { - @Test - public void testSingleCauseException() { - Table table = new Table(); - Throwable[] causes = new Throwable[] { - new RuntimeException("Broken in one way.") }; - - CacheUpdateException exception = new CacheUpdateException(table, - "Error during Table cache update.", causes); - - Assert.assertSame(causes[0], exception.getCause()); - Assert.assertEquals("Error during Table cache update.", - exception.getMessage()); - } - - @Test - public void testMultipleCauseException() { - Table table = new Table(); - Throwable[] causes = new Throwable[] { - new RuntimeException("Broken in the first way."), - new RuntimeException("Broken in the second way.") }; - - CacheUpdateException exception = new CacheUpdateException(table, - "Error during Table cache update.", causes); - - Assert.assertSame(causes[0], exception.getCause()); - Assert.assertEquals( - "Error during Table cache update. Additional causes not shown.", - exception.getMessage()); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java deleted file mode 100644 index 3df2b8fbcb..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/FooterTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.ui.Table; - -/** - * Test case for testing the footer API - * - */ -public class FooterTest { - - /** - * Tests if setting the footer visibility works properly - */ - @Test - public void testFooterVisibility() { - Table table = new Table("Test table", createContainer()); - - // The footer should by default be hidden - assertFalse(table.isFooterVisible()); - - // Set footer visibility to tru should be reflected in the - // isFooterVisible() method - table.setFooterVisible(true); - assertTrue(table.isFooterVisible()); - } - - /** - * Tests adding footers to the columns - */ - @Test - public void testAddingFooters() { - Table table = new Table("Test table", createContainer()); - - // Table should not contain any footers at initialization - assertNull(table.getColumnFooter("col1")); - assertNull(table.getColumnFooter("col2")); - assertNull(table.getColumnFooter("col3")); - - // Adding column footer - table.setColumnFooter("col1", "Footer1"); - assertEquals("Footer1", table.getColumnFooter("col1")); - - // Add another footer - table.setColumnFooter("col2", "Footer2"); - assertEquals("Footer2", table.getColumnFooter("col2")); - - // Add footer for a non-existing column - table.setColumnFooter("fail", "FooterFail"); - } - - /** - * Test removing footers - */ - @Test - public void testRemovingFooters() { - Table table = new Table("Test table", createContainer()); - table.setColumnFooter("col1", "Footer1"); - table.setColumnFooter("col2", "Footer2"); - - // Test removing footer - assertNotNull(table.getColumnFooter("col1")); - table.setColumnFooter("col1", null); - assertNull(table.getColumnFooter("col1")); - - // The other footer should still be there - assertNotNull(table.getColumnFooter("col2")); - - // Remove non-existing footer - table.setColumnFooter("fail", null); - } - - /** - * Creates a container with three properties "col1,col2,col3" with 100 items - * - * @return Returns the created table - */ - private static Container createContainer() { - IndexedContainer container = new IndexedContainer(); - container.addContainerProperty("col1", String.class, ""); - container.addContainerProperty("col2", String.class, ""); - container.addContainerProperty("col3", String.class, ""); - - for (int i = 0; i < 100; i++) { - Item item = container.addItem("item " + i); - item.getItemProperty("col1").setValue("first" + i); - item.getItemProperty("col2").setValue("middle" + i); - item.getItemProperty("col3").setValue("last" + i); - } - - return container; - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java deleted file mode 100644 index b29357ea6a..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/MultipleSelectionTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.Set; - -import org.junit.Test; - -import com.vaadin.data.Container; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.shared.ui.MultiSelectMode; -import com.vaadin.ui.Table; - -public class MultipleSelectionTest { - - /** - * Tests weather the multiple select mode is set when using Table.set - */ - @Test - @SuppressWarnings("unchecked") - public void testSetMultipleItems() { - Table table = new Table("", createTestContainer()); - - // Tests if multiple selection is set - table.setMultiSelect(true); - assertTrue(table.isMultiSelect()); - - // Test multiselect by setting several items at once - - table.setValue(Arrays.asList("1", new String[] { "3" })); - assertEquals(2, ((Set<String>) table.getValue()).size()); - } - - /** - * Tests setting the multiselect mode of the Table. The multiselect mode - * affects how mouse selection is made in the table by the user. - */ - @Test - public void testSetMultiSelectMode() { - Table table = new Table("", createTestContainer()); - - // Default multiselect mode should be MultiSelectMode.DEFAULT - assertEquals(MultiSelectMode.DEFAULT, table.getMultiSelectMode()); - - // Tests if multiselectmode is set - table.setMultiSelectMode(MultiSelectMode.SIMPLE); - assertEquals(MultiSelectMode.SIMPLE, table.getMultiSelectMode()); - } - - /** - * Creates a testing container for the tests - * - * @return A new container with test items - */ - private Container createTestContainer() { - IndexedContainer container = new IndexedContainer( - Arrays.asList("1", new String[] { "2", "3", "4" })); - return container; - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java deleted file mode 100644 index ff4c8336fb..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableColumnAlignmentsTest.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import static org.junit.Assert.assertArrayEquals; - -import org.junit.Test; - -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.Align; - -public class TableColumnAlignmentsTest { - - @Test - public void defaultColumnAlignments() { - for (int properties = 0; properties < 10; properties++) { - Table t = TableGeneratorTest - .createTableWithDefaultContainer(properties, 10); - Object[] expected = new Object[properties]; - for (int i = 0; i < properties; i++) { - expected[i] = Align.LEFT; - } - org.junit.Assert.assertArrayEquals("getColumnAlignments", expected, - t.getColumnAlignments()); - } - } - - @Test - public void explicitColumnAlignments() { - int properties = 5; - Table t = TableGeneratorTest.createTableWithDefaultContainer(properties, - 10); - Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT, - Align.RIGHT, Align.RIGHT, Align.LEFT }; - - t.setColumnAlignments(explicitAlignments); - - assertArrayEquals("Explicit visible columns, 5 properties", - explicitAlignments, t.getColumnAlignments()); - } - - @Test - public void invalidColumnAlignmentStrings() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 7); - Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT, - Align.LEFT }; - try { - t.setColumnAlignments(new Align[] { Align.RIGHT, Align.RIGHT }); - junit.framework.Assert - .fail("No exception thrown for invalid array length"); - } catch (IllegalArgumentException e) { - // Ok, expected - } - - assertArrayEquals("Invalid change affected alignments", - defaultAlignments, t.getColumnAlignments()); - - } - - @Test - public void columnAlignmentForPropertyNotInContainer() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 7); - Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT, - Align.LEFT }; - try { - t.setColumnAlignment("Property 1200", Align.LEFT); - // FIXME: Uncomment as there should be an exception (#6475) - // junit.framework.Assert - // .fail("No exception thrown for property not in container"); - } catch (IllegalArgumentException e) { - // Ok, expected - } - - assertArrayEquals("Invalid change affected alignments", - defaultAlignments, t.getColumnAlignments()); - - // FIXME: Uncomment as null should be returned (#6474) - // junit.framework.Assert.assertEquals( - // "Column alignment for property not in container returned", - // null, t.getColumnAlignment("Property 1200")); - - } - - @Test - public void invalidColumnAlignmentsLength() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(7, 7); - Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT, - Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT }; - - try { - t.setColumnAlignments(new Align[] { Align.LEFT }); - junit.framework.Assert - .fail("No exception thrown for invalid array length"); - } catch (IllegalArgumentException e) { - // Ok, expected - } - assertArrayEquals("Invalid change affected alignments", - defaultAlignments, t.getColumnAlignments()); - - try { - t.setColumnAlignments(new Align[] {}); - junit.framework.Assert - .fail("No exception thrown for invalid array length"); - } catch (IllegalArgumentException e) { - // Ok, expected - } - assertArrayEquals("Invalid change affected alignments", - defaultAlignments, t.getColumnAlignments()); - - try { - t.setColumnAlignments(new Align[] { Align.LEFT, Align.LEFT, - Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, - Align.LEFT }); - junit.framework.Assert - .fail("No exception thrown for invalid array length"); - } catch (IllegalArgumentException e) { - // Ok, expected - } - assertArrayEquals("Invalid change affected alignments", - defaultAlignments, t.getColumnAlignments()); - - } - - @Test - public void explicitColumnAlignmentOneByOne() { - int properties = 5; - Table t = TableGeneratorTest.createTableWithDefaultContainer(properties, - 10); - Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT, - Align.RIGHT, Align.RIGHT, Align.LEFT }; - - Align[] currentAlignments = new Align[] { Align.LEFT, Align.LEFT, - Align.LEFT, Align.LEFT, Align.LEFT }; - - for (int i = 0; i < properties; i++) { - t.setColumnAlignment("Property " + i, explicitAlignments[i]); - currentAlignments[i] = explicitAlignments[i]; - - assertArrayEquals( - "Explicit visible columns, " + i + " alignments set", - currentAlignments, t.getColumnAlignments()); - } - - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java deleted file mode 100644 index 3ee8b76d76..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableContextClickTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.table; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.event.ContextClickEvent; -import com.vaadin.event.ContextClickEvent.ContextClickListener; -import com.vaadin.shared.ui.table.TableConstants.Section; -import com.vaadin.ui.Table; - -public class TableContextClickTest extends Table { - - private String error = null; - private boolean handled = false; - - @Test - public void testContextClickListenerWithTableEvent() { - addContextClickListener(new ContextClickListener() { - - @Override - public void contextClick(ContextClickEvent event) { - if (!(event instanceof TableContextClickEvent)) { - return; - } - - TableContextClickEvent e = (TableContextClickEvent) event; - if (e.getSection() != Section.BODY) { - error = "Event section was not BODY."; - } - handled = true; - } - }); - fireEvent(new TableContextClickEvent(this, null, null, null, - Section.BODY)); - - if (error != null) { - Assert.fail(error); - } else if (!handled) { - Assert.fail("Event was not handled by the ContextClickListener"); - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java deleted file mode 100644 index f3b9b1cece..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.table; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.server.ExternalResource; -import com.vaadin.shared.ui.MultiSelectMode; -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.Align; -import com.vaadin.ui.Table.ColumnHeaderMode; -import com.vaadin.ui.Table.RowHeaderMode; -import com.vaadin.ui.Table.TableDragMode; -import com.vaadin.ui.declarative.Design; - -/** - * Test declarative support for {@link Table}. - * - * @since - * @author Vaadin Ltd - */ -public class TableDeclarativeTest extends TableDeclarativeTestBase { - - @Test - public void testBasicAttributes() { - - String design = "<" + getTag() - + " page-length=30 cache-rate=3 selectable editable " - + "sortable=false sort-ascending=false sort-container-property-id=foo " - + "drag-mode=row multi-select-mode=simple column-header-mode=id row-header-mode=id " - + "column-reordering-allowed column-collapsing-allowed />"; - - Table table = getTable(); - table.setPageLength(30); - table.setCacheRate(3); - table.setSelectable(true); - table.setEditable(true); - - table.setSortEnabled(false); - table.setSortAscending(false); - table.setSortContainerPropertyId("foo"); - - table.setDragMode(TableDragMode.ROW); - table.setMultiSelectMode(MultiSelectMode.SIMPLE); - table.setColumnHeaderMode(ColumnHeaderMode.ID); - table.setRowHeaderMode(RowHeaderMode.ID); - - table.setColumnReorderingAllowed(true); - table.setColumnCollapsingAllowed(true); - - testRead(design, table); - testWrite(design, table); - } - - @Test - public void testColumns() { - String design = "<" + getTag() + " column-collapsing-allowed>" // - + " <table>" // - + " <colgroup>" + " <col property-id='foo' width=300>" - + " <col property-id='bar' center expand=1 collapsible=false>" - + " <col property-id='baz' right expand=2 collapsed>" - + " </colgroup>" // - + " </table>"; - - Table table = getTable(); - table.setColumnCollapsingAllowed(true); - - table.addContainerProperty("foo", String.class, null); - table.setColumnAlignment("foo", Align.LEFT); - table.setColumnWidth("foo", 300); - - table.addContainerProperty("bar", String.class, null); - table.setColumnAlignment("bar", Align.CENTER); - table.setColumnExpandRatio("bar", 1); - table.setColumnCollapsible("bar", false); - - table.addContainerProperty("baz", String.class, null); - table.setColumnAlignment("baz", Align.RIGHT); - table.setColumnExpandRatio("baz", 2); - table.setColumnCollapsed("baz", true); - - testRead(design, table); - testWrite(design, table); - } - - @Test - public void testHeadersFooters() { - String design = "<" + getTag() + ">" // - + " <table>" // - + " <colgroup><col property-id=foo><col property-id=bar></colgroup>" // - + " <thead>" // - + " <tr><th icon='http://example.com/icon.png'>FOO<th>BAR" // - + " </thead>" // - + " <tfoot>" // - + " <tr><td>foo<td>bar" // - + " </tfoot>" // - + " </table>"; - - Table table = getTable(); - table.setFooterVisible(true); - - table.addContainerProperty("foo", String.class, null); - table.setColumnHeader("foo", "FOO"); - table.setColumnIcon("foo", - new ExternalResource("http://example.com/icon.png")); - table.setColumnFooter("foo", "foo"); - - table.addContainerProperty("bar", String.class, null); - table.setColumnHeader("bar", "BAR"); - table.setColumnFooter("bar", "bar"); - - testRead(design, table); - testWrite(design, table); - } - - @Test - public void testInlineData() { - String design = "<" + getTag() + ">" // - + " <table>" // - + " <colgroup>" + " <col property-id='foo' />" - + " <col property-id='bar' />" - + " <col property-id='baz' />" // - + " </colgroup>" + " <thead>" - + " <tr><th>Description<th>Milestone<th>Status</tr>" - + " </thead>" + " <tbody>" - + " <tr item-id=1><td>r1c1</td><td>r1c2</td><td>r1c3</td>" // - + " <tr item-id=2><td>r2c1</td><td>r2c2</td><td>r2c3</td>" // - + " </tbody>" // - + " <tfoot>" // - + " <tr><td>F1<td>F2<td>F3</tr>" // - + " </tfoot>" // - + " </table>"; - - Table table = getTable(); - table.addContainerProperty("foo", String.class, null); - table.addContainerProperty("bar", String.class, null); - table.addContainerProperty("baz", String.class, null); - table.setColumnHeaders("Description", "Milestone", "Status"); - table.setColumnFooter("foo", "F1"); - table.setColumnFooter("bar", "F2"); - table.setColumnFooter("baz", "F3"); - table.addItem(new Object[] { "r1c1", "r1c2", "r1c3" }, "1"); - table.addItem(new Object[] { "r2c1", "r2c2", "r2c3" }, "2"); - table.setFooterVisible(true); - - testRead(design, table); - testWrite(design, table, true); - } - - @Test - public void testHtmlEntities() { - String design = "<v-table>" + "<table>" + " <colgroup>" - + " <col property-id=\"test\"" + " </colgroup>" - + " <thead>" + " <tr><th>& Test</th></tr>" - + " </thead>" + " <tbody>" - + " <tr item-id=\"test\"><td>& Test</tr>" + " </tbody>" - + " <tfoot>" + " <tr><td>& Test</td></tr>" - + " </tfoot>" + "</table>" + "</v-table>"; - Table read = read(design); - - Assert.assertEquals("& Test", - read.getContainerProperty("test", "test").getValue()); - Assert.assertEquals("& Test", read.getColumnHeader("test")); - Assert.assertEquals("& Test", read.getColumnFooter("test")); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java deleted file mode 100644 index 7a7b13e933..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableDeclarativeTestBase.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.table; - -import static org.junit.Assert.assertTrue; - -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.Table; - -public abstract class TableDeclarativeTestBase - extends DeclarativeTestBase<Table> { - - @Override - public Table testRead(String design, Table expected) { - Table read = super.testRead(design, expected); - compareColumns(read, expected); - compareBody(read, expected); - return read; - } - - protected Table getTable() { - return new Table(); - } - - protected String getTag() { - return "vaadin-table"; - } - - protected void compareBody(Table read, Table expected) { - assertEquals("number of items", expected.getItemIds().size(), - read.getItemIds().size()); - for (Object rowId : expected.getItemIds()) { - assertTrue(read.containsId(rowId)); - for (Object propertyId : read.getVisibleColumns()) { - Object expectedItem = expected.getContainerProperty(rowId, - propertyId); - Object readItem = read.getContainerProperty(rowId, propertyId); - assertEquals("property '" + propertyId + "'", expectedItem, - readItem); - } - } - } - - protected void compareColumns(Table read, Table expected) { - for (Object pid : expected.getVisibleColumns()) { - String col = "column '" + pid + "'"; - assertEquals(col + " width", expected.getColumnWidth(pid), - read.getColumnWidth(pid)); - assertEquals(col + " expand ratio", - expected.getColumnExpandRatio(pid), - read.getColumnExpandRatio(pid)); - assertEquals(col + " collapsible", - expected.isColumnCollapsible(pid), - read.isColumnCollapsible(pid)); - assertEquals(col + " collapsed", expected.isColumnCollapsed(pid), - read.isColumnCollapsed(pid)); - assertEquals(col + " footer", expected.getColumnFooter(pid), - read.getColumnFooter(pid)); - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java deleted file mode 100644 index 6fbe5557f8..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableGeneratorTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import org.junit.Test; - -import com.vaadin.data.Item; -import com.vaadin.ui.Table; - -public class TableGeneratorTest { - public static Table createTableWithDefaultContainer(int properties, - int items) { - Table t = new Table(); - - for (int i = 0; i < properties; i++) { - t.addContainerProperty("Property " + i, String.class, null); - } - - for (int j = 0; j < items; j++) { - Item item = t.addItem("Item " + j); - for (int i = 0; i < properties; i++) { - item.getItemProperty("Property " + i) - .setValue("Item " + j + "/Property " + i); - } - } - - return t; - } - - @Test - public void testTableGenerator() { - Table t = createTableWithDefaultContainer(1, 1); - junit.framework.Assert.assertEquals(t.size(), 1); - junit.framework.Assert.assertEquals(t.getContainerPropertyIds().size(), - 1); - - t = createTableWithDefaultContainer(100, 50); - junit.framework.Assert.assertEquals(t.size(), 50); - junit.framework.Assert.assertEquals(t.getContainerPropertyIds().size(), - 100); - - } - -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java deleted file mode 100644 index ac6fb171e3..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableListenersTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import org.junit.Test; - -import com.vaadin.event.ItemClickEvent; -import com.vaadin.event.ItemClickEvent.ItemClickListener; -import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.ColumnReorderEvent; -import com.vaadin.ui.Table.ColumnReorderListener; -import com.vaadin.ui.Table.ColumnResizeEvent; -import com.vaadin.ui.Table.ColumnResizeListener; -import com.vaadin.ui.Table.FooterClickEvent; -import com.vaadin.ui.Table.FooterClickListener; -import com.vaadin.ui.Table.HeaderClickEvent; -import com.vaadin.ui.Table.HeaderClickListener; - -public class TableListenersTest extends AbstractListenerMethodsTestBase { - - @Test - public void testColumnResizeListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Table.class, ColumnResizeEvent.class, - ColumnResizeListener.class); - } - - @Test - public void testItemClickListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Table.class, ItemClickEvent.class, - ItemClickListener.class); - } - - @Test - public void testFooterClickListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Table.class, FooterClickEvent.class, - FooterClickListener.class); - } - - @Test - public void testHeaderClickListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Table.class, HeaderClickEvent.class, - HeaderClickListener.class); - } - - @Test - public void testColumnReorderListenerAddGetRemove() throws Exception { - testListenerAddGetRemove(Table.class, ColumnReorderEvent.class, - ColumnReorderListener.class); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java deleted file mode 100644 index 5a9297014c..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TablePropertyValueConverterTest.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.table; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.lang.reflect.Field; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map.Entry; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.ui.Table; -import com.vaadin.v7.data.util.converter.LegacyConverter; - -public class TablePropertyValueConverterTest { - protected TestableTable table; - protected Collection<?> initialProperties; - - @Test - public void testRemovePropertyId() { - Collection<Object> converters = table.getCurrentConverters(); - assertTrue("Set of converters was empty at the start.", - converters.size() > 0); - - Object firstId = converters.iterator().next(); - - table.removeContainerProperty(firstId); - - Collection<Object> converters2 = table.getCurrentConverters(); - assertTrue("FirstId was not removed", !converters2.contains(firstId)); - - assertTrue("The number of removed converters was not one.", - converters.size() - converters2.size() == 1); - - for (Object originalId : converters) { - if (!originalId.equals(firstId)) { - assertTrue("The wrong converter was removed.", - converters2.contains(originalId)); - } - } - - } - - @Test - public void testSetContainer() { - table.setContainerDataSource(createContainer( - new String[] { "col1", "col3", "col4", "col5" })); - Collection<Object> converters = table.getCurrentConverters(); - assertTrue("There should only have been one converter left.", - converters.size() == 1); - Object onlyKey = converters.iterator().next(); - assertTrue("The incorrect key was left.", onlyKey.equals("col1")); - - } - - @Test - public void testSetContainerWithInexactButCompatibleTypes() { - TestableTable customTable = new TestableTable("Test table", - createContainer(new String[] { "col1", "col2", "col3" }, - new Class[] { String.class, BaseClass.class, - DerivedClass.class })); - customTable.setConverter("col1", new LegacyConverter<String, String>() { - private static final long serialVersionUID = 1L; - - @Override - public String convertToModel(String value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "model"; - } - - @Override - public String convertToPresentation(String value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "presentation"; - } - - @Override - public Class<String> getModelType() { - return String.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - - }); - customTable.setConverter("col2", - new LegacyConverter<String, BaseClass>() { - private static final long serialVersionUID = 1L; - - @Override - public BaseClass convertToModel(String value, - Class<? extends BaseClass> targetType, - Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return new BaseClass("model"); - } - - @Override - public Class<BaseClass> getModelType() { - return BaseClass.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - - @Override - public String convertToPresentation(BaseClass value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return null; - } - }); - customTable.setConverter("col3", - new LegacyConverter<String, DerivedClass>() { - private static final long serialVersionUID = 1L; - - @Override - public DerivedClass convertToModel(String value, - Class<? extends DerivedClass> targetType, - Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return new DerivedClass("derived" + 1001); - } - - @Override - public Class<DerivedClass> getModelType() { - return DerivedClass.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - - @Override - public String convertToPresentation(DerivedClass value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return null; - } - }); - customTable.setContainerDataSource( - createContainer(new String[] { "col1", "col2", "col3" }, - new Class[] { DerivedClass.class, DerivedClass.class, - BaseClass.class })); - Set<Object> converters = customTable.getCurrentConverters(); - // TODO Test temporarily disabled as this feature - // is not yet implemented in Table - /* - * assertTrue("Incompatible types were not removed.", converters.size() - * <= 1); assertTrue("Even compatible types were removed", - * converters.size() == 1); assertTrue("Compatible type was missing.", - * converters.contains("col2")); - */ - } - - @Test - public void testPrimitiveTypeConverters() { - TestableTable customTable = new TestableTable("Test table", - createContainer(new String[] { "col1", "col2", "col3" }, - new Class[] { int.class, BaseClass.class, - DerivedClass.class })); - customTable.setConverter("col1", - new LegacyConverter<String, Integer>() { - private static final long serialVersionUID = 1L; - - @Override - public Integer convertToModel(String value, - Class<? extends Integer> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return 11; - } - - @Override - public String convertToPresentation(Integer value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "presentation"; - } - - @Override - public Class<Integer> getModelType() { - return Integer.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - }); - Set<Object> converters = customTable.getCurrentConverters(); - assertTrue("Converter was not set.", converters.size() > 0); - } - - @Test - public void testInheritance() { - assertTrue("BaseClass isn't assignable from DerivedClass", - BaseClass.class.isAssignableFrom(DerivedClass.class)); - assertFalse("DerivedClass is assignable from BaseClass", - DerivedClass.class.isAssignableFrom(BaseClass.class)); - } - - @Before - public void setUp() { - table = new TestableTable("Test table", - createContainer(new String[] { "col1", "col2", "col3" })); - table.setConverter("col1", new LegacyConverter<String, String>() { - private static final long serialVersionUID = 1L; - - @Override - public String convertToModel(String value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "model"; - } - - @Override - public String convertToPresentation(String value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "presentation"; - } - - @Override - public Class<String> getModelType() { - return String.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - - }); - - table.setConverter("col2", new LegacyConverter<String, String>() { - private static final long serialVersionUID = 1L; - - @Override - public String convertToModel(String value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "model2"; - } - - @Override - public String convertToPresentation(String value, - Class<? extends String> targetType, Locale locale) - throws com.vaadin.v7.data.util.converter.LegacyConverter.ConversionException { - return "presentation2"; - } - - @Override - public Class<String> getModelType() { - return String.class; - } - - @Override - public Class<String> getPresentationType() { - return String.class; - } - - }); - - initialProperties = table.getContainerPropertyIds(); - } - - private static Container createContainer(Object[] ids) { - Class[] types = new Class[ids.length]; - for (int i = 0; i < types.length; ++i) { - types[i] = String.class; - } - return createContainer(ids, types); - } - - private static Container createContainer(Object[] ids, Class[] types) { - IndexedContainer container = new IndexedContainer(); - if (ids.length > types.length) { - throw new IllegalArgumentException("Too few defined types"); - } - for (int i = 0; i < ids.length; ++i) { - container.addContainerProperty(ids[i], types[i], ""); - } - - for (int i = 0; i < 100; i++) { - Item item = container.addItem("item " + i); - for (int j = 0; j < ids.length; ++j) { - Property itemProperty = item.getItemProperty(ids[j]); - if (types[j] == String.class) { - itemProperty.setValue(ids[j].toString() + i); - } else if (types[j] == BaseClass.class) { - itemProperty.setValue(new BaseClass("base" + i)); - } else if (types[j] == DerivedClass.class) { - itemProperty.setValue(new DerivedClass("derived" + i)); - } else if (types[j] == int.class) { - // FIXME can't set values because the int is autoboxed into - // an Integer and not unboxed prior to set - - // itemProperty.setValue(i); - } else { - throw new IllegalArgumentException( - "Unhandled type in createContainer: " + types[j]); - } - } - } - - return container; - } - - private class TestableTable extends Table { - /** - * @param string - * @param createContainer - */ - public TestableTable(String string, Container container) { - super(string, container); - } - - Set<Object> getCurrentConverters() { - try { - Field f = Table.class - .getDeclaredField("propertyValueConverters"); - f.setAccessible(true); - HashMap<Object, LegacyConverter<String, Object>> pvc = (HashMap<Object, LegacyConverter<String, Object>>) f - .get(this); - Set<Object> currentConverters = new HashSet<Object>(); - for (Entry<Object, LegacyConverter<String, Object>> entry : pvc - .entrySet()) { - currentConverters.add(entry.getKey()); - } - return currentConverters; - - } catch (Exception e) { - fail("Unable to retrieve propertyValueConverters"); - return null; - } - } - } - - private static class BaseClass { - private String title; - - public BaseClass(String title) { - this.title = title; - } - } - - private static class DerivedClass extends BaseClass { - public DerivedClass(String title) { - super(title); - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableSelectableTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableSelectableTest.java deleted file mode 100644 index 906827958f..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableSelectableTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.table; - -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.ui.Table; - -/** - * Tests for 'selectable' property of {@link Table} class. - * - * @author Vaadin Ltd - */ -public class TableSelectableTest { - - @Test - public void setSelectable_explicitSelectable_tableIsSelectable() { - Table table = new Table(); - table.setSelectable(true); - - Assert.assertTrue(table.isSelectable()); - } - - @Test - public void addValueChangeListener_explicitSelectable_tableIsSelectable() { - TestTable table = new TestTable(); - table.addValueChangeListener( - EasyMock.createMock(ValueChangeListener.class)); - - Assert.assertTrue(table.isSelectable()); - Assert.assertTrue(table.markAsDirtyCalled); - } - - @Test - public void tableIsNotSelectableByDefult() { - Table table = new Table(); - - Assert.assertFalse(table.isSelectable()); - } - - @Test - public void setSelectable_explicitNotSelectable_tableIsNotSelectable() { - Table table = new Table(); - table.setSelectable(false); - table.addValueChangeListener( - EasyMock.createMock(ValueChangeListener.class)); - - Assert.assertFalse(table.isSelectable()); - } - - private static final class TestTable extends Table { - @Override - public void markAsDirty() { - markAsDirtyCalled = true; - } - - private boolean markAsDirtyCalled; - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java deleted file mode 100644 index 22f2381980..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableSerializationTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import org.apache.commons.lang.SerializationUtils; -import org.junit.Test; - -import com.vaadin.ui.Table; - -public class TableSerializationTest { - - @Test - public void testSerialization() { - Table t = new Table(); - byte[] ser = SerializationUtils.serialize(t); - Table t2 = (Table) SerializationUtils.deserialize(ser); - - } - - @Test - public void testSerializationWithRowHeaders() { - Table t = new Table(); - t.setRowHeaderMode(Table.ROW_HEADER_MODE_EXPLICIT); - t.setColumnWidth(null, 100); - byte[] ser = SerializationUtils.serialize(t); - Table t2 = (Table) SerializationUtils.deserialize(ser); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java deleted file mode 100644 index 43b03c41e8..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableStateTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.table; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.shared.ui.table.TableState; -import com.vaadin.ui.Table; - -/** - * Tests for Table State. - * - */ -public class TableStateTest { - - @Test - public void getState_tableHasCustomState() { - TestTable table = new TestTable(); - TableState state = table.getState(); - Assert.assertEquals("Unexpected state class", TableState.class, - state.getClass()); - } - - @Test - public void getPrimaryStyleName_tableHasCustomPrimaryStyleName() { - Table table = new Table(); - TableState state = new TableState(); - Assert.assertEquals("Unexpected primary style name", - state.primaryStyleName, table.getPrimaryStyleName()); - } - - @Test - public void tableStateHasCustomPrimaryStyleName() { - TableState state = new TableState(); - Assert.assertEquals("Unexpected primary style name", "v-table", - state.primaryStyleName); - } - - private static class TestTable extends Table { - - @Override - public TableState getState() { - return super.getState(); - } - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java b/server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java deleted file mode 100644 index f9f6e7f979..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/table/TableVisibleColumnsTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.vaadin.tests.server.component.table; - -import static org.junit.Assert.assertArrayEquals; - -import org.junit.Test; - -import com.vaadin.ui.Table; - -public class TableVisibleColumnsTest { - - String[] defaultColumns3 = new String[] { "Property 0", "Property 1", - "Property 2" }; - - @Test - public void defaultVisibleColumns() { - for (int properties = 0; properties < 10; properties++) { - Table t = TableGeneratorTest - .createTableWithDefaultContainer(properties, 10); - Object[] expected = new Object[properties]; - for (int i = 0; i < properties; i++) { - expected[i] = "Property " + i; - } - org.junit.Assert.assertArrayEquals("getVisibleColumns", expected, - t.getVisibleColumns()); - } - } - - @Test - public void explicitVisibleColumns() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(5, 10); - Object[] newVisibleColumns = new Object[] { "Property 1", - "Property 2" }; - t.setVisibleColumns(newVisibleColumns); - assertArrayEquals("Explicit visible columns, 5 properties", - newVisibleColumns, t.getVisibleColumns()); - - } - - @Test - public void invalidVisibleColumnIds() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10); - - try { - t.setVisibleColumns( - new Object[] { "a", "Property 2", "Property 3" }); - junit.framework.Assert.fail("IllegalArgumentException expected"); - } catch (IllegalArgumentException e) { - // OK, expected - } - assertArrayEquals(defaultColumns3, t.getVisibleColumns()); - } - - @Test - public void duplicateVisibleColumnIds() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10); - try { - t.setVisibleColumns(new Object[] { "Property 0", "Property 1", - "Property 2", "Property 1" }); - } catch (IllegalArgumentException e) { - // OK, expected - } - assertArrayEquals(defaultColumns3, t.getVisibleColumns()); - } - - @Test - public void noVisibleColumns() { - Table t = TableGeneratorTest.createTableWithDefaultContainer(3, 10); - t.setVisibleColumns(new Object[] {}); - assertArrayEquals(new Object[] {}, t.getVisibleColumns()); - - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java deleted file mode 100644 index 2a667bea72..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/treetable/EmptyTreeTableTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.vaadin.tests.server.component.treetable; - -import static org.junit.Assert.assertFalse; - -import org.junit.Test; - -import com.vaadin.ui.TreeTable; - -public class EmptyTreeTableTest { - - @Test - public void testLastId() { - TreeTable treeTable = new TreeTable(); - - assertFalse(treeTable.isLastId(treeTable.getValue())); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java deleted file mode 100644 index eb25bcb0aa..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableDeclarativeTest.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.treetable; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.tests.server.component.table.TableDeclarativeTest; -import com.vaadin.ui.Table; -import com.vaadin.ui.TreeTable; -import com.vaadin.ui.declarative.DesignException; - -/** - * Test declarative support for {@link TreeTable}. - * - * @since - * @author Vaadin Ltd - */ -public class TreeTableDeclarativeTest extends TableDeclarativeTest { - - @Test - public void testAttributes() { - String design = "<vaadin-tree-table animations-enabled>"; - TreeTable table = getTable(); - table.setAnimationsEnabled(true); - - testRead(design, table); - testWrite(design, table); - } - - @Test - public void testHierarchy() { - String design = "<vaadin-tree-table>" // - + "<table>" // - + "<colgroup><col property-id=''></colgroup>" // - + "<tbody>" // - + " <tr item-id='1'><td></tr>" // - + " <tr depth=1 item-id='1.1'><td></tr>" // - + " <tr depth=1 item-id='1.2'><td></tr>" // - + " <tr depth=2 item-id='1.2.1'><td></tr>" // - + " <tr depth=3 item-id='1.2.1.1'><td></tr>" // - + " <tr depth=2 item-id='1.2.2'><td></tr>" // - + " <tr item-id='2'><td></tr>" // - + " <tr depth=1 item-id='2.1'><td></tr>" // - + "</tbody>" // - + "</table>" // - + "</vaadin-tree-table>"; - - TreeTable table = getTable(); - table.addContainerProperty("", String.class, ""); - - table.addItem("1"); - table.addItem("1.1"); - table.setParent("1.1", "1"); - table.addItem("1.2"); - table.setParent("1.2", "1"); - table.addItem("1.2.1"); - table.setParent("1.2.1", "1.2"); - table.addItem("1.2.1.1"); - table.setParent("1.2.1.1", "1.2.1"); - table.addItem("1.2.2"); - table.setParent("1.2.2", "1.2"); - table.addItem("2"); - table.addItem("2.1"); - table.setParent("2.1", "2"); - - testRead(design, table); - testWrite(design, table, true); - } - - @Test - public void testCollapsed() { - String design = "<vaadin-tree-table>" // - + " <table>" // - + " <colgroup><col property-id=''></colgroup>" // - + " <tbody>" // - + " <tr item-id='1' collapsed=false><td></tr>" // - + " <tr depth=1 item-id='1.1'><td></tr>" // - + " <tr depth=2 item-id='1.1.1'><td></tr>" // - + " </tbody>" // - + " </table>" // - + "</vaadin-tree-table>"; - - TreeTable table = getTable(); - table.addContainerProperty("", String.class, ""); - - table.addItem("1"); - table.setCollapsed("1", false); - table.addItem("1.1"); - table.setParent("1.1", "1"); - table.addItem("1.1.1"); - table.setParent("1.1.1", "1.1"); - - testRead(design, table); - testWrite(design, table, true); - } - - @Test - public void testMalformedHierarchy() { - assertMalformed("<tr depth=-4><td>"); - assertMalformed("<tr depth=1><td>"); - assertMalformed("<tr><td><tr depth=3><td>"); - } - - protected void assertMalformed(String hierarchy) { - String design = "<vaadin-tree-table>" // - + " <table>" // - + " <colgroup><col property-id=''></colgroup>" // - + " <tbody>" + hierarchy + "</tbody>" // - + " </table>" // - + "</vaadin-tree-table>"; - - try { - read(design); - Assert.fail("Malformed hierarchy should fail: " + hierarchy); - } catch (DesignException expected) { - } - } - - @Override - protected void compareBody(Table read, Table expected) { - super.compareBody(read, expected); - - for (Object itemId : read.getItemIds()) { - Assert.assertEquals("parent of item " + itemId, - ((TreeTable) expected).getParent(itemId), - ((TreeTable) read).getParent(itemId)); - Assert.assertEquals("collapsed status of item " + itemId, - ((TreeTable) expected).isCollapsed(itemId), - ((TreeTable) read).isCollapsed(itemId)); - } - } - - @Override - protected TreeTable getTable() { - return new TreeTable(); - } - - @Override - protected String getTag() { - return "vaadin-tree-table"; - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java deleted file mode 100644 index 9718d24f8c..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableSetContainerNullTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.vaadin.tests.server.component.treetable; - -import org.junit.Test; - -import com.vaadin.ui.TreeTable; - -public class TreeTableSetContainerNullTest { - - @Test - public void testNullContainer() { - TreeTable treeTable = new TreeTable(); - - // should not cause an exception - treeTable.setContainerDataSource(null); - } -} diff --git a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java b/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java deleted file mode 100644 index 4706ec1413..0000000000 --- a/server/src/test/java/com/vaadin/tests/server/component/treetable/TreeTableTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2000-2016 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component.treetable; - -import java.util.EnumSet; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.shared.ui.treetable.TreeTableState; -import com.vaadin.ui.Table.RowHeaderMode; -import com.vaadin.ui.TreeTable; - -/** - * Tests for {@link TreeTable} - * - * @author Vaadin Ltd - */ -public class TreeTableTest { - - @Test - public void rowHeadersAreEnabled_iconRowHeaderMode_rowHeadersAreDisabled() { - TestTreeTable tree = new TestTreeTable(); - tree.setRowHeaderMode(RowHeaderMode.ICON_ONLY); - - Assert.assertFalse("Row headers are enabled for Icon header mode", - tree.rowHeadersAreEnabled()); - } - - @Test - public void rowHeadersAreEnabled_hiddenRowHeaderMode_rowHeadersAreDisabled() { - TestTreeTable tree = new TestTreeTable(); - tree.setRowHeaderMode(RowHeaderMode.HIDDEN); - - Assert.assertFalse("Row headers are enabled for Hidden header mode", - tree.rowHeadersAreEnabled()); - } - - @Test - public void rowHeadersAreEnabled_otherRowHeaderModes_rowHeadersAreEnabled() { - TestTreeTable tree = new TestTreeTable(); - EnumSet<RowHeaderMode> modes = EnumSet.allOf(RowHeaderMode.class); - modes.remove(RowHeaderMode.ICON_ONLY); - modes.remove(RowHeaderMode.HIDDEN); - - for (RowHeaderMode mode : modes) { - tree.setRowHeaderMode(mode); - Assert.assertTrue( - "Row headers are disabled for " + mode + " header mode", - tree.rowHeadersAreEnabled()); - } - } - - @Test - public void getState_treeTableHasCustomState() { - TestTreeTable table = new TestTreeTable(); - TreeTableState state = table.getState(); - Assert.assertEquals("Unexpected state class", TreeTableState.class, - state.getClass()); - } - - @Test - public void getPrimaryStyleName_treeTableHasCustomPrimaryStyleName() { - TreeTable table = new TreeTable(); - TreeTableState state = new TreeTableState(); - Assert.assertEquals("Unexpected primary style name", - state.primaryStyleName, table.getPrimaryStyleName()); - } - - @Test - public void treeTableStateHasCustomPrimaryStyleName() { - TreeTableState state = new TreeTableState(); - Assert.assertEquals("Unexpected primary style name", "v-table", - state.primaryStyleName); - } - - private static class TestTreeTable extends TreeTable { - - @Override - protected boolean rowHeadersAreEnabled() { - return super.rowHeadersAreEnabled(); - } - - @Override - public TreeTableState getState() { - return super.getState(); - } - } -} |