]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merge branch 'master' into grid-unbuffered-editor
authorHenri Sara <hesara@vaadin.com>
Wed, 19 Aug 2015 08:58:33 +0000 (11:58 +0300)
committerHenri Sara <hesara@vaadin.com>
Wed, 19 Aug 2015 12:22:59 +0000 (15:22 +0300)
Conflicts:
server/src/com/vaadin/data/RpcDataProviderExtension.java

Change-Id: I1bd55b03a8c114823ed8655fc89758f37b16e9c4

1  2 
server/src/com/vaadin/data/RpcDataProviderExtension.java

index d81d024d72ccaf08e0c598f6b52ab605ebabd5dc,848873098d40a35db868b4cc83653b50c0b1310a..403cc4c016ad6564158842d167b703066e43a75b
@@@ -21,10 -21,14 +21,11 @@@ import java.util.ArrayList
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.HashSet;
+ import java.util.Iterator;
  import java.util.LinkedHashSet;
  import java.util.List;
 -import java.util.Locale;
  import java.util.Map;
  import java.util.Set;
 -import java.util.logging.Level;
 -import java.util.logging.Logger;
  
  import com.google.gwt.thirdparty.guava.common.collect.BiMap;
  import com.google.gwt.thirdparty.guava.common.collect.HashBiMap;
@@@ -56,7 -66,7 +57,6 @@@ import com.vaadin.ui.Grid.RowReference
  import elemental.json.Json;
  import elemental.json.JsonArray;
  import elemental.json.JsonObject;
--import elemental.json.JsonValue;
  
  /**
   * Provides Vaadin server-side container data source to a
@@@ -268,135 -250,51 +240,61 @@@ public class RpcDataProviderExtension e
              return pinnedItemIds.contains(itemId);
          }
  
-     }
-     /**
-      * A helper class that handles the client-side Escalator logic relating to
-      * making sure that whatever is currently visible to the user, is properly
-      * initialized and otherwise handled on the server side (as far as
-      * required).
-      * <p>
-      * This bookeeping includes, but is not limited to:
-      * <ul>
-      * <li>listening to the currently visible {@link com.vaadin.data.Property
-      * Properties'} value changes on the server side and sending those back to
-      * the client; and
-      * <li>attaching and detaching {@link com.vaadin.ui.Component Components}
-      * from the Vaadin Component hierarchy.
-      * </ul>
-      */
-     private class ActiveRowHandler implements Serializable {
-         /**
-          * A map from index to the value change listener used for all of column
-          * properties
-          */
-         private final Map<Integer, GridValueChangeListener> valueChangeListeners = new HashMap<Integer, GridValueChangeListener>();
-         /**
-          * The currently active range. Practically, it's the range of row
-          * indices being cached currently.
-          */
-         private Range activeRange = Range.withLength(0, 0);
 +        /**
 +         * {@inheritDoc}
 +         * 
 +         * @since
 +         */
 +        @Override
 +        public void generateData(Object itemId, Item item, JsonObject rowData) {
 +            rowData.put(GridState.JSONKEY_ROWKEY, getKey(itemId));
 +        }
 +
          /**
-          * A hook for making sure that appropriate data is "active". All other
-          * rows should be "inactive".
-          * <p>
-          * "Active" can mean different things in different contexts. For
-          * example, only the Properties in the active range need
-          * ValueChangeListeners. Also, whenever a row with a Component becomes
-          * active, it needs to be attached (and conversely, when inactive, it
-          * needs to be detached).
+          * Removes all inactive item id to key mapping from the key mapper.
           * 
-          * @param firstActiveRow
-          *            the first active row
-          * @param activeRowCount
-          *            the number of active rows
+          * @since
           */
-         public void setActiveRows(Range newActiveRange) {
-             // TODO [[Components]] attach and detach components
-             /*-
-              *  Example
-              * 
-              *  New Range:       [3, 4, 5, 6, 7]
-              *  Old Range: [1, 2, 3, 4, 5]
-              *  Result:    [1, 2][3, 4, 5]      []
-              */
-             final Range[] depractionPartition = activeRange
-                     .partitionWith(newActiveRange);
-             removeValueChangeListeners(depractionPartition[0]);
-             removeValueChangeListeners(depractionPartition[2]);
-             /*-
-              *  Example
-              *  
-              *  Old Range: [1, 2, 3, 4, 5]
-              *  New Range:       [3, 4, 5, 6, 7]
-              *  Result:    []    [3, 4, 5][6, 7]
-              */
-             final Range[] activationPartition = newActiveRange
-                     .partitionWith(activeRange);
-             addValueChangeListeners(activationPartition[0]);
-             addValueChangeListeners(activationPartition[2]);
-             activeRange = newActiveRange;
-             assert valueChangeListeners.size() == newActiveRange.length() : "Value change listeners not set up correctly!";
-         }
-         private void addValueChangeListeners(Range range) {
-             for (Integer i = range.getStart(); i < range.getEnd(); i++) {
-                 final Object itemId = container.getIdByIndex(i);
-                 final Item item = container.getItem(itemId);
-                 assert valueChangeListeners.get(i) == null : "Overwriting existing listener";
-                 GridValueChangeListener listener = new GridValueChangeListener(
-                         itemId, item);
-                 valueChangeListeners.put(i, listener);
+         public void dropInactiveItems() {
+             Collection<Object> active = activeItemHandler.getActiveItemIds();
+             Iterator<Object> itemIter = itemIdToKey.keySet().iterator();
+             while (itemIter.hasNext()) {
+                 Object itemId = itemIter.next();
+                 if (!active.contains(itemId) && !isPinned(itemId)) {
+                     itemIter.remove();
+                 }
              }
          }
+     }
  
-         private void removeValueChangeListeners(Range range) {
-             for (Integer i = range.getStart(); i < range.getEnd(); i++) {
-                 final GridValueChangeListener listener = valueChangeListeners
-                         .remove(i);
-                 assert listener != null : "Trying to remove nonexisting listener";
+     /**
+      * Class for keeping track of current items and ValueChangeListeners.
+      * 
+      * @since
+      */
+     private class ActiveItemHandler implements Serializable {
  
-                 listener.removeListener();
-             }
-         }
+         private final Map<Object, GridValueChangeListener> activeItemMap = new HashMap<Object, GridValueChangeListener>();
+         private final Set<Object> droppedItems = new HashSet<Object>();
  
          /**
-          * Manages removed columns in active rows.
-          * <p>
-          * This method does <em>not</em> send data again to the client.
+          * Registers ValueChangeListeners for given items ids.
           * 
-          * @param removedColumns
-          *            the columns that have been removed from the grid
+          * @param itemIds
+          *            collection of new active item ids
           */
-         public void columnsRemoved(Collection<Column> removedColumns) {
-             if (removedColumns.isEmpty()) {
-                 return;
+         public void addActiveItems(Collection<?> itemIds) {
+             for (Object itemId : itemIds) {
+                 if (!activeItemMap.containsKey(itemId)) {
+                     activeItemMap.put(itemId, new GridValueChangeListener(
+                             itemId, container.getItem(itemId)));
+                 }
              }
  
-             for (GridValueChangeListener listener : valueChangeListeners
-                     .values()) {
-                 listener.removeColumns(removedColumns);
-             }
+             // Remove still active rows that were "dropped"
+             droppedItems.removeAll(itemIds);
+             dropListeners(droppedItems);
+             droppedItems.clear();
          }
  
          /**
              }
              this.grid = grid;
          }
-                 rowData.put(GridState.JSONKEY_DETAILS_VISIBLE, true);
 +
 +        /**
 +         * {@inheritDoc}
 +         * 
 +         * @since
 +         */
 +        @Override
 +        public void generateData(Object itemId, Item item, JsonObject rowData) {
 +            if (visibleDetails.contains(itemId)) {
++                // Double check to be sure details component exists.
++                detailComponentManager.createDetails(itemId);
++                Component detailsComponent = visibleDetailsComponents
++                        .get(itemId);
++                rowData.put(
++                        GridState.JSONKEY_DETAILS_VISIBLE,
++                        (detailsComponent != null ? detailsComponent
++                                .getConnectorId() : ""));
 +            }
 +        }
      }
  
      private final Indexed container;
       * This map represents all the details that are user-defined as visible.
       * This does not reflect the status in the DOM.
       */
 -    private Set<Object> visibleDetails = new HashSet<Object>();
 +    // TODO this should probably be inside DetailComponentManager
-     private Set<Object> visibleDetails = new HashSet<Object>();
++    private final Set<Object> visibleDetails = new HashSet<Object>();
  
      private final DetailComponentManager detailComponentManager = new DetailComponentManager();
-     private Set<DataGenerator> dataGenerators = new LinkedHashSet<DataGenerator>();
 +
++    private final Set<DataGenerator> dataGenerators = new LinkedHashSet<DataGenerator>();
++
+     private final ActiveItemHandler activeItemHandler = new ActiveItemHandler();
  
      /**
       * Creates a new data provider using the given container.
          }
          rpc.setRowData(firstRowToPush, rows);
  
-         activeRowHandler.setActiveRows(fullRange);
+         activeItemHandler.addActiveItems(itemIds);
+         keyMapper.dropInactiveItems();
      }
  
-     private JsonValue getRowData(Collection<Column> columns, Object itemId) {
+     private JsonObject getRowData(Collection<Column> columns, Object itemId) {
          Item item = container.getItem(itemId);
  
 -        JsonObject rowData = Json.createObject();
 -
 -        Grid grid = getGrid();
 -
 -        for (Column column : columns) {
 -            Object propertyId = column.getPropertyId();
 -
 -            Object propertyValue = item.getItemProperty(propertyId).getValue();
 -            JsonValue encodedValue = encodeValue(propertyValue,
 -                    column.getRenderer(), column.getConverter(),
 -                    grid.getLocale());
 -
 -            rowData.put(columnKeys.key(propertyId), encodedValue);
 -        }
 -
          final JsonObject rowObject = Json.createObject();
 -        rowObject.put(GridState.JSONKEY_DATA, rowData);
 -        rowObject.put(GridState.JSONKEY_ROWKEY, keyMapper.getKey(itemId));
 -
 -        if (visibleDetails.contains(itemId)) {
 -            // Double check to be sure details component exists.
 -            detailComponentManager.createDetails(itemId);
 -            Component detailsComponent = detailComponentManager.visibleDetailsComponents
 -                    .get(itemId);
 -            rowObject.put(
 -                    GridState.JSONKEY_DETAILS_VISIBLE,
 -                    (detailsComponent != null ? detailsComponent
 -                            .getConnectorId() : ""));
 -        }
 -
 -        rowReference.set(itemId);
 -
 -        CellStyleGenerator cellStyleGenerator = grid.getCellStyleGenerator();
 -        if (cellStyleGenerator != null) {
 -            setGeneratedCellStyles(cellStyleGenerator, rowObject, columns);
 -        }
 -        RowStyleGenerator rowStyleGenerator = grid.getRowStyleGenerator();
 -        if (rowStyleGenerator != null) {
 -            setGeneratedRowStyles(rowStyleGenerator, rowObject);
 +        for (DataGenerator dg : dataGenerators) {
 +            dg.generateData(itemId, item, rowObject);
          }
  
          return rowObject;