diff options
author | Henrik Paul <henrik@vaadin.com> | 2015-03-20 11:18:35 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-03-20 12:16:04 +0000 |
commit | 4a52ec0b7ad95a4b44a70be9ce9386f6cde1192b (patch) | |
tree | 92432ac606957a0aca39d9a54bec6a44fd249781 /server/src/com/vaadin/ui/Grid.java | |
parent | f6a148783e898c828155aab59b97f7a52faa5129 (diff) | |
download | vaadin-framework-4a52ec0b7ad95a4b44a70be9ce9386f6cde1192b.tar.gz vaadin-framework-4a52ec0b7ad95a4b44a70be9ce9386f6cde1192b.zip |
Move DetailComponentManager from Grid to RDPE (#16644)
Change-Id: I2b65a878bb50c2b1f62135a998207a41e82fe62f
Diffstat (limited to 'server/src/com/vaadin/ui/Grid.java')
-rw-r--r-- | server/src/com/vaadin/ui/Grid.java | 253 |
1 files changed, 6 insertions, 247 deletions
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index 0e035ae524..4488789406 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -37,9 +37,6 @@ 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; -import com.google.gwt.thirdparty.guava.common.collect.Maps; import com.google.gwt.thirdparty.guava.common.collect.Sets; import com.google.gwt.thirdparty.guava.common.collect.Sets.SetView; import com.vaadin.data.Container; @@ -52,6 +49,7 @@ import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.RpcDataProviderExtension; import com.vaadin.data.RpcDataProviderExtension.DataProviderKeyMapper; +import com.vaadin.data.RpcDataProviderExtension.DetailComponentManager; import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.data.fieldgroup.DefaultFieldGroupFieldFactory; import com.vaadin.data.fieldgroup.FieldGroup; @@ -80,7 +78,6 @@ import com.vaadin.server.KeyMapper; import com.vaadin.server.VaadinSession; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.data.sort.SortDirection; -import com.vaadin.shared.ui.grid.DetailsConnectorChange; import com.vaadin.shared.ui.grid.EditorClientRpc; import com.vaadin.shared.ui.grid.EditorServerRpc; import com.vaadin.shared.ui.grid.GridClientRpc; @@ -2996,246 +2993,6 @@ public class Grid extends AbstractComponent implements SelectionNotifier, } /** - * A class that makes detail component related internal communication - * possible between {@link RpcDataProviderExtension} and grid. - * - * @since - * @author Vaadin Ltd - */ - public final class DetailComponentManager implements Serializable { - /** - * This map represents all the components that have been requested for - * each item id. - * <p> - * Normally this map is consistent with what is displayed in the - * component hierarchy (and thus the DOM). The only time this map is out - * of sync with the DOM is between the any calls to - * {@link #createDetails(Object, int)} or - * {@link #destroyDetails(Object)}, and - * {@link GridClientRpc#setDetailsConnectorChanges(Set)}. - * <p> - * This is easily checked: if {@link #unattachedComponents} is - * {@link Collection#isEmpty() empty}, then this field is consistent - * with the connector hierarchy. - */ - private final Map<Object, Component> visibleDetailsComponents = Maps - .newHashMap(); - - /** A lookup map for which row contains which details component. */ - private BiMap<Integer, Component> rowIndexToDetails = HashBiMap - .create(); - - /** - * A copy of {@link #rowIndexToDetails} from its last stable state. Used - * for creating a diff against {@link #rowIndexToDetails}. - * - * @see #getAndResetConnectorChanges() - */ - private BiMap<Integer, Component> prevRowIndexToDetails = HashBiMap - .create(); - - /** - * A set keeping track on components that have been created, but not - * attached. They should be attached at some later point in time. - * <p> - * This isn't strictly requried, but it's a handy explicit log. You - * could find out the same thing by taking out all the other components - * and checking whether Grid is their parent or not. - */ - private final Set<Component> unattachedComponents = Sets.newHashSet(); - - /** - * Keeps tabs on all the details that did not get a component during - * {@link #createDetails(Object, int)}. - */ - private final Map<Object, Integer> emptyDetails = Maps.newHashMap(); - - /** - * Creates a details component by the request of the client side, with - * the help of the user-defined {@link DetailsGenerator}. - * <p> - * Also keeps internal bookkeeping up to date. - * - * @param itemId - * the item id for which to create the details component. - * Assumed not <code>null</code> and that a component is not - * currently present for this item previously - * @param rowIndex - * the row index for {@code itemId} - * @throws IllegalStateException - * if the current details generator provides a component - * that was manually attached, or if the same instance has - * already been provided - */ - public void createDetails(Object itemId, int rowIndex) - throws IllegalStateException { - assert itemId != null : "itemId was null"; - Integer newRowIndex = Integer.valueOf(rowIndex); - - assert !visibleDetailsComponents.containsKey(itemId) : "itemId " - + "already has a component. Should be destroyed first."; - - RowReference rowReference = new RowReference(Grid.this); - rowReference.set(itemId); - - Component details = getDetailsGenerator().getDetails(rowReference); - if (details != null) { - if (details.getParent() != null) { - String generatorName = getDetailsGenerator().getClass() - .getName(); - throw new IllegalStateException(generatorName - + " generated a details component that already " - + "was attached. (itemId: " + itemId + ", row: " - + rowIndex + ", component: " + details); - } - - if (rowIndexToDetails.containsValue(details)) { - String generatorName = getDetailsGenerator().getClass() - .getName(); - throw new IllegalStateException(generatorName - + " provided a details component that already " - + "exists in Grid. (itemId: " + itemId + ", row: " - + rowIndex + ", component: " + details); - } - - visibleDetailsComponents.put(itemId, details); - rowIndexToDetails.put(newRowIndex, details); - unattachedComponents.add(details); - - assert !emptyDetails.containsKey(itemId) : "Bookeeping thinks " - + "itemId is empty even though we just created a " - + "component for it (" + itemId + ")"; - } else { - assert !emptyDetails.containsKey(itemId) : "Bookkeeping has " - + "already itemId marked as empty (itemId: " + itemId - + ", old index: " + emptyDetails.get(itemId) - + ", new index: " + newRowIndex + ")"; - assert !emptyDetails.containsValue(newRowIndex) : "Bookkeeping" - + " already had another itemId for this empty index " - + "(index: " + newRowIndex + ", new itemId: " + itemId - + ")"; - emptyDetails.put(itemId, newRowIndex); - } - - /* - * Don't attach the components here. It's done by - * GridServerRpc.sendDetailsComponents in a separate roundtrip. - */ - } - - /** - * Destroys correctly a details component, by the request of the client - * side. - * <p> - * Also keeps internal bookkeeping up to date. - * - * @param itemId - * the item id for which to destroy the details component - */ - public void destroyDetails(Object itemId) { - emptyDetails.remove(itemId); - - Component removedComponent = visibleDetailsComponents - .remove(itemId); - if (removedComponent == null) { - return; - } - - rowIndexToDetails.inverse().remove(removedComponent); - - removedComponent.setParent(null); - markAsDirty(); - } - - /** - * Gets all details components that are currently attached to the grid. - * <p> - * Used internally by the Grid object. - * - * @return all details components that are currently attached to the - * grid - */ - Collection<Component> getComponents() { - Set<Component> components = new HashSet<Component>( - visibleDetailsComponents.values()); - components.removeAll(unattachedComponents); - return components; - } - - /** - * Gets information on how the connectors have changed. - * <p> - * This method only returns the changes that have been made between two - * calls of this method. I.e. Calling this method once will reset the - * state for the next state. - * <p> - * Used internally by the Grid object. - * - * @return information on how the connectors have changed - */ - Set<DetailsConnectorChange> getAndResetConnectorChanges() { - Set<DetailsConnectorChange> changes = new HashSet<DetailsConnectorChange>(); - - // populate diff with added/changed - for (Entry<Integer, Component> entry : rowIndexToDetails.entrySet()) { - Component component = entry.getValue(); - assert component != null : "rowIndexToDetails contains a null component"; - - Integer newIndex = entry.getKey(); - Integer oldIndex = prevRowIndexToDetails.inverse().get( - component); - - /* - * only attach components. Detaching already happened in - * destroyDetails. - */ - if (newIndex != null && oldIndex == null) { - assert unattachedComponents.contains(component) : "unattachedComponents does not contain component for index " - + newIndex + " (" + component + ")"; - component.setParent(Grid.this); - unattachedComponents.remove(component); - } - - if (!SharedUtil.equals(oldIndex, newIndex)) { - changes.add(new DetailsConnectorChange(component, oldIndex, - newIndex)); - } - } - - // populate diff with removed - for (Entry<Integer, Component> entry : prevRowIndexToDetails - .entrySet()) { - Integer oldIndex = entry.getKey(); - Component component = entry.getValue(); - Integer newIndex = rowIndexToDetails.inverse().get(component); - if (newIndex == null) { - changes.add(new DetailsConnectorChange(null, oldIndex, null)); - } - } - - // reset diff map - prevRowIndexToDetails = HashBiMap.create(rowIndexToDetails); - - return changes; - } - - public void refresh(Object itemId) { - Component component = visibleDetailsComponents.get(itemId); - Integer rowIndex = null; - if (component != null) { - rowIndex = rowIndexToDetails.inverse().get(component); - destroyDetails(itemId); - } else { - rowIndex = emptyDetails.remove(itemId); - } - - assert rowIndex != null : "Given itemId does not map to an existing detail row (" - + itemId + ")"; - createDetails(itemId, rowIndex.intValue()); - } - } - - /** * The data source attached to the grid */ private Container.Indexed datasource; @@ -3349,7 +3106,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, */ private DetailsGenerator detailsGenerator = DetailsGenerator.NULL; - private final DetailComponentManager detailComponentManager = new DetailComponentManager(); + private DetailComponentManager detailComponentManager = null; private static final Method SELECTION_CHANGE_METHOD = ReflectTools .findMethod(SelectionListener.class, "select", SelectionEvent.class); @@ -3765,10 +3522,12 @@ public class Grid extends AbstractComponent implements SelectionNotifier, sortOrder.clear(); } - datasourceExtension = new RpcDataProviderExtension(container, - detailComponentManager); + datasourceExtension = new RpcDataProviderExtension(container); datasourceExtension.extend(this, columnKeys); + detailComponentManager = datasourceExtension + .getDetailComponentManager(); + /* * selectionModel == null when the invocation comes from the * constructor. |