You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractListing.java 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright 2000-2014 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.ui.components;
  17. import java.util.LinkedHashSet;
  18. import java.util.Set;
  19. import com.vaadin.server.AbstractClientConnector;
  20. import com.vaadin.server.AbstractExtension;
  21. import com.vaadin.server.ListingExtension;
  22. import com.vaadin.server.communication.data.typed.AbstractSelectionModel;
  23. import com.vaadin.server.communication.data.typed.DataProvider;
  24. import com.vaadin.server.communication.data.typed.SelectionModel;
  25. import com.vaadin.server.communication.data.typed.TypedDataGenerator;
  26. import com.vaadin.ui.AbstractComponent;
  27. /**
  28. * Base class for Listing components. Provides common handling for
  29. * {@link DataProvider}, {@link SelectionModel} and {@link TypedDataGenerator}s.
  30. *
  31. * @param <T>
  32. * listing data type
  33. */
  34. public abstract class AbstractListing<T> extends AbstractComponent implements
  35. Listing<T> {
  36. /**
  37. * Helper base class for creating extensions for Listing components. This
  38. * class provides helpers for accessing the underlying parts of the
  39. * component and it's communicational mechanism.
  40. *
  41. * @param <T>
  42. * listing data type
  43. */
  44. public abstract static class AbstractListingExtension<T> extends
  45. AbstractExtension implements ListingExtension<T>,
  46. TypedDataGenerator<T> {
  47. /**
  48. * {@inheritDoc}
  49. * <p>
  50. * Note: AbstractListingExtensions need parent to be of type
  51. * AbstractListing.
  52. *
  53. * @throws IllegalArgument
  54. * if parent is not an AbstractListing
  55. */
  56. @Override
  57. public void extend(Listing<T> listing) {
  58. if (listing instanceof AbstractListing) {
  59. AbstractListing<T> parent = (AbstractListing<T>) listing;
  60. super.extend(parent);
  61. parent.addDataGenerator(this);
  62. } else {
  63. throw new IllegalArgumentException(
  64. "Parent needs to extend AbstractListing");
  65. }
  66. }
  67. @Override
  68. public void remove() {
  69. getParent().removeDataGenerator(this);
  70. super.remove();
  71. }
  72. /**
  73. * Gets a data object based on it's client-side identifier key.
  74. *
  75. * @param key
  76. * key for data object
  77. * @return the data object
  78. */
  79. protected T getData(String key) {
  80. DataProvider<T> dataProvider = getParent().getDataProvider();
  81. if (dataProvider != null) {
  82. return dataProvider.getKeyMapper().get(key);
  83. }
  84. return null;
  85. }
  86. @Override
  87. @SuppressWarnings("unchecked")
  88. public AbstractListing<T> getParent() {
  89. return (AbstractListing<T>) super.getParent();
  90. }
  91. /**
  92. * Helper method for refreshing a single data object.
  93. *
  94. * @param data
  95. * data object to refresh
  96. */
  97. protected void refresh(T data) {
  98. DataProvider<T> dataProvider = getParent().getDataProvider();
  99. if (dataProvider != null) {
  100. dataProvider.refresh(data);
  101. }
  102. }
  103. }
  104. /* DataProvider for this Listing component */
  105. private DataProvider<T> dataProvider;
  106. /* TypedDataGenerators used by this Listing */
  107. private Set<TypedDataGenerator<T>> generators = new LinkedHashSet<>();
  108. /* SelectionModel for this Listing */
  109. private SelectionModel<T> selectionModel;
  110. /**
  111. * Adds a {@link TypedDataGenerator} for the {@link DataProvider} of this
  112. * Listing component.
  113. *
  114. * @param generator
  115. * typed data generator
  116. */
  117. protected void addDataGenerator(TypedDataGenerator<T> generator) {
  118. generators.add(generator);
  119. if (dataProvider != null) {
  120. dataProvider.addDataGenerator(generator);
  121. }
  122. }
  123. /**
  124. * Removed a {@link TypedDataGenerator} from the {@link DataProvider} of
  125. * this Listing component.
  126. *
  127. * @param generator
  128. * typed data generator
  129. */
  130. protected void removeDataGenerator(TypedDataGenerator<T> generator) {
  131. generators.remove(generator);
  132. if (dataProvider != null) {
  133. dataProvider.removeDataGenerator(generator);
  134. }
  135. }
  136. /**
  137. * Extends this listing component with a data provider. This method
  138. * reapplies all data generators to the new data provider.
  139. *
  140. * @param dataProvider
  141. * new data provider
  142. */
  143. protected void setDataProvider(DataProvider<T> dataProvider) {
  144. if (this.dataProvider == dataProvider) {
  145. return;
  146. }
  147. if (this.dataProvider != null) {
  148. this.dataProvider.remove();
  149. }
  150. this.dataProvider = dataProvider;
  151. if (dataProvider != null) {
  152. addExtension(dataProvider);
  153. if (dataProvider != null) {
  154. // Reapply all data generators to the new data provider.
  155. for (TypedDataGenerator<T> generator : generators) {
  156. dataProvider.addDataGenerator(generator);
  157. }
  158. }
  159. }
  160. }
  161. /**
  162. * Get the {@link DataProvider} of this Listing component.
  163. *
  164. * @return data provider
  165. */
  166. protected DataProvider<T> getDataProvider() {
  167. return dataProvider;
  168. }
  169. @SuppressWarnings("unchecked")
  170. @Override
  171. public void setSelectionModel(SelectionModel<T> model) {
  172. if (selectionModel != null) {
  173. selectionModel.remove();
  174. }
  175. selectionModel = model;
  176. if (model != null) {
  177. model.extend(this);
  178. }
  179. }
  180. @Override
  181. public SelectionModel<T> getSelectionModel() {
  182. return selectionModel;
  183. }
  184. }